การรักษาบริบทระหว่างส่วนต่าง ๆ
การซ้อนทับ บริบทแบบเลื่อนไหล และการแทรกข้อมูลกำกับเพื่อความต่อเนื่อง
การรักษาบริบทระหว่างส่วนต่าง ๆ เป็นบทเรียน AI Prompt Engineering ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน 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 ปรับปรุงสรุปโดยรวมข้อมูลใหม่จากชิ้นส่วนนั้นเข้าไป สรุปสะสมควรสั้น โดยมีขนาด 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การประเมินการคงบริบท
เพื่อตรวจสอบว่ากลยุทธ์ด้านบริบทของคุณทำงานได้ ให้สร้างคำถามทดสอบที่ต้องใช้ข้อมูลจากหลายชิ้นส่วน:
- ให้คำจำกัดความคำศัพท์ที่นำเสนอในชิ้นส่วนที่ 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 ที่ราคา $0.15/1M): 73 × 1030 × $0.15/1M ≈ $0.011
กลยุทธ์ด้านบริบทเพิ่มต้นทุนเพียงเล็กน้อย แต่ช่วยปรับปรุงความสอดคล้องได้อย่างมาก
ตรวจสอบความรู้
จุดประสงค์ของ สรุปสะสม ในการประมวลผลเอกสารทีละชิ้นส่วนคืออะไร
สรุปทบทวน: บริบทระหว่างชิ้นส่วน
กลยุทธ์สี่ประการสำหรับรักษาบริบทระหว่างชิ้นส่วน:
- ส่วนซ้อนทับ: ทำซ้ำโทเค็น N รายการสุดท้ายของชิ้นส่วน N ไว้ที่จุดเริ่มต้นของชิ้นส่วน N+1
- สรุปสะสม: แทรกบทคัดย่อสั้น ๆ ที่สะสมต่อเนื่องก่อนแต่ละชิ้นส่วน
- แท็กข้อมูลเมตา: ส่วนหัวที่มีข้อมูลเอกสาร บท ส่วน และหน้า
- เครื่องหมายหน้า: ฝังหมายเลขหน้าลงในข้อความก่อนแบ่งเป็นชิ้นส่วน
รวมทั้งสี่กลยุทธ์เข้าด้วยกันสำหรับกระบวนการใช้งานจริง ทดสอบการคงบริบทระหว่างชิ้นส่วนด้วยคำถามที่ใช้หลายชิ้นส่วน เนื้อหานี้เป็นบทสรุปของหลักสูตรที่ 16 เรื่องกลยุทธ์การจัดการเอกสารขนาดยาว
คำถามที่พบบ่อย
บทเรียน “การรักษาบริบทระหว่างส่วนต่าง ๆ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การรักษาบริบทระหว่างส่วนต่าง ๆ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Prompt Engineering ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Prompt Engineering มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การรักษาบริบทระหว่างส่วนต่าง ๆ”
การซ้อนทับ บริบทแบบเลื่อนไหล และการแทรกข้อมูลกำกับเพื่อความต่อเนื่อง คุณปฏิบัติ AI Prompt Engineering ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Prompt Engineering หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Prompt Engineering บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การรักษาบริบทระหว่างส่วนต่าง ๆ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Prompt Engineering นี้ได้ไหม
ได้ บทเรียน AI Prompt Engineering ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- กลยุทธ์การแบ่งข้อความยาวเป็นส่วน
- รูปแบบการสรุปแบบ Map-Reduce
- การสรุปแบบลำดับชั้น
- การรักษาบริบทระหว่างส่วนต่าง ๆ