Сохранение контекста между блоками
Используйте перекрытие, скользящий контекст и добавление метаданных для непрерывности
«Сохранение контекста между блоками» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 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 Prompt Engineering с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 53
- Уроки
- 199
Часто задаваемые вопросы
Урок «Сохранение контекста между блоками» бесплатный?
Да — полный текст урока «Сохранение контекста между блоками» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.
Чему я научусь в уроке «Сохранение контекста между блоками»?
Используйте перекрытие, скользящий контекст и добавление метаданных для непрерывности Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Prompt Engineering?
Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Сохранение контекста между блоками»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Prompt Engineering?
Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Стратегии разбиения длинных текстов
- Шаблон обобщения Map-Reduce
- Иерархическое обобщение
- Сохранение контекста между блоками