LLM을 활용한 컨텍스트 압축: 효율적인 정보 전달을 위한 가이드 - DB검색 요약

GoGoComputer·2024년 10월 31일
0

LangChain Basics

목록 보기
20/40
post-thumbnail

안녕하세요! 컨텍스트 압축 강의에 오신 것을 환영합니다.

이번 강의에서는 대형 언어 모델(LLM)을 활용하여 출력 결과를 압축하는 방법에 대해 자세히 알아보겠습니다. 이전 강의에서는 입력 측면에서 LLM을 활용하여 멀티 쿼리 검색기를 사용하여 쿼리를 확장하는 방법을 살펴보았습니다. 이제는 출력 측면에서 LLM을 사용하여 컨텍스트를 압축하는 방법을 알아보겠습니다.

컨텍스트 압축이란 무엇인가요?

컨텍스트 압축은 관련된 문서의 내용을 간결하게 요약하여 사용자에게 전달하는 것을 의미합니다. 이는 전통적인 파일 압축(zip 파일 등)과는 다릅니다. 여기서는 LLM을 활용하여 긴 문서를 더 작고 의미 있는 형태로 증류(distillation)하는 것입니다.

왜 컨텍스트 압축이 필요한가요?

  • 효율성 향상: 긴 문서를 모두 보여주는 것보다 핵심 내용만 전달하여 사용자 경험을 개선합니다.
  • 자원 절약: 모델이 처리해야 하는 데이터의 양을 줄여 성능을 향상시킵니다.
  • 정확한 정보 제공: 사용자 질문에 더욱 정확하게 답변할 수 있습니다.

컨텍스트 압축 실습 예제

이제 실제로 컨텍스트 압축을 구현해보겠습니다. 이번 실습에서는 LangChain 라이브러리를 사용하여 컨텍스트 압축 리트리버를 설정하고 활용하는 방법을 알아봅니다.

1. 필요한 라이브러리 불러오기

import os
from dotenv import load_dotenv
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

2. 환경 변수 설정

.env 파일에서 OPENAI_API_KEY를 불러옵니다.

load_dotenv()
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

3. 임베딩 함수 설정

OpenAI 임베딩을 사용하여 임베딩 함수를 설정합니다.

embedding_function = OpenAIEmbeddings()

4. 벡터 데이터베이스 연결

Chroma 벡터 데이터베이스에 연결합니다. 데이터베이스는 미리 구축되어 있어야 합니다.

db_directory = './mk_ultra'
db_connection = Chroma(persist_directory=db_directory, embedding_function=embedding_function)

5. LLM 및 압축기 설정

ChatGPT 모델을 사용하여 LLM을 설정하고, 이를 통해 LLM 체인 추출기를 생성합니다.

llm = ChatOpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)

6. 컨텍스트 압축 리트리버 생성

컨텍스트 압축 리트리버를 생성하여 기본 리트리버와 압축기를 설정합니다.

compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=db_connection.as_retriever()
)

7. 쿼리 수행 및 결과 압축

사용자의 질문을 입력하여 관련 문서를 검색하고 압축된 결과를 얻습니다.

query = "이 문서는 언제 기밀 해제되었나요?"
compressed_docs = compression_retriever.get_relevant_documents(query)

8. 결과 확인

압축된 문서의 내용을 확인합니다.

for idx, doc in enumerate(compressed_docs):
    print(f"문서 {idx+1}:")
    print("페이지 내용:", doc.page_content)
    print("요약:", doc.metadata.get('summary', '요약 없음'))
    print("-" * 50)

전체 실습 코드

아래는 위의 모든 단계를 포함한 전체 코드입니다.

import os
from dotenv import load_dotenv

from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

# 1. 환경 변수 로드
load_dotenv()
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

if OPENAI_API_KEY is None:
    raise ValueError("OPENAI_API_KEY가 설정되지 않았습니다. 환경 변수를 확인하세요.")

# 2. 임베딩 함수 설정
try:
    embedding_function = OpenAIEmbeddings()
except Exception as e:
    raise RuntimeError(f"임베딩 함수 설정 중 오류 발생: {e}")

# 3. 벡터 데이터베이스 연결
db_directory = './mk_ultra'  # 데이터베이스 디렉토리 (수정 필요)
persist_directory = db_directory
try:
    db_connection = Chroma(persist_directory=persist_directory, embedding_function=embedding_function)
except Exception as e:
    raise RuntimeError(f"벡터 데이터베이스 연결 중 오류 발생: {e}")

# 4. LLM 및 압축기 설정
try:
    llm = ChatOpenAI(model_name="gpt-4", temperature=0)  # 모델 이름 변경 가능
