안녕하세요! 컨텍스트 압축 강의에 오신 것을 환영합니다.
이번 강의에서는 대형 언어 모델(LLM)을 활용하여 출력 결과를 압축하는 방법에 대해 자세히 알아보겠습니다. 이전 강의에서는 입력 측면에서 LLM을 활용하여 멀티 쿼리 검색기를 사용하여 쿼리를 확장하는 방법을 살펴보았습니다. 이제는 출력 측면에서 LLM을 사용하여 컨텍스트를 압축하는 방법을 알아보겠습니다.
컨텍스트 압축은 관련된 문서의 내용을 간결하게 요약하여 사용자에게 전달하는 것을 의미합니다. 이는 전통적인 파일 압축(zip 파일 등)과는 다릅니다. 여기서는 LLM을 활용하여 긴 문서를 더 작고 의미 있는 형태로 증류(distillation)하는 것입니다.
이제 실제로 컨텍스트 압축을 구현해보겠습니다. 이번 실습에서는 LangChain 라이브러리를 사용하여 컨텍스트 압축 리트리버를 설정하고 활용하는 방법을 알아봅니다.
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
.env
파일에서 OPENAI_API_KEY
를 불러옵니다.
load_dotenv()
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
OpenAI 임베딩을 사용하여 임베딩 함수를 설정합니다.
embedding_function = OpenAIEmbeddings()
Chroma 벡터 데이터베이스에 연결합니다. 데이터베이스는 미리 구축되어 있어야 합니다.
db_directory = './mk_ultra'
db_connection = Chroma(persist_directory=db_directory, embedding_function=embedding_function)
ChatGPT 모델을 사용하여 LLM을 설정하고, 이를 통해 LLM 체인 추출기를 생성합니다.
llm = ChatOpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)
컨텍스트 압축 리트리버를 생성하여 기본 리트리버와 압축기를 설정합니다.
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=db_connection.as_retriever()
)
사용자의 질문을 입력하여 관련 문서를 검색하고 압축된 결과를 얻습니다.
query = "이 문서는 언제 기밀 해제되었나요?"
compressed_docs = compression_retriever.get_relevant_documents(query)
압축된 문서의 내용을 확인합니다.
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}' 파일로 저장되었습니다.")
compressed_docs
의 각 문서를 output_data
리스트에 딕셔너리 형식으로 저장합니다.json.dump
를 사용해 output_data
를 JSON 파일로 변환하여 compressed_docs.json
에 저장합니다.이제 실행 후 "compressed_docs.json"
파일에 요약 결과가 저장될 것입니다.