Проблема: больше контекста ≠ лучше

Интуиция подсказывает: раз окно 200k токенов, надо использовать его целиком — вся история, все документы, все инструменты. На практике это ухудшает агента сразу по трём осям.

ОсьЧто происходит при раздутом контексте
КачествоМодель хуже находит нужное среди шума, путается, следует не тем инструкциям
СтоимостьПлатишь за каждый входной токен на каждом шаге агента — растёт квадратично по ходу диалога
ЛатентностьБольше входных токенов → дольше обработка → выше время ответа

Особенно коварна экономика: у агента каждый шаг reasoning отправляет весь накопленный контекст заново. Диалог из 10 шагов с растущей историей — это не 10 отправок по 1k токенов, а 1k+2k+3k+…: суммарно на порядок больше. Раздутый контекст бьёт по счёту тем сильнее, чем длиннее работает агент.

⚠️ Context rot: качество падает с ростом длины

Ключевой эффект, который надо принять: способность модели надёжно использовать информацию деградирует по мере роста контекста. Известное проявление — «lost in the middle»: факты в начале и в конце промпта модель использует заметно лучше, чем закопанные в середине. Практический вывод: 200k-окно — это не «200k полезной памяти», а верхняя техническая граница, у которой качество уже не то. Помещается ≠ работает. Важное клади ближе к краям (особенно к концу) и убирай лишнее.

Бюджет контекста

Первый шаг инженерного подхода — перестать считать контекст «бесконечным» и начать считать его бюджетом: сколько токенов на что тратится. У агента конкуренты за окно всегда одни и те же.

100%
колёсико — масштаб  ·  зажать и тянуть — перемещение
Кто конкурирует за контекстное окно агента system описания tools история диалога (растёт!) RAG-документы запрос + место под ОТВЕТ модели — его тоже надо оставить! Как растёт при работе агента (каждый шаг шлёт ВСЁ заново): шаг 1 — 2k токенов шаг 2 — 4k (+ ответ tool) шаг 3 — 7k шаг 5 — 14k шаг 10 — 40k+ · платим за КАЖДЫЙ токен на КАЖДОМ шаге · качество уже «поплыло» CONTEXT ROT: чем длиннее контекст, тем хуже модель им пользуется «lost in the middle» — начало и конец работают лучше середины · помещается ≠ работает

Практика бюджетирования проста: прикинь лимит на каждую статью и следи, чтобы сумма не приближалась к окну (оставив место под ответ). Например: system — до 1k, инструменты — до 2k, RAG — до 4k, история — до 8k. Как только история упирается в свой лимит — включается сжатие (ниже), а не «пусть растёт, окно большое».

Управление историей диалога

История — главный «пожиратель» контекста у агента, потому что она единственная растёт неограниченно. Основные стратегии (часто комбинируют):

СтратегияКак работаетМинус
Sliding windowДержим последние N сообщений, старые выбрасываемПолная потеря ранних деталей
SummarizationСтарую часть сжимаем в краткую сводку (LLM)Стоит вызова; сводка теряет нюансы
Обрезка tool-выходовОгромные ответы инструментов урезаем/суммаризируемМожно срезать нужное
Вынос наружуДетали в файл/БД, в контексте — только ссылкаНужен инструмент чтения
Гибрид: свежие сообщения целиком + сводка старых
python
KEEP_RECENT = 6          # последние сообщения — дословно
HISTORY_BUDGET = 8000    # лимит токенов на историю

def compact_history(messages: list, summary: str | None):
    if count_tokens(messages) <= HISTORY_BUDGET:
        return messages, summary            # влезаем — ничего не делаем

    recent = messages[-KEEP_RECENT:]        # хвост важен: свежий контекст
    older  = messages[:-KEEP_RECENT]

    # старое сжимаем в сводку (доклеивая к предыдущей — сводка накопительная)
    summary = llm(f"""Кратко суммируй ход диалога, сохранив:
решения, факты, незакрытые задачи. Предыдущая сводка: {summary or '—'}
Новые сообщения: {render(older)}""", temperature=0)

    # сводка идёт как system-сообщение ПЕРЕД свежими
    return [{"role": "system", "content": f"Сводка ранее: {summary}"}] + recent, summary

