청크 간 맥락 유지하기
연속성을 위해 겹침, 순환 맥락 및 메타데이터 주입을 활용합니다.
청크 간 맥락 유지하기은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
청크 간 문맥 문제
문서를 청크로 나누면 청크 N의 정보가 청크 N+1을 올바르게 해석하는 데 필요할 수 있습니다. 예를 들어 청크 3에서 정의된 용어가 청크 7에서 사용될 수 있습니다. 문맥을 연결하지 않으면 청크 7을 처리하는 모델은 해당 정의를 알 수 없습니다.
이 문제를 해결하는 네 가지 전략은 오버랩, 누적 요약 주입, 메타데이터 태그, 페이지 번호 참조입니다.
전략 1: 토큰 오버랩
오버랩은 청크 N의 마지막 N개 토큰을 청크 N+1의 시작 부분에 반복하는 방식입니다. 따라서 경계를 가로지르는 문장이나 주장이 적어도 하나의 청크에는 온전히 포함됩니다.
일반적인 오버랩은 100~200개 토큰(대략 75~150단어)입니다. 오버랩이 너무 많으면 중복성과 비용이 증가하고, 너무 적으면 경계에 공백이 생깁니다.
import tiktoken
enc = tiktoken.get_encoding('cl100k_base')
def chunk_with_overlap(text, max_tokens=1000, overlap=200):
tokens = enc.encode(text)
chunks = []
step = max_tokens - overlap
i = 0
while i < len(tokens):
chunk = tokens[i:i + max_tokens]
chunks.append(enc.decode(chunk))
i += step
return chunks
chunks = chunk_with_overlap(document, max_tokens=1000, overlap=200)
print(f'{len(chunks)} chunks with 200-token overlap')검색과 요약에서의 오버랩
오버랩은 작업에 따라 다르게 작동합니다:
- 검색: 오버랩이 도움이 됩니다. 질의가 인접한 두 청크 중 어느 쪽의 오버랩 영역과도 일치할 수 있어 검색 재현율이 향상됩니다. 청크 크기의 10~20%를 오버랩으로 사용합니다.
- 요약: 오버랩은 반복을 일으킬 수 있습니다. 같은 문장이 두 번 요약되기 때문입니다. 더 작은 오버랩(5~10%)을 사용하거나 요약하기 전에 오버랩을 제거합니다.
def strip_overlap(chunks, overlap_tokens=200):
'''Remove the leading overlap from each chunk (except the first).'''
cleaned = [chunks[0]]
for chunk in chunks[1:]:
tokens = enc.encode(chunk)
trimmed = enc.decode(tokens[overlap_tokens:])
cleaned.append(trimmed)
return cleaned전략 2: 누적 요약 주입
누적 요약은 지금까지 처리한 모든 청크를 계속 요약해 둔 개요입니다. 청크 N을 처리하기 전에 누적 요약을 문맥으로 프롬프트에 주입합니다. 이렇게 하면 문맥 창을 초과하지 않고도 모델이 이전 내용을 파악할 수 있습니다.
import openai
client = openai.OpenAI(api_key='sk-...')
def process_with_rolling_summary(chunks):
rolling_summary = ''
results = []
for i, chunk in enumerate(chunks):
context = ''
if rolling_summary:
context = f'Summary of previous sections:\n{rolling_summary}\n\n'
prompt = context + f'Current section:\n{chunk}'
resp = client.chat.completions.create(
model='gpt-4o',
messages=[
{'role': 'system', 'content': 'Answer questions or summarize, using prior context.'},
{'role': 'user', 'content': prompt}
]
)
result = resp.choices[0].message.content
results.append(result)
# Update rolling summary
rolling_summary = update_rolling_summary(rolling_summary, chunk)
return results누적 요약 갱신
누적 요약은 점진적으로 늘어나야 합니다. 각 청크를 처리한 후 LLM에 해당 청크의 새 정보를 반영하여 요약을 update하도록 요청합니다. 현재 청크를 위한 공간을 남겨 두도록 누적 요약을 짧게 유지하세요(200~400토큰).
def update_rolling_summary(current_summary, new_chunk, max_words=150):
if not current_summary:
prompt = f'Summarize the following in under {max_words} words:\n\n{new_chunk}'
else:
prompt = (
f'Current running summary (under {max_words} words):\n{current_summary}\n\n'
f'New section to incorporate:\n{new_chunk}\n\n'
f'Update the summary to include the new section. Stay under {max_words} words.'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.content전략 3: 메타데이터 태그
메타데이터 태그는 각 청크에 구조화된 정보를 연결하여 LLM이 무엇을 처리하고 있는지 파악하고 논리적 연속성을 유지할 수 있게 합니다.
일반적인 태그는 document_title, chapter, section, page, chunk_index, total_chunks입니다. 내용과 메타데이터를 분리하려면 이러한 태그를 청크 텍스트가 아니라 프롬프트의 헤더로 주입하세요.
def build_prompt_with_metadata(chunk, metadata):
header = (
f'Document: {metadata["title"]}\n'
f'Chapter: {metadata["chapter"]}\n'
f'Section: {metadata["section"]}\n'
f'Page: {metadata["page"]}\n'
f'Chunk: {metadata["chunk_index"] + 1} of {metadata["total_chunks"]}\n'
'---\n'
)
return header + chunk
prompt = build_prompt_with_metadata(
chunk=chunks[5],
metadata={
'title': 'Annual Report 2024',
'chapter': '3. Financial Results',
'section': '3.2 Revenue Breakdown',
'page': 42,
'chunk_index': 5,
'total_chunks': 120
}
)전략 4: 페이지 번호 참조
청크가 이전 페이지의 내용을 참조할 때 페이지 번호가 삽입되어 있으면 모델이 이를 인용할 수 있습니다. 청크로 나누기 전에 텍스트에 페이지 구분을 표시자로 주입하면 해당 표시자가 청크에 남습니다:
def inject_page_markers(pages):
'''pages: list of strings, one per page.'''
marked = []
for i, page_text in enumerate(pages):
marked.append(f'[PAGE {i+1}]\n{page_text}')
return '\n\n'.join(marked)
# When the model sees [PAGE 12] in context, it can say
# 'As defined on page 12...' in its output, enabling traceability.
document_with_markers = inject_page_markers(pdf_pages)
chunks = chunk_with_overlap(document_with_markers)전략 결합
운영 환경에서는 문맥 충실도를 최대화하기 위해 네 가지 전략을 모두 결합하세요:
- 청크로 나누기 전에 페이지 표시자 추가
- 200토큰이 겹치도록 청크로 나누기
- 각 청크 프롬프트에 메타데이터 헤더 연결
- 각 청크 전에 누적 요약 주입
이 결합 방식은 모델이 문서에서 현재 위치, 앞선 내용, 현재 청크가 전체와 어떤 관련이 있는지를 항상 파악하도록 합니다.
def process_document(pages, doc_metadata):
# Step 1: inject page markers
full_text = inject_page_markers(pages)
# Step 2: chunk with overlap
chunks = chunk_with_overlap(full_text, max_tokens=900, overlap=150)
total = len(chunks)
rolling_summary = ''
results = []
for i, chunk in enumerate(chunks):
meta = {**doc_metadata, 'chunk_index': i, 'total_chunks': total}
prompt = build_prompt_with_metadata(chunk, meta)
if rolling_summary:
prompt = 'Prior context:\n' + rolling_summary + '\n\n' + prompt
result = call_llm(prompt)
results.append(result)
rolling_summary = update_rolling_summary(rolling_summary, chunk)
return results문맥 유지 평가
문맥 전략이 제대로 작동하는지 확인하려면 여러 청크의 정보가 필요한 검사 질문을 create하세요:
- 청크 2에서 소개하고 청크 8에서 묻는 용어 정의
- 여러 페이지에 걸친 합계 계산
- 1장과 5장 사이의 모순 식별
처리 과정을 실행하고 답변이 이전 내용을 올바르게 참조하는지 확인하세요. 실패하면 겹침 크기나 누적 요약 크기를 늘리세요.
test_questions = [
{
'question': 'What is the definition of "net recurring revenue" used in this report?',
'defined_in_chunk': 2,
'asked_in_chunk': 9,
'expected_keywords': ['net recurring revenue', 'subscription', 'exclude']
}
]
def evaluate_context_retention(pipeline_results, test_questions):
for test in test_questions:
answer = pipeline_results[test['asked_in_chunk']]
for kw in test['expected_keywords']:
if kw.lower() not in answer.lower():
print(f'FAIL: missing "{kw}" in answer to chunk {test["asked_in_chunk"]}')장단점 요약
각 전략에는 비용과 이점이 있습니다:
- 겹침: 간단하고, 겹침 비율만큼 토큰 수를 늘리며, 요약 과정에서 반복이 생길 수 있습니다
- 누적 요약: 강력하지만 청크마다 LLM 호출이 한 번 추가되고, 요약이 점차 어긋나거나 세부 정보를 잃을 수 있습니다
- 메타데이터 태그: 추가 비용 없이 넣을 수 있고 모델의 위치 파악을 돕지만, 내용을 대신하지는 않습니다
- 페이지 표시자: 추적 가능성을 높이고 텍스트에 문자를 추가하지만 토큰 증가는 최소화됩니다
먼저 겹침과 메타데이터를 사용하세요. 검사에서 청크 간 문맥 실패가 관찰될 때만 누적 요약을 추가하세요.
실전 크기 가이드
100페이지 문서(페이지당 평균 500토큰, 총 50,000토큰)에 적용할 실제 크기:
- 청크 크기: 800토큰, 겹침 150토큰 → 약 73개 청크
- 누적 요약: 최대 200토큰(각 청크 처리 후 갱신)
- 메타데이터 헤더: 청크당 약 30토큰
- API 호출당 실제 입력: 800 + 200 + 30 = 1030토큰
- 맵 비용(gpt-4o-mini, 1백만 토큰당 $0.15): 73 × 1030 × $0.15/1M ≈ $0.011
문맥 전략은 비용을 거의 늘리지 않으면서 일관성을 크게 향상합니다.
지식 확인
청크 단위로 문서를 처리할 때 누적 요약의 목적은 무엇인가요?
복습: 청크 간 문맥
청크 간 문맥을 유지하는 네 가지 전략:
- 겹침: 청크 N의 마지막 N개 토큰을 청크 N+1의 시작 부분에 반복
- 누적 요약: 각 청크 전에 짧은 누적 개요를 주입
- 메타데이터 태그: 문서, 장, 절, 페이지 정보가 담긴 헤더
- 페이지 표시자: 청크로 나누기 전에 텍스트에 페이지 번호 삽입
운영 환경의 처리 과정에는 네 가지를 모두 결합하세요. 여러 청크에 걸친 질문으로 청크 간 문맥 유지를 검사하세요. 이것으로 장문 문서 처리 전략에 관한 16번째 과정을 마칩니다.
AI 튜터와 함께 AI Prompt Engineering을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 53
- 레슨
- 199
자주 묻는 질문
“청크 간 맥락 유지하기” 강의는 무료인가요?
네 — “청크 간 맥락 유지하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 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개 중 4번째 강의입니다.
“청크 간 맥락 유지하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 긴 텍스트를 위한 청킹 전략
- 맵-리듀스 요약 패턴
- 계층적 요약
- 청크 간 맥락 유지하기