except Exception as e:
    raise RuntimeError(f"LLM 설정 중 오류 발생: {e}")

try:
    compressor = LLMChainExtractor.from_llm(llm)
except Exception as e:
    raise RuntimeError(f"LLMChainExtractor 설정 중 오류 발생: {e}")

# 5. 컨텍스트 압축 리트리버 생성
try:
    compression_retriever = ContextualCompressionRetriever(
        base_compressor=compressor,
        base_retriever=db_connection.as_retriever()
    )
except Exception as e:
    raise RuntimeError(f"컨텍스트 압축 리트리버 생성 중 오류 발생: {e}")

# 6. 쿼리 입력 및 압축된 문서 검색
query = "이 문서는 어떤 내용 인가요?"
try:
    docs = compression_retriever.get_relevant_documents(query)
except Exception as e:
    raise RuntimeError(f"문서 검색 중 오류 발생: {e}")

# 7. 결과 출력
if not docs:
    print("관련 문서를 찾지 못했습니다.")
else:
    for idx, doc in enumerate(docs):
        print(f"문서 {idx+1}:")
        print("페이지 내용:", doc.page_content)
        print("요약:", doc.metadata.get('summary', '요약 없음'))
        print("-" * 50)

추가 설명

  • 환경 변수 설정: python-dotenv 라이브러리를 사용하여 .env 파일에서 OPENAI_API_KEY를 불러옵니다. 이는 API 키의 보안을 유지하는 데 도움이 됩니다.

  • 데이터베이스 구축: 실제로 이 코드를 실행하려면 Chroma 데이터베이스에 문서를 로드해야 합니다. 이를 위해 WikipediaLoader나 다른 문서 로더를 사용할 수 있습니다.

  • LLM 설정: ChatOpenAI 모델을 사용할 때 temperature=0으로 설정하면 결과의 일관성을 높일 수 있습니다.

  • 결과 해석: 압축된 문서의 page_content는 원본 문서보다 간결하며, 사용자의 질문에 더 직접적으로 답변합니다.

라이브러리 설치

코드를 실행하기 전에 필요한 라이브러리를 설치해야 합니다.

pip install langchain chromadb openai python-dotenv

결론

컨텍스트 압축은 대형 언어 모델을 활용하여 긴 문서를 간결하게 요약하고, 사용자에게 필요한 핵심 정보를 효율적으로 제공하는 방법입니다. 이를 통해 모델의 효율성을 높이고, 사용자 경험을 개선할 수 있습니다.


이상으로 컨텍스트 압축에 대한 자세한 설명과 실습을 마치겠습니다. 도움이 되셨길 바랍니다!


부록

compressed_docs의 결과를 JSON 파일로 저장하려면, 문서의 내용을 JSON 포맷으로 변환하고 파일로 작성하는 코드가 필요합니다. 다음은 위 코드의 결과를 JSON 파일로 저장하는 방법입니다:

import os
import json
from dotenv import load_dotenv
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

# 1. 환경 변수 로드
load_dotenv()
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

# 2. 임베딩 함수 설정
embedding_function = OpenAIEmbeddings()

# 3. 벡터 데이터베이스 연결
db_directory = './mk_ultra'
db_connection = Chroma(persist_directory=db_directory, embedding_function=embedding_function)

# 4. LLM 및 압축기 설정
llm = ChatOpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)

# 5. 컨텍스트 압축 리트리버 생성
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=db_connection.as_retriever()
)

# 6. 쿼리 입력 및 압축된 문서 검색
query = "이 문서는 언제 기밀 해제되었나요?"
compressed_docs = compression_retriever.get_relevant_documents(query)

# 7. 결과를 JSON 파일로 저장
output_data = []

for idx, doc in enumerate(compressed_docs):
    doc_data = {
        "문서번호": idx + 1,
        "페이지 내용": doc.page_content,
        "요약": doc.metadata.get('summary', '요약 없음')
    }
    output_data.append(doc_data)

# JSON 파일로 작성
output_file = 'compressed_docs.json'
with open(output_file, 'w', encoding='utf-8') as f:
    json.dump(output_data, f, ensure_ascii=False, indent=4)

print(f"결과가 '{output_file}' 파일로 저장되었습니다.")

코드 설명

  1. 결과 변환: compressed_docs의 각 문서를 output_data 리스트에 딕셔너리 형식으로 저장합니다.
  2. JSON 저장: json.dump를 사용해 output_data를 JSON 파일로 변환하여 compressed_docs.json에 저장합니다.

이제 실행 후 "compressed_docs.json" 파일에 요약 결과가 저장될 것입니다.

profile
IT를 좋아합니다.

0개의 댓글