# Context rot (деградация контекста): почему длинный контекст не значит умный ответ

> **Context rot** (деградация контекста) — снижение качества ответов языковой модели по мере роста длины входа. Все токены при этом формально помещаются в контекстное окно, модель отвечает так же уверенно, но на длинном входе чаще теряет факты из середины, путает инструкции и хуже держит порядок шагов.

Context rot — это про **качество**, а не про **лимит**. Лимит описывает [контекстное окно](/pages/context-window): сколько токенов модель принимает. Деградация показывает, насколько надёжно она работает с тем, что приняла. Запрос на 200 тыс. токенов может пройти без ошибок и всё равно дать худший ответ, чем тот же вопрос на 5 тыс.

## Откуда термин {#otkuda-termin}

Идея не нова: в работе «Lost in the Middle» (Liu et al., 2023) показали, что модели лучше используют информацию из начала и конца контекста, а факты из середины теряют. Дальше стали популярны тесты «иголка в стоге сена» (needle in a haystack): в длинный текст прячут одну фразу и просят её найти. Современные модели обычно проходят такой тест почти идеально, из чего легко сделать вывод, что длинный контекст «решён».

Название закрепил технический отчёт Chroma «Context Rot: How Increasing Input Tokens Impacts LLM Performance» (Kelly Hong, Anton Troynikov, Jeff Huber, июль 2025). Авторы проверили 18 моделей, включая GPT-4.1, Claude 4, Gemini 2.5 и Qwen3, на более реалистичных задачах, чем поиск дословной фразы. Что они нашли:

- качество падало с ростом длины входа во всех экспериментах, даже на простых задачах;
- чем меньше вопрос похож на искомый фрагмент, тем быстрее падает точность;
- один отвлекающий фрагмент (distractor) уже ухудшает результат, четыре ухудшают сильнее;
- на длинной истории диалога (LongMemEval, до 113 тыс. токенов) модели отвечали заметно лучше, когда им давали только нужные фрагменты, а не весь текст.

Код отчёта открыт: [chroma-core/context-rot](https://github.com/chroma-core/context-rot). Anthropic в статье про context engineering тоже называет context rot и относит его ко всем моделям: у одних деградация мягче, у других резче.

## Как это работает {#kak-rabotaet}

Единой причины нет, но обычно называют такие факторы:

- **Внимание размазывается.** В трансформере каждый токен «смотрит» на все остальные, то есть пар взаимосвязей порядка n² на n токенов. Чем длиннее вход, тем слабее выделяется нужное. Anthropic называет это «бюджетом внимания» (attention budget).
- **Мало длинных примеров в обучении.** Короткие последовательности встречаются в обучающих данных чаще, поэтому длинные модель видела реже. Это тоже объяснение из статьи Anthropic.
- **Потеря в середине (lost in the middle).** Начало и конец контекста используются лучше, чем середина.
- **Шум.** Похожие на ответ, но неверные фрагменты (distractors) сбивают модель сильнее, чем явно посторонний текст.
- **Конкурирующие инструкции.** Чем больше в контексте старых правил, примеров и результатов инструментов, тем выше шанс, что модель выполнит не ту инструкцию.

Эффект зависит от модели и задачи. Универсального «порога», после которого всё ломается, нет.

## Что видно на практике {#praktika}

- **Агент на 20-м шаге** начинает повторять уже сделанные действия, забывает принятые решения или теряет исходное ТЗ: оно осталось в самом начале, под десятками логов и результатов команд.
- **RAG с десятками чанков** часто отвечает хуже, чем с несколькими отобранными: лишние фрагменты работают как distractors. Это согласуется с выводом Chroma про «сфокусированный» и «полный» вход. Подробнее про нарезку — в статье про [чанкинг для RAG](/pages/text-chunking-dlya-rag).
- **Длинный чат** начинает противоречить договорённостям из начала разговора.
- **Ответ становится общим**: вместо конкретных деталей из документа модель пересказывает «как обычно бывает».

## Как с этим бороться {#kak-borotsya}

Общий принцип из статьи Anthropic: искать **наименьший набор токенов с высокой информативностью**, а не заполнять окно до предела. Подробнее в статье про [контекст-инжиниринг](/pages/kontekst-inzhiniring-context-engineering).

| Приём | Что делает | Когда применять |
|---|---|---|
| Сокращать вход | Убирать лишнее до отправки: сжимать логи и вывод инструментов, отбирать фрагменты ретривером | Длинные результаты инструментов, RAG. Для агентов — [Headroom](/pages/headroom-routerai) |
| Главное в начало и конец | Инструкции и вопрос — в начале, повтор вопроса или формата ответа — в конце | Любой длинный промпт |
| Разбить задачу | Несколько запросов на подзадачи вместо одного огромного | Анализ больших документов, мульти-шаговые задачи |
| Суммаризация истории (compaction) | Старый диалог заменить кратким итогом и продолжить с чистого листа | Долгие сессии агента |
| Субагенты с чистым контекстом | Подзадачу решает отдельный агент и возвращает короткий результат | Поиск по кодовой базе, исследование |
| Структурированные заметки | Агент пишет план и прогресс во внешний файл и читает его, а не держит всё в промпте. См. [Agent Memory](/pages/agent-memory) | Задачи на много шагов |
| Очистка результатов инструментов | Убирать из истории старые выводы команд, которые уже не нужны | Агенты с длинной историей вызовов |
| Кэширование стабильного префикса | Не уменьшает деградацию, но удешевляет повторяющуюся часть: системный промпт, документы. Рядом стоит [семантический кэш](/pages/semantic-caching) | Один и тот же длинный префикс в многих запросах |

Compaction, structured note-taking и субагенты Anthropic перечисляет как три основных способа работать с долгими задачами, которые не помещаются в окно или в «бюджет внимания».

## Связь с RouterAI {#svyaz-s-routerai}

Через RouterAI доступны модели с окном около 1 млн токенов: `deepseek/deepseek-v4.1-flash`, `z-ai/glm-5.3`, `google/gemini-3.8-flash`, `anthropic/claude-sonnet-5.5` и другие (см. [каталог моделей](/models)). Размер окна — только половина выбора: качество на длинном входе у разных моделей отличается, и по заголовку карточки его не угадать. Проверяйте на своих данных.

Одно и то же сообщение можно отправить разным моделям через единый OpenAI-совместимый API, поменяв только `model`. Пример: прячем «иголку» в длинный текст и спрашиваем про неё, сдвигая позицию.

```python
import os
import sys
from openai import OpenAI

client = OpenAI(base_url="https://routerai.ru/api/v1", api_key=os.environ["ROUTERAI_API_KEY"])
MODELS = sys.argv[1].split(",")
RECORDS = int(sys.argv[2])
NEEDLE = "Код доступа к архиву договоров — ЗЕБРА-7391."
QUESTION = "Каков код доступа к архиву договоров? Ответь одним кодом."


def build(position):
    records = [f"Запись {i}: отдел {i % 17} передал партию №{i * 7} на склад {i % 5}, замечаний нет." for i in range(RECORDS)]
    records.insert(int(len(records) * position), NEEDLE)
    return "\n".join(records)


def ask(model, position):
    prompt = build(position) + "\n\n" + QUESTION
    resp = client.chat.completions.create(model=model, temperature=0, max_tokens=3000, messages=[{"role": "user", "content": prompt}])
    answer = (resp.choices[0].message.content or "").strip()
    ok = "ЗЕБРА-7391" in answer
    print(model, "позиция", position, "токенов", resp.usage.prompt_tokens, "OK" if ok else "MISS", repr(answer[:40]))


for model in MODELS:
    for position in (0.05, 0.5, 0.95):
        ask(model, position)
```

Запуск: `python rot_test.py deepseek/deepseek-v4.1-flash,anthropic/claude-haiku-5.5 1500`. Ключ берётся из переменной окружения `ROUTERAI_API_KEY`, в код его вписывать не нужно. `max_tokens` оставлен большим: модели с рассуждением тратят часть лимита на размышления, и при маленьком значении ответ может прийти пустым или обрезанным.

На таком запросе (около 42 тыс. токенов у DeepSeek и 51 тыс. у Haiku, у моделей разные токенизаторы) обе модели нашли код при всех трёх позициях. Это нормально: дословная «иголка» — самый лёгкий случай, и именно поэтому Chroma использует более трудные задачи. Чтобы увидеть разницу, усложните тест: добавьте похожие, но неверные коды (distractors), задайте вопрос другими словами, чем в тексте, или возьмите свой реальный документ и свой вопрос.

Стоимость сравнения считается по ценам каталога. Один запрос на 1 млн входных токенов — это 1 млн × цену «вход» за токен: для `deepseek/deepseek-v4.1-flash` около 2,6 ₽, для `anthropic/claude-haiku-5.5` около 10,7 ₽, для `anthropic/claude-sonnet-5.5` около 214 ₽, а за ответ платится отдельно. Запрос на 40–50 тыс. токенов пропорционально дешевле: у DeepSeek это порядка 0,1 ₽, у Haiku около 0,5 ₽, а весь прогон скрипта (три запроса на модель) укладывается в несколько рублей. Актуальные цены смотрите в [каталоге](/models). Работа из России без VPN и оплата в рублях доступны для всех моделей.

## Чек-лист: агент деградирует {#chek-list}

1. Сколько токенов в запросе на проблемном шаге? Посмотрите `usage.prompt_tokens` и сравните с началом сессии.
2. Что занимает контекст? Часто это результаты инструментов, а не диалог.
3. Где лежит исходное ТЗ? Если в начале под сотнями строк логов, продублируйте его в конце или держите в файле заметок.
4. Есть ли в контексте противоречащие или устаревшие инструкции?
5. Нужны ли все фрагменты RAG? Попробуйте уменьшить число чанков и сравнить ответы.
6. Можно ли выделить подзадачу в субагента с чистым контекстом?
7. Давно ли была суммаризация истории? Включите compaction или начните новую сессию с кратким итогом.
8. Стабилен ли префикс? Если да, включите кэширование: оно не лечит деградацию, но снижает цену повторов.
9. Если дать ту же задачу в сокращённом виде, ответ станет лучше? Если да, причина именно в длине.
10. Сравните две-три модели на одном и том же длинном входе (скрипт выше).

## Связанные термины {#svyazannye-terminy}

- [Context Window](/pages/context-window) — сколько токенов модель принимает
- [Контекст-инжиниринг](/pages/kontekst-inzhiniring-context-engineering) — как собирать контекст
- [Agent Memory](/pages/agent-memory) — внешняя память агента вместо «всё в промпте»
- [Semantic Caching](/pages/semantic-caching) — кэш ответов по смыслу запроса
- [Agentic RAG](/pages/agentic-rag) — когда агент сам решает, что и сколько извлекать

## Что почитать {#chto-pochitat}

- [Context Rot: How Increasing Input Tokens Impacts LLM Performance — Chroma](https://www.trychroma.com/research/context-rot)
- [chroma-core/context-rot — код экспериментов](https://github.com/chroma-core/context-rot)
- [Effective context engineering for AI agents — Anthropic](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents)
- [Lost in the Middle: How Language Models Use Long Contexts — arXiv](https://arxiv.org/abs/2307.03172)