# обрезаем и «толстые» ответы инструментов — они раздувают историю быстрее всего
def trim_tool_output(text: str, limit: int = 2000) -> str:
    return text if len(text) <= limit else text[:limit] + "\n…[обрезано]"
✅ Сжимай tool-выходы агрессивнее всего

Самый дешёвый выигрыш: ответы инструментов (JSON API, дампы поиска, HTML страницы) часто занимают больше, чем весь остальной диалог, а полезной информации в них — пара строк. Обрезай/суммаризируй их до попадания в историю, а не потом. Правило: инструмент должен возвращать ответ, а не сырые данные. Это же снижает риск того, что модель утонет в мусоре и потеряет инструкцию.

Отбор: инструменты и документы

История — не единственный источник раздувания. Два других — описания инструментов и RAG-документы, и оба лечатся отбором.

  • Инструменты. Описания всех tools уходят в каждый запрос. 40 инструментов — это тысячи токенов на каждом шаге, плюс модели труднее выбрать нужный. Решение: давать только релевантные текущей задаче (динамический отбор по этапу/намерению) — прямая связь с Skills-роутингом из модуля 05.
  • RAG-документы. Соблазн «дадим top-50 чанков, вдруг пригодится» вредит: релевантное тонет в шуме (context rot). Лучше меньше, но точнее — качественный retrieval и reranking важнее объёма (модуль 04).
  • Порядок важен. Раз середина работает хуже — критичные инструкции и самые релевантные документы ставь ближе к концу промпта, ближе к вопросу.
⚠️ «Положим побольше, вдруг пригодится» — антипаттерн

Каждый лишний блок в контексте не нейтрален: он стоит денег, добавляет латентность и снижает вероятность, что модель заметит действительно нужное. Правильный вопрос не «влезет ли?», а «изменит ли это ответ?». Если блок не влияет на решение — он не должен попадать в окно. Контекст — не склад, а рабочий стол: чем чище, тем точнее работа.

Изоляция контекста через субагентов

Мощная структурная техника (мостик к модулю 05): если задача требует много «грязной» работы с большими данными, вынеси её в субагента с отдельным контекстным окном. Субагент перелопачивает документы в своём окне и возвращает наверх короткую выжимку, а не сырьё.

❌ Один агент на всё:
  главный контекст ← 50 документов + история + всё подряд → распух, качество ↓

✅ Изоляция через субагента:
  главный агент (чистый контекст, видит только итоги)
       │  «изучи эти 50 документов по теме X»
       ▼
  субагент (СВОЙ контекст: 50 документов, черновая работа)
       │  возвращает выжимку на 300 токенов
       ▼
  главный агент ← +300 токенов вместо +40 000

Грязная работа — в изолированном окне, наверх — только результат.

Это тот же принцип, что «агент-как-инструмент» из модуля 05: снаружи виден компактный результат, а сложность (и раздутый контекст) спрятаны внутри. Так же работают и файлы как внешняя память: агент пишет промежуточные результаты в файл и читает нужное по требованию, вместо того чтобы тащить всё в окне.

🎯 Три рычага context engineering

Сводя воедино: сжимай (суммаризация истории, обрезка tool-выходов), отбирай (только нужные инструменты и документы, важное — ближе к концу), изолируй (субагенты и внешняя память вместо одного распухшего окна). Эти три рычага решают почти все проблемы с контекстом — и одновременно снижают стоимость и латентность, о которых пойдёт речь в следующих уроках раздела.

Типичные ошибки

❌ Ошибка 1: «окно большое — влезет всё»

Помещается ≠ работает. Длинный контекст роняет качество (context rot), стоимость и скорость. Считай бюджет, а не заполняй окно до предела.

❌ Ошибка 2: неограниченный рост истории

Агент шлёт всю историю на каждом шаге — расходы растут лавинообразно, качество падает. Нужны sliding window + суммаризация с лимитом токенов.

