맵-리듀스 요약 패턴
각 청크를 독립적으로 요약한 다음 요약 결과를 종합합니다.
맵-리듀스 요약 패턴은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
맵리듀스 패턴
문서가 LLM의 컨텍스트 창보다 길면 문서 전체를 한 번에 전달할 수 없습니다. 맵리듀스 패턴은 이 문제를 해결합니다:
- 맵: 각 청크를 독립적으로 요약
- 리듀스: 모든 청크 요약을 하나의 최종 요약으로 종합
이는 분산 시스템의 고전적인 MapReduce와 같은 방식으로, 나누어 정복하는 논리를 언어 작업에 적용합니다.
1단계: 맵 단계
맵 단계에서는 각 청크를 요약 프롬프트와 함께 LLM에 전달합니다. 모델은 해당 청크만을 간략하게 요약해 반환합니다. 이렇게 생성된 요약은 목록에 모읍니다.
각 요약은 원래 청크보다 훨씬 짧아야 하며, 일반적으로 원래 길이의 10~20% 정도입니다. 이러한 압축 덕분에 리듀스 단계를 실행할 수 있습니다.
import openai
client = openai.OpenAI(api_key='sk-...')
def summarize_chunk(chunk, model='gpt-4o'):
resp = client.chat.completions.create(
model=model,
messages=[
{'role': 'system', 'content': 'Summarize the following text concisely in 3-5 sentences.'},
{'role': 'user', 'content': chunk}
]
)
return resp.choices[0].message.content
def map_phase(chunks):
return [summarize_chunk(c) for c in chunks]2단계: 리듀스 단계
리듀스 단계에서는 모든 청크 요약을 이어 붙여 종합 프롬프트와 함께 LLM에 전달합니다. 모델은 일관성 있는 하나의 최종 요약을 생성합니다.
청크 요약이 여전히 하나의 컨텍스트 창에 들어가기에는 너무 길다면 리듀스를 재귀적으로 적용합니다. 먼저 요약을 여러 그룹으로 나누어 요약한 다음, 그 결과를 종합합니다.
def reduce_phase(chunk_summaries, model='gpt-4o'):
combined = '\n\n'.join(
f'Section {i+1}:\n{s}'
for i, s in enumerate(chunk_summaries)
)
resp = client.chat.completions.create(
model=model,
messages=[
{'role': 'system', 'content': 'You are given summaries of consecutive sections of a document. Write a single coherent summary of the entire document.'},
{'role': 'user', 'content': combined}
]
)
return resp.choices[0].message.content통합하기: 원시 API
다음은 별도 프레임워크 없이 원시 OpenAI API 호출을 사용한 완전한 맵리듀스 파이프라인입니다. 각 단계의 프롬프트와 매개변수를 완전히 제어할 수 있습니다.
def map_reduce_summarize(document, chunk_size=1000):
chunks = fixed_chunk(document, max_tokens=chunk_size)
print(f'Chunks: {len(chunks)}')
chunk_summaries = map_phase(chunks)
print(f'Map phase complete. Summaries: {len(chunk_summaries)}')
final_summary = reduce_phase(chunk_summaries)
return final_summary
with open('long_report.txt') as f:
doc = f.read()
result = map_reduce_summarize(doc)
print(result)LangChain MapReduceDocumentsChain
LangChain은 청킹, 병렬 맵 호출, 리듀스 단계를 처리하는 기성 MapReduceDocumentsChain을 제공합니다. 편리하지만 원시 API 호출보다 유연성이 떨어집니다.
from langchain_openai import ChatOpenAI
from langchain.chains.summarize import load_summarize_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.docstore.document import Document
llm = ChatOpenAI(model='gpt-4o', openai_api_key='sk-...')
splitter = RecursiveCharacterTextSplitter(chunk_size=3000, chunk_overlap=200)
with open('long_report.txt') as f:
text = f.read()
docs = splitter.create_documents([text])
chain = load_summarize_chain(llm, chain_type='map_reduce')
result = chain.invoke(docs)
print(result['output_text'])맵 단계 병렬화
각 청크 요약은 서로 독립적이므로 맵 단계를 병렬화할 수 있습니다. Python의 ThreadPoolExecutor를 사용하면 모든 청크 API 호출을 동시에 전송하여 실제 경과 시간을 크게 줄일 수 있습니다.
from concurrent.futures import ThreadPoolExecutor, as_completed
def map_phase_parallel(chunks, max_workers=10):
summaries = [None] * len(chunks)
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(summarize_chunk, chunk): i
for i, chunk in enumerate(chunks)
}
for future in as_completed(futures):
idx = futures[future]
summaries[idx] = future.result()
return summaries재귀적 리듀스
문서가 매우 길면 청크 요약 자체가 컨텍스트 창을 초과할 수 있습니다. 리듀스를 재귀적으로 적용하여 요약을 여러 묶음으로 그룹화하고, 각 묶음을 리듀스한 다음 묶음 요약을 다시 리듀스합니다.
def recursive_reduce(summaries, batch_size=10):
while len(summaries) > 1:
batches = [
summaries[i:i + batch_size]
for i in range(0, len(summaries), batch_size)
]
summaries = [reduce_phase(batch) for batch in batches]
print(f'Reduced to {len(summaries)} summaries')
return summaries[0]핵심 세부 정보 보존
단순한 맵리듀스에서 흔히 발생하는 문제는 압축 과정에서 중요한 세부 정보가 사라지는 것입니다. 완화 방법은 다음과 같습니다:
- 맵 단계에서 이름, 숫자, 날짜를 보존하도록 프롬프트 작성
- 리듀스 단계에서 섹션 간 모순을 확인하도록 요청
- 맵의 문맥을 더 풍부하게 만들 수 있도록 더 큰 청크 크기 사용
- 검증 단계 실행: 원문의 핵심 개체가 최종 요약에 포함되어 있는지 모델에 질문
MAP_PROMPT = '''Summarize the following section in 5 sentences.
Preserve all key names, numbers, dates, and conclusions.
Section:
{chunk}'''개선 체인: 대안 패턴
개선 체인은 맵리듀스의 대안입니다. 청크를 순차적으로 처리하여 청크 N의 요약을 청크 N+1과 함께 전달하고, 모델이 누적 요약을 갱신하도록 합니다. 이 방식은 더 일관성 있는 결과를 생성하지만 병렬화할 수 없고 더 느립니다.
서사적 일관성이 중요할 때(예: 법률 계약서)는 개선 체인을 사용합니다. 속도가 중요할 때(예: 뉴스 기사 묶음)는 맵리듀스를 사용합니다.
def refine_summarize(chunks):
current_summary = summarize_chunk(chunks[0])
for chunk in chunks[1:]:
prompt = (
f'Existing summary:\n{current_summary}\n\n'
f'New section:\n{chunk}\n\n'
'Update the summary to incorporate the new section.'
)
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
current_summary = resp.choices[0].message.content
return current_summary비용 및 토큰 관리
맵리듀스는 많은 API 호출을 생성합니다. 입력 토큰 100만 개당 5달러인 gpt-4o를 사용하여 100개 청크 문서를 처리하는 경우:
- 맵: 청크 100개 × 토큰 1000개 = 입력 토큰 100k개 ≈ $0.50
- 리듀스: 약 10k개 토큰(요약) ≈ $0.05
- 합계: 문서당 약 $0.55
비용을 줄이려면 맵 단계에 gpt-4o-mini($0.15/1M)를 사용하고 리듀스에는 gpt-4o만 사용합니다. 이 하이브리드 방식은 품질 저하를 최소화하면서 비용을 70% 절감합니다.
def map_phase_cheap(chunks):
# Use mini model for map — cheaper, sufficient for chunk summaries
return [
summarize_chunk(c, model='gpt-4o-mini')
for c in chunks
]
def reduce_phase_quality(summaries):
# Use full model for final synthesis
return reduce_phase(summaries, model='gpt-4o')맵리듀스를 사용하는 경우
맵리듀스 요약은 다음과 같은 경우에 가장 적합합니다:
- 모델의 컨텍스트 창보다 긴 문서
- 여러 문서의 일괄 요약(문서 수준에서도 병렬화 가능)
- 각 단계의 프롬프트를 직접 제어해야 하는 경우
다음과 같은 경우에는 적합하지 않습니다. 특정 사실을 추출해야 하는 경우(대신 검색 사용), 또는 문서가 컨텍스트에 들어갈 만큼 짧은 경우(그냥 직접 요약).
지식 확인
맵리듀스 요약 패턴에서 리듀스 단계에는 어떤 일이 일어나나요?
복습: 맵리듀스 요약
맵리듀스 패턴은 한 번의 LLM 호출로 처리하기에는 너무 긴 문서를 다룹니다:
- 맵: 각 청크를 독립적으로 요약 — 병렬화 가능
- 리듀스: 청크 요약을 하나의 최종 요약으로 종합
- 재귀적 리듀스: 요약 자체가 너무 길 때 적용
- 비용 절감 팁: 맵에는 저렴한 모델을, 리듀스에는 고품질 모델을 사용
LangChain의 MapReduceDocumentsChain은 바로 사용할 수 있는 구현을 제공합니다. 다음 수업에서는 책과 연구 논문을 위한 계층적 요약을 다룹니다.
자주 묻는 질문
“맵-리듀스 요약 패턴” 강의는 무료인가요?
네 — “맵-리듀스 요약 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
“맵-리듀스 요약 패턴”에서 뭘 배우나요?
각 청크를 독립적으로 요약한 다음 요약 결과를 종합합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“맵-리듀스 요약 패턴” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 긴 텍스트를 위한 청킹 전략
- 맵-리듀스 요약 패턴
- 계층적 요약
- 청크 간 맥락 유지하기