Context engineering: как обращаться с окнами на 1M токенов и не словить context rot
Контекстные окна на 1M токенов существуют, но качество просаживается задолго до этого предела. Context engineering — дисциплина эффективного использования контекстного окна: что включать, что суммировать, что подгружать на лету и какие паттерны держат качество, пока контекст растёт.
В 2026 году у вас есть контекстные окна на 1M токенов. Gemini, GPT-5, Claude (с extended thinking) — все поддерживают. Демо показывают, как модели читают целые книги одним проходом. Мечта наконец сбылась: просто положи всё в контекст и пусть модель разбирается.
Реальность, как обычно, тоньше. 1M токенов — это техническая ёмкость, а не гарантия качества. Реальные модели лучше всего работают на 5–50K токенов контекста. На 100K+ появляются тонкие проблемы с качеством. На 500K+ важная информация надёжно теряется. На 1M модель захлёбывается.
Это явление — «context rot» — реально, хорошо задокументировано и видно в evals. Вывод: нельзя просто вывалить всё в контекст и считать дело сделанным. Нужен context engineering: осознанные решения о том, что включать, что суммировать, что подгружать динамически и как структурировать получившийся контекст.
Эта статья — о паттернах и дисциплине эффективного context engineering для серьёзных продакшен-систем.
Что такое context rot
«Context rot» — эмпирическое наблюдение, что качество LLM просаживается по мере роста контекста, даже внутри технического лимита.
Конкретные формы провала:
Lost-in-the-middle. Модели внимательнее к содержимому в начале и в конце контекста. Информацию из середины используют менее надёжно. Факт, поставленный на позицию 50K из 100K, с большей вероятностью будет упущен, чем тот же факт на позиции 1K или 99K.
Bias на свежее. Модели переоценивают свежий контент. В истории разговора старый контекст становится фактически невидим.
Чувствительность к дистракторам. Нерелевантное содержимое в контексте просаживает качество даже на задачах, которым это содержимое не нужно. Модели приходится фильтровать; часть фильтрующего сигнала просачивается в ответ.
Падает качество рассуждений. Многошаговое рассуждение становится менее надёжным с ростом контекста. Модели приходится отслеживать больше; качество отслеживания страдает.
Стоимость и латентность. Независимо от качества: большие контексты — дорого (потокенная цена) и медленно (линейно по токенам для многих моделей).
Это не теоретические опасения. Продакшен-развёртывания с наивно большим контекстом стабильно проигрывают развёртываниям с курированным.
Принцип: меньше — это больше
Главное соображение: контекст — драгоценный, деградирующий ресурс. Используйте его стратегически.
Контекст на 30K токенов с тщательно подобранным содержимым обычно опережает контекст на 300K, куда свалили всё подряд. Качество, стоимость и латентность — всё за маленький контекст.
Это смещает инженерную работу. Не «найти, как впихнуть больше», а «решить, что действительно должно быть в контексте, и положить туда хорошо».
Бюджет контекста
Считайте контекст бюджетом, который распределяете.
Типичное распределение для агента клиентской поддержки:
Total context budget: 30K tokens
- System prompt: 1500 tokens (5%)
- Tool descriptions: 1000 tokens (3%)
- User profile / context: 500 tokens (2%)
- Conversation history summary: 1000 tokens (3%)
- Recent conversation turns (full): 4000 tokens (13%)
- Retrieved relevant knowledge: 12000 tokens (40%)
- User's current message: 500 tokens (2%)
- Output token budget (response): 10K tokens (33%)Каждый компонент конкурирует за место. По мере роста контекста — компромиссы.
Дисциплина: будьте явны в распределении. Не давайте ни одному компоненту расти неограниченно.
Паттерн 1. Многоуровневая память разговора
Для многоходовых разговоров полная история растёт неограниченно. Большинство продакшен-систем используют многоуровневую память.
Уровень 1. Свежие ходы целиком. Последние 5–10 обменов, дословно.
Уровень 2. Суммированные старые ходы. Более раннее в разговоре — сжато в короткое summary.
Уровень 3. Извлечённые факты. Ключевая информация из разговора (имя пользователя, предпочтения, принятые решения), сохранённая как структурированные факты.
Реализация:
On each turn:
1. Take the conversation history.
2. The last 10 turns are kept verbatim.
3. Turns 11-30 are summarized into 200 words ("Earlier, the user discussed X and we agreed Y").
4. Turns 31+ are reduced to extracted facts ("User prefers Python. User is on enterprise tier.").
5. Total memory: ~2K tokens regardless of conversation length.Этот паттерн фундаментален для любого долгоживущего разговора. Без него разговоры деградируют, пока растут.
Нюанс: суммирование должно сохранять информацию, которая понадобится агенту. Если пользователь упомянул номер счёта на ходе 5, а агент не вытянул его в долгую память, к ходу 50 этот номер потерян.
Запускайте суммирование с явными инструкциями, что сохранять:
Summarize the conversation so far. Preserve:
- All facts about the user (name, role, preferences, account info).
- All decisions made.
- All open commitments or follow-ups.
- The current goal of the conversation.
Discard:
- Pleasantries.
- Repeated information.
- Detailed reasoning that's been resolved.Паттерн 2. Just-in-time-извлечение
Вместо предзагрузки контекста — подтягивайте то, что релевантно, тогда, когда оно релевантно.
Антипаттерн: засунуть в контекст все документы пользователя «на всякий случай». Большинству запросов нужно ничтожное подмножество. Контекст потрачен зря; качество страдает.
Лучше: извлекать документы под текущий запрос. Разные запросы — разные документы. Суммарный контекст на вызов остаётся маленьким; релевантность остаётся высокой.
Это просто RAG, применённый дисциплинированно. Ключ: не поддавайтесь искушению «давайте просто включим всё, потому что можем». Это соблазняет даже опытные команды, когда доступны длинноконтекстные модели.
Паттерн 3. Сжатые представления
Для информации, которая всё же должна задерживаться в контексте, используйте сжатые представления.
Оригинал (многословный):
The user has been working in software engineering for 8 years. They started at a small startup called Acme Corp where they worked on backend systems. After 3 years they moved to a larger company called Beta Inc where they did frontend work. They're currently at Gamma LLC working on machine learning systems.Сжатый:
User: SWE, 8 years, currently ML at Gamma LLC. Prior: backend@Acme (3yr), frontend@Beta.Сжатый вариант сохраняет нужные факты в меньшем числе токенов. Для большинства целей модель одинаково хорошо использует и тот и другой.
Применяйте к:
- Профилям пользователя.
- Сводкам документов.
- Контексту прошлых разговоров.
- Записям из базы знаний (когда полный текст не нужен).
Трейд-офф: сжатие теряет нюанс. Используйте полный текст, когда нюанс важен; сжатый — когда нет.
Паттерн 4. Иерархический retrieval
Для очень больших баз знаний извлекайте иерархически.
Шаг 1. Извлеките широкие категории или сводки документов по запросу.
Шаг 2. Внутри самых релевантных категорий извлеките конкретные чанки.
Шаг 3. Включайте в финальный контекст только чанки, выбранные на шаге 2.
Это уводит от «у меня 10K документов, давайте затолкнём их все». Воронка держит контекст компактным.
Вариант: маленький LLM-вызов отбирает, какие чанки наиболее релевантны, прежде чем их включают в основной вызов. Чуть дороже, но заметно режет бутрах контекста.
Паттерн 5. Рефлексия по контексту
Для агентов в долгих задачах периодически рефлексируйте над тем, что в контексте сейчас и что там должно быть.
Every 10 steps, the agent does:
1. Reviews its current context.
2. Identifies what's relevant to ongoing work.
3. Summarizes or drops anything no longer needed.
4. Notes what additional context might help.
5. Replaces the old context with the curated version.Это «сборка мусора» для контекста. Без неё агенты копят устаревшую информацию, которая выталкивает новую, релевантную.
Реализация требует кастомной оркестрации — большинство фреймворков нативно этого не делают. Паттерн: между шагами у агента есть фаза «консолидации памяти», которая корректирует, что находится в контексте.
Паттерн 6. Динамические контекстные окна
Разные части работы агента могут требовать разного оптимального размера контекста.
- Шаги принятия решений: маленький контекст, сфокусированный на конкретном решении.
- Шаги синтеза: контекст побольше, со множеством источников.
- Шаги генерации: средний контекст, с референсами по стилю и формату.
Паттерн: каждый шаг в рабочем процессе агента использует свою форму контекста. Оркестрация управляет, что попадает на какой шаг.
Это требует разбиения работы агента на явные шаги, а не один большой цикл. Тут важен выбор фреймворка (LangGraph справляется естественно; на прямом API — руками).
Паттерн 7. Position-aware-размещение
Учитывая, что модели сильнее обращают внимание на начало и конец контекста, важный контент кладите туда.
Менее эффективно: критическая инструкция, зарытая в середине длинного системного промпта.
Более эффективно: критическая инструкция в самом начале И повторённая ближе к концу.
Для RAG с несколькими извлечёнными документами: самый релевантный — в начало, второй по релевантности — в конец, менее релевантные — в середину.
Это тактическая оптимизация, но она измеримо влияет на выходы.
Паттерн 8. Селективное суммирование
Не всякое суммирование одинаково. Подгоняйте суммирование под нужды downstream-задач.
Плохо: общее summary, которое выкидывает предпочтения пользователя.
Лучше: summary, явно сохраняющее предпочтения пользователя, релевантные downstream-задаче.
Summarize this document focusing on:
- Technical decisions made.
- Stakeholders mentioned.
- Open questions or risks.
Drop:
- General context already known to the team.
- Repeated points.Промпт суммирования инженерится под downstream-использование.
Паттерн 9. Структурированный контекст
Plain text — один вариант. Структурированный контекст (JSON, XML, специфическая разметка) может быть значительно плотнее.
Многословная проза:
The customer's name is John Smith. He's been a customer since March 2023. His current plan is Pro, billed monthly at $29. He has 3 active integrations: Slack, Notion, and Linear. His usage in the last 30 days has been moderate — 1,250 API calls.Структурированный:
{
"customer": {
"name": "John Smith",
"since": "2023-03",
"plan": "Pro",
"billing": "monthly $29",
"integrations": ["Slack", "Notion", "Linear"],
"usage_30d": {"api_calls": 1250, "tier": "moderate"}
}
}Структурированный вариант короче и (часто) проще для модели. Модель быстро находит конкретные факты.
Оговорка: не все модели одинаково хорошо работают со структурированным входом. Тестируйте оба формата под свой кейс.
Паттерн 10. Слои контекста
Слоями по приоритету. Высокий приоритет — всегда включается; средний — когда релевантно; низкий — подтягивается по требованию.
Всегда:
- Системный промпт (идентичность, поведение).
- Текущий контекст пользователя (ключевые факты).
- Свежий разговор.
Когда релевантно:
- Извлечённые документы под запрос.
- Выходы инструментов с недавних шагов.
По требованию:
- Конкретные данные, которые агент запрашивает через вызовы инструментов.
- Исторический контекст за пределами свежего окна.
Паттерн «по требованию» критичен для масштабирования: агент достаёт то, что нужно, когда нужно, а не предзагружает всё.
Паттерн 11. Стратегии вытеснения
Когда контекст подходит к лимитам — что выкидывать?
- По свежести: старое — первым.
- По релевантности: наименее связанное с текущей задачей — первым.
- По важности: помеченное низким приоритетом — первым.
Практичный паттерн: тегайте элементы контекста уровнями приоритета. Когда нужно вытеснить — выкидывайте в порядке приоритета.
context_items = [
{"content": "...", "priority": "critical"}, # Never evict
{"content": "...", "priority": "high"}, # Evict last
{"content": "...", "priority": "medium"}, # Evict if needed
{"content": "...", "priority": "low"}, # Evict first
]
def evict_to_fit(items, budget):
items_by_priority = sorted(items, key=lambda x: priority_value(x.priority))
while total_tokens(items) > budget:
items.remove(items_by_priority.pop(0)) # Remove lowest priority
return itemsПаттерн 12. Кэширование повторяющегося контекста
Многие вызовы переиспользуют один и тот же контекст — тот же системный промпт, те же описания инструментов, тот же профиль пользователя.
Большинство провайдеров теперь поддерживают prompt caching:
- Anthropic: явные маркеры
cache_controlв сообщениях. - OpenAI: автоматически для prefix-matching-запросов.
- Google: явный закешированный контент через API.
Когда переиспользуется один и тот же префикс, закешированная версия быстрее и дешевле (часто на 90%).
Для агентов, делающих много вызовов в сессии, убедитесь, что статические части (системный промпт, инструменты, контекст пользователя) кешируемы. Динамику (текущий шаг, недавние результаты) кладите после кешируемого префикса.
Это одна из самых высоких по ROI оптимизаций. Статический префикс на 10K токенов, используемый в 50 вызовах сессии: полная цена на первом вызове, минус 90% на последующих. Серьёзная экономия.
Паттерн 13. Context-aware-промпты
Промпты могут поощрять модель хорошо использовать контекст:
Reference the documents below to answer the user's question. Always cite the specific document and quote relevant passages.
If you cannot find the answer in the provided documents, say so explicitly. Do not invent information.
When information from multiple documents is relevant, synthesize them and note any disagreements.Такой промптинг снижает галлюцинации на задачах, заземлённых на контекст, и улучшает качество цитирования.
Когда длинный контекст оправдан
Несмотря на context rot, для некоторых задач длинный контекст действительно лучше.
Анализ одного документа. Если задача — «проанализировать этот договор», уместить договор целиком обычно лучше, чем чанковый retrieval.
Сравнение многих элементов. Сравнить 10 договоров бок о бок выигрывает от наличия всех 10 в контексте.
Редактирование кода в контексте. Изменить функцию в файле на 5K строк проще с файлом в контексте, чем со снипетами из retrieval.
Суммирование целого разговора. Готовить summary длинного разговора лучше при полном контексте (до определённой точки).
Паттерн: когда задача фундаментально требует понимать связи между частями содержимого — длинный контекст помогает. Когда задача делается на маленьком срезе — лучше короткий.
Практическая эвристика: контексты до 50K токенов обычно нормальны. 50–200K работают, но качество просаживается. 200K+ часто проигрывают более коротким. Проверяйте эмпирически.
Дисциплина evals
Откуда вы знаете, что ваш context engineering работает? Eval.
Конкретные evals:
Recall-тесты. Вставьте ключевые факты на разные позиции в длинном контексте. Проверьте, использует ли модель их. Замерьте recall в зависимости от позиции.
Дистрактор-тесты. Сравните качество на одном и том же запросе с и без нерелевантного контекста. Измерьте просадку.
Long-context vs RAG. Те же запросы — с полным контекстом против извлечённых чанков. Сравните качество.
Token-efficiency. Качество за евро. По мере роста контекста вы платите больше — растёт ли качество соразмерно?
Эти evals показывают, реально ли ваши решения по контексту помогают. Без них — вы гадаете.
Разобранный пример: research-ассистент
Реальный пример: AI-research-ассистент для небольшой команды.
Задача. Отвечать на вопросы по корпусу из 200 документов (статьи, внутренние документы, заметки со встреч).
Наивный подход. Запихнуть все документы в контекст (300K токенов). Качество приемлемое; стоимость высокая; латентность плохая.
Инженерный подход:
Context budget: 25K tokens
- System prompt: 1500 tokens (cached)
- Tool descriptions (search, fetch_doc, etc.): 800 tokens (cached)
- Conversation memory: 1500 tokens (last 10 turns)
- Retrieved chunks for current query: 18000 tokens (top 12 chunks via RAG)
- User's current question: 200 tokens
- Output budget: ~3000 tokensАгент динамически достаёт чанки под вопрос. Память разговора держит свежий контекст. Статические элементы закешированы.
Результат:
- Латентность: 2–3 секунды (против 10–15 при 300K контексте).
- Стоимость: ~€0,01 на запрос (против ~€0,10).
- Качество: лучше — по eval-набору, потому что релевантному содержимому реально уделяется внимание.
Вот как выглядит дисциплинированный context engineering. Не разовое решение, а постоянная настройка.
Частые ошибки
Несколько паттернов.
Ошибка 1. «Больше контекста — лучше». Тянуться за длинным контекстом как за решением проблем с качеством. Часто справедливо обратное.
Ошибка 2. Нет бюджета контекста. Компоненты растут неограниченно. Секция профиля пользователя становится 5K токенов; секция извлечённых чанков — 50K. Никакой дисциплины.
Ошибка 3. Игнорировать позиции. Критичные инструкции зарыты в середину в надежде, что модель их найдёт. Иногда находит; часто — нет.
Ошибка 4. Многословная проза вместо фактов. Длинные предложения там, где хватило бы структурированных данных. Тратит токены.
Ошибка 5. Нет суммирования разговора. Разговоры растут, пока не упрутся в лимиты. Дальше — либо отваливается хвост, либо ломается.
Ошибка 6. Нет кэширования. Повторяющиеся статические префиксы платят полную цену каждый вызов. Лёгкие деньги, оставленные на столе.
Ошибка 7. Нет evals по выбору контекста. Верить, что «лучшая инженерия контекста» работает. Иногда — нет.
Ошибка 8. Generic-суммирование. Суммировать, не думая о нуждах downstream. Терять то, что важно.
Итог
Длинные контекстные окна реальны, но это не индульгенция, чтобы игнорировать context engineering. Качество просаживается задолго до техлимита. Стоимость и латентность — реальны.
Дисциплина context engineering:
- Относитесь к контексту как к бюджету.
- Стройте многоуровневую память (свежее — дословно, старое — сводкой, древнее — фактами).
- Извлекайте just-in-time, а не превентивно.
- Сжимайте там, где сжатие сохраняет информацию.
- Размещайте критичное в позициях высокого внимания.
- Слои по приоритету.
- Кэшируйте статические префиксы.
- Постоянно прогоняйте evals.
Эти паттерны дают системы, которые работают лучше, быстрее и дешевле наивного «вывали всё в контекст».
Для зрелых продакшен-систем context engineering — одна из областей с наибольшим рычагом. Технические примитивы простые; дисциплина их строгого применения — то, что отличает «демо работает» от «продакшен надёжен».
Вкладывайтесь в паттерны. Стройте дисциплину. На выходе — AI-системы, которые масштабируются грациозно по мере того, как сталкиваются с большим объёмом данных, разговоров и сложности.