❌ Ошибка 3: сырые tool-выходы в контексте

Дампы API/поиска занимают больше всего места при минимуме пользы. Обрезай и суммаризируй их до попадания в историю.

❌ Ошибка 4: все инструменты и top-50 чанков всегда

Описания всех tools и лишние документы уходят в каждый запрос, топя релевантное в шуме. Отбирай динамически, важное ставь ближе к концу.

Шпаргалка

Context engineering — всё в одном месте
text
КОНТЕКСТ = ограниченный ДОРОГОЙ ресурс с убывающей отдачей (не бесконечная память)
  больше ≠ лучше: КАЧЕСТВО↓ (context rot) · СТОИМОСТЬ↑ · ЛАТЕНТНОСТЬ↑
  CONTEXT ROT: чем длиннее, тем хуже модель находит нужное
  «lost in the middle» — края работают лучше середины · ПОМЕЩАЕТСЯ ≠ РАБОТАЕТ

ЭКОНОМИКА АГЕНТА: каждый шаг шлёт ВЕСЬ накопленный контекст ЗАНОВО
  10 шагов ≠ 10×1k, а 1k+2k+3k+… → раздутый контекст бьёт тем сильнее, чем дольше работа

БЮДЖЕТ КОНТЕКСТА (лимит на каждую статью, + место под ОТВЕТ):
  system · описания tools · ИСТОРИЯ (растёт!) · RAG-документы · запрос

3 РЫЧАГА:
  ① СЖИМАЙ: sliding window (последние N) · summarization старого (накопительная сводка) ·
     ОБРЕЗКА TOOL-ВЫХОДОВ (самый дешёвый выигрыш!) · вынос деталей в файл/БД
     правило: инструмент возвращает ОТВЕТ, а не сырые данные
  ② ОТБИРАЙ: только релевантные tools (40 tools = тысячи токенов КАЖДЫЙ шаг) ·
     меньше, но точнее чанков (reranking > объём) · важное БЛИЖЕ К КОНЦУ
     вопрос не «влезет ли?», а «ИЗМЕНИТ ЛИ ЭТО ОТВЕТ?»
  ③ ИЗОЛИРУЙ: субагент со СВОИМ окном делает грязную работу → наверх выжимка (300 токенов
     вместо 40 000) · файлы как внешняя память · = «агент-как-инструмент» (модуль 05)

ГРАБЛИ: «окно большое — влезет всё» · безлимитная история · сырые tool-выходы ·
        все tools + top-50 чанков всегда

Практическое задание

Задание: наведи порядок в контексте агента

  1. Для агента из модулей 03–05 замерь по трейсу (LangSmith/Langfuse), сколько входных токенов уходит на шаге 1 и на последнем шаге. Во сколько раз вырос контекст?
  2. Разложи контекст по статьям (system / tools / история / RAG / запрос): что занимает больше всего? Назначь бюджет каждой статье.
  3. Найди самый «толстый» ответ инструмента. Сколько в нём полезного? Добавь обрезку/суммаризацию до попадания в историю — насколько упал общий контекст?
  4. Реализуй гибрид: последние N сообщений дословно + накопительная сводка старых. Проверь, что агент не теряет ключевые решения из ранней части диалога.
  5. Посчитай, сколько токенов занимают описания всех твоих инструментов. Можно ли давать не все? По какому признаку отбирать?
  6. Найди задачу, которую стоит вынести в субагента с изолированным контекстом. Сколько токенов это сэкономит главному агенту?
  7. Со звёздочкой: прогони offline-оценку (раздел «Оценка качества») до и после сжатия контекста. Качество сохранилось? Насколько упала стоимость запроса?

Что дальше

Мы сократили контекст до необходимого. Но часть его неизбежно повторяется в каждом запросе: системный промпт, описания инструментов, инструкции. Платить за них заново на каждом шаге — расточительство, и провайдеры дают способ этого избежать. Следующий урок — prompt caching: как кэшировать неизменную часть промпта и экономить до 90% стоимости.