728x90
RAG 시스템이 문서를 검색해 답변을 생성할 때,
단일 문서만 참조하는 것이 아니라 여러 문서를 동시에 참조하는 경우가 많습니다.
하지만 GPT가 3~5개 문서를 한꺼번에 받게 되면,
- 핵심 내용이 흐려지거나
- 전체 내용을 단순 나열하거나
- 응답 길이가 길어지고 요점을 놓치게 됩니다.
그래서 이번 글에서는:
- ✅ LangChain의 stuff, map_reduce, refine 체인 전략을 이해하고
- ✅ 멀티 문서에 대한 요약을 보다 효과적으로 수행할 수 있도록
- ✅ 실제 체인 구조를 비교하고 선택하는 기준을 제시합니다.
🎯 목표
- 여러 문서를 입력받아 GPT가 요약한 응답을 생성하는 구조 설계
- stuff, map_reduce, refine 체인 방식 비교
- 실무에서 적용 가능한 요약 전략 예제 구현
🧠 Step 1. 체인 비교를 위한 기본 구조 준비
# src/chain_compare.py
from langchain.chat_models import ChatOpenAI
from langchain.chains.combine_documents import (
StuffDocumentsChain,
MapReduceDocumentsChain,
RefineDocumentsChain
)
from langchain.prompts import PromptTemplate
from langchain.docstore.document import Document
# ✅ 기본 LLM 설정
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# ✅ 공통 프롬프트 정의 (질문은 요약 지시)
prompt = PromptTemplate.from_template(
"다음 문서들을 참고하여 요약된 응답을 생성하세요:\n\n{context}"
)
# ✅ 샘플 문서 리스트 (예시)
docs = [
Document(page_content="products 테이블에는 상품의 ID, 이름, 카테고리 정보가 포함됩니다."),
Document(page_content="orders 테이블은 주문 ID, 고객 ID, 상품 ID, 주문일을 포함합니다."),
Document(page_content="customers 테이블은 고객의 ID, 이름, 지역 정보를 가지고 있습니다.")
]
🧪 Step 2. Stuff 방식 체인
# ✅ Stuff 방식: 모든 문서를 하나로 합쳐서 한 번에 처리
stuff_chain = StuffDocumentsChain(
llm_chain=prompt | llm, # 프롬프트 → LLM으로 연결
document_variable_name="context"
)
result = stuff_chain.run(docs)
print("🧾 Stuff 방식 응답:")
print(result)
📝 장점: 빠르고 간단함
⚠️ 단점: 문서 수가 많거나 길면 출력이 초과될 수 있음
🧪 Step 3. MapReduce 방식 체인
# ✅ MapReduce 방식: 각 문서를 개별 처리 → 부분 응답 → 통합 요약
map_reduce_chain = MapReduceDocumentsChain.from_llm(
llm=llm,
prompt=prompt,
document_variable_name="context"
)
result = map_reduce_chain.run(docs)
print("🗂️ MapReduce 방식 응답:")
print(result)
📝 장점: 문서가 많아도 안정적 처리 가능
⚠️ 단점: 처리 속도가 상대적으로 느림
🧪 Step 4. Refine 방식 체인
# ✅ Refine 방식: 첫 문서에서 초안 생성 → 다음 문서마다 점진적 개선
refine_prompt = PromptTemplate.from_template(
"초기 요약: {existing_answer}\n새로운 문서: {context}\n개선된 응답을 작성하세요."
)
refine_chain = RefineDocumentsChain.from_llm(
llm=llm,
initial_prompt=prompt,
refine_prompt=refine_prompt,
document_variable_name="context"
)
result = refine_chain.run(docs)
print("🔁 Refine 방식 응답:")
print(result)
📝 장점: 문서마다 반영을 반복하며 깊이 있는 응답 가능
⚠️ 단점: 초안이 너무 단순하면 개선 효과가 떨어짐
📎 요약 및 핵심 정리
방식 | 특징 | 적합한 상황 |
Stuff | 모든 문서를 한번에 입력 | 문서 수 적고 짧을 때 |
MapReduce | 분할 요약 후 통합 | 문서 수가 많고 균일할 때 |
Refine | 초안 생성 후 문서마다 개선 | 순차적 정제 또는 깊이 있는 요약 |
- 멀티 문서를 다룰 때는 GPT에게 **"모든 걸 보여준다"기보다는 "잘게 나누고 요약하게 한다"**는 관점이 중요합니다.
- 특히 문서가 많고 길다면 MapReduce나 Refine이 더 안정적입니다.
728x90