0Pricing
AI Prompt Engineering · Lekcja

Zachowywanie kontekstu między fragmentami

Nakładanie fragmentów, kontekst kroczący i wstrzykiwanie metadanych zapewniające ciągłość.

Zachowywanie kontekstu między fragmentami to bezpłatna lekcja AI Prompt Engineering na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Prompt Engineering, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Problem kontekstu między fragmentami

Gdy dokument zostaje podzielony na fragmenty, informacje z fragmentu N mogą być potrzebne do prawidłowej interpretacji fragmentu N+1. Na przykład termin zdefiniowany we fragmencie 3 jest używany we fragmencie 7. Bez mechanizmu łączenia kontekstu model przetwarzający fragment 7 nie zna tej definicji.

Problem ten rozwiązują cztery strategie: nakładanie, wstrzykiwanie podsumowania kroczącego, znaczniki metadanych oraz odwołania do numerów stron.

Strategia 1: Nakładanie tokenów

Nakładanie polega na powtórzeniu ostatnich N tokenów fragmentu N na początku fragmentu N+1. Dzięki temu zdanie lub argument rozciągający się na granicy występuje w całości w co najmniej jednym fragmencie.

Typowe nakładanie wynosi 100–200 tokenów (około 75–150 słów). Zbyt duże nakładanie zwiększa redundancję i koszt, a zbyt małe pozostawia luki na granicach.

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')

Nakładanie w wyszukiwaniu a podsumowywanie

Nakładanie działa różnie w zależności od zadania:

  • Wyszukiwanie: nakładanie pomaga — zapytanie pasuje do nakładającego się obszaru w dowolnym z dwóch sąsiednich fragmentów, co poprawia recall. Należy użyć nakładania obejmującego 10–20% rozmiaru fragmentu.
  • Podsumowywanie: nakładanie może powodować powtórzenia — to samo zdanie zostaje podsumowane dwukrotnie. Należy użyć mniejszego nakładania (5–10%) lub usunąć nakładającą się część przed podsumowaniem.
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

Strategia 2: Wstrzykiwanie narastającego podsumowania

Narastające podsumowanie to bieżące streszczenie wszystkich dotychczas przetworzonych fragmentów. Przed przetworzeniem fragmentu N należy wstrzyknąć narastające podsumowanie do promptu jako kontekst. Dzięki temu model uzyskuje wiedzę o wcześniejszej treści bez przekraczania rozmiaru okna kontekstu.

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

Aktualizowanie narastającego podsumowania

Narastające podsumowanie powinno być rozszerzane stopniowo. Po przetworzeniu każdego fragmentu należy poprosić LLM o zaktualizowanie podsumowania przez uwzględnienie nowych informacji z tego fragmentu. Narastające podsumowanie powinno być krótkie — 200–400 tokenów — aby pozostawić miejsce na bieżący fragment.

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

Strategia 3: Znaczniki metadanych

Znaczniki metadanych dołączają ustrukturyzowane informacje do każdego fragmentu, dzięki czemu LLM wie, co przetwarza, i może zachować logiczną ciągłość.

Typowe znaczniki to: document_title, chapter, section, page, chunk_index, total_chunks. Należy wstrzykiwać je jako nagłówek w prompcie, a nie w tekście fragmentu, aby oddzielić treść od metadanych.

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
    }
)

Strategia 4: Odwołania do numerów stron

Gdy fragment odwołuje się do czegoś z wcześniejszej strony, model może wskazać to odwołanie, jeśli numery stron są osadzone w tekście. Przed podziałem na fragmenty należy wstawić znaczniki podziału stron, aby zachowały się w fragmentach:

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)

Łączenie strategii

W środowisku produkcyjnym należy połączyć wszystkie cztery strategie, aby maksymalnie wiernie zachować kontekst:

  1. Przed podziałem na fragmenty dodać znaczniki stron
  2. Podzielić tekst na fragmenty z nakładaniem się 200 tokenów
  3. Dołączyć nagłówek metadanych do promptu każdego fragmentu
  4. Przed każdym fragmentem wstrzyknąć narastające podsumowanie

Takie połączenie gwarantuje, że model zawsze wie, w którym miejscu dokumentu się znajduje, co pojawiło się wcześniej i jaki jest związek bieżącego fragmentu z całością.

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

Ocena zachowania kontekstu

Aby sprawdzić, czy strategia zachowania kontekstu działa prawidłowo, należy utworzyć pytania testowe wymagające informacji z wielu fragmentów:

  • Zdefiniowanie terminu wprowadzonego we fragmencie 2 na podstawie pytania z fragmentu 8
  • Obliczenie sumy obejmującej wiele stron
  • Wskazanie sprzeczności między rozdziałem 1 a rozdziałem 5

Należy uruchomić potok i sprawdzić, czy odpowiedzi prawidłowo odwołują się do wcześniejszej treści. Jeśli odpowiedzi są niepoprawne, należy zwiększyć nakładanie się fragmentów lub rozmiar narastającego podsumowania.

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"]}')

Podsumowanie kompromisów

Każda strategia ma swoje koszty i korzyści:

  • Nakładanie się fragmentów: proste rozwiązanie, zwiększa liczbę tokenów o procent nakładania się, może powodować powtarzanie treści w podsumowaniu
  • Narastające podsumowanie: skuteczne, dodaje jedno wywołanie LLM na fragment, podsumowanie może z czasem odbiegać od treści lub tracić szczegóły
  • Znaczniki metadanych: nie wiążą się z dodatkowym kosztem, pomagają modelowi zorientować się w treści, ale nie zastępują jej
  • Znaczniki stron: umożliwiają prześledzenie źródła, zwiększają liczbę znaków w tekście, ale tylko nieznacznie wpływają na liczbę tokenów

Na początku należy użyć nakładania się fragmentów i metadanych. Narastające podsumowanie warto dodać dopiero wtedy, gdy testy wykażą problemy z zachowaniem kontekstu między fragmentami.

Praktyczny przewodnik doboru rozmiarów

Praktyczne wartości dla dokumentu o długości 100 stron (średnio 500 tokenów na stronę, czyli łącznie 50 000 tokenów):

  • Rozmiar fragmentu: 800 tokenów, nakładanie się: 150 tokenów → ~73 fragmenty
  • Narastające podsumowanie: maksymalnie 200 tokenów (aktualizowane po każdym fragmencie)
  • Nagłówek metadanych: ~30 tokenów na fragment
  • Efektywne dane wejściowe na wywołanie API: 800 + 200 + 30 = 1030 tokenów
  • Koszt mapowania (gpt-4o-mini przy $0.15/1M): 73 × 1030 × $0.15/1M ≈ $0.011

Strategie zachowania kontekstu wiążą się z minimalnym kosztem, a jednocześnie znacząco poprawiają spójność.

Sprawdzenie wiedzy

Jaki jest cel narastającego podsumowania podczas przetwarzania dokumentu fragment po fragmencie?

Powtórzenie: kontekst między fragmentami

Cztery strategie zachowywania kontekstu między fragmentami:

  • Nakładanie się fragmentów: powtórzenie ostatnich N tokenów fragmentu N na początku fragmentu N+1
  • Narastające podsumowanie: wstrzyknięcie krótkiego bieżącego streszczenia przed każdym fragmentem
  • Znaczniki metadanych: nagłówek z informacjami o dokumencie, rozdziale, sekcji i stronie
  • Znaczniki stron: osadzenie numerów stron w tekście przed podziałem na fragmenty

W potokach produkcyjnych należy połączyć wszystkie cztery strategie. Zachowanie kontekstu między fragmentami należy testować za pomocą pytań wymagających informacji z wielu fragmentów. Na tym kończy się Kurs 16 poświęcony strategiom obsługi długich dokumentów.

Często zadawane pytania

Czy lekcja „Zachowywanie kontekstu między fragmentami” jest bezpłatna?

Tak — pełny tekst „Zachowywanie kontekstu między fragmentami” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Prompt Engineering, przejdź na CoddyKit PRO. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Co nauczysz się w „Zachowywanie kontekstu między fragmentami”?

Nakładanie fragmentów, kontekst kroczący i wstrzykiwanie metadanych zapewniające ciągłość. Ćwiczysz AI Prompt Engineering z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Prompt Engineering?

Nie wymagamy żadnego doświadczenia. AI Prompt Engineering w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Zachowywanie kontekstu między fragmentami”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Prompt Engineering?

Tak. Każda lekcja AI Prompt Engineering zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Strategie dzielenia długich tekstów na fragmenty
  2. Wzorzec podsumowywania Map-Reduce
  3. Podsumowywanie hierarchiczne
  4. Zachowywanie kontekstu między fragmentami
← Powrót do AI Prompt Engineering