0Pricing
AI Prompt Engineering · บทเรียน

การรักษาบริบทระหว่างส่วนต่าง ๆ

การซ้อนทับ บริบทแบบเลื่อนไหล และการแทรกข้อมูลกำกับเพื่อความต่อเนื่อง

การรักษาบริบทระหว่างส่วนต่าง ๆ เป็นบทเรียน 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)

การรวมกลยุทธ์

ในการใช้งานจริง ให้รวมทั้งสี่กลยุทธ์เข้าด้วยกันเพื่อรักษาความเที่ยงตรงของบริบทให้สูงสุด:

  1. เพิ่มเครื่องหมายหน้าก่อนแบ่งเป็นชิ้นส่วน
  2. แบ่งเป็นชิ้นส่วนโดยมีส่วนซ้อนทับ 200 โทเค็น
  3. แนบส่วนหัวข้อมูลเมตาเข้ากับพรอมต์ของแต่ละชิ้นส่วน
  4. แทรกสรุปสะสมก่อนประมวลผลแต่ละชิ้นส่วน

แนวทางแบบผสมนี้ช่วยให้โมเดลทราบอยู่เสมอว่าอยู่ ณ จุดใดในเอกสาร มีเนื้อหาใดมาก่อน และชิ้นส่วนปัจจุบันสัมพันธ์กับเอกสารทั้งหมดอย่างไร

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. กลยุทธ์การแบ่งข้อความยาวเป็นส่วน
  2. รูปแบบการสรุปแบบ Map-Reduce
  3. การสรุปแบบลำดับชั้น
  4. การรักษาบริบทระหว่างส่วนต่าง ๆ
← กลับไปที่ AI Prompt Engineering