Context engineering: почему ваш agent глупеет на 40-м ходе
Один факт сдвинули на три строки в prompt на 2,6 % окна — retrieval упал с 84 % до 19 %. Дело было не в размере окна.
На этой странице
Вот один prompt, отправленный 288 раз одной и той же модели с greedy decoding. Его длина — 853 token. В нем есть реестр из двадцати пяти тикетов поддержки — город, очередь, приоритет, владелец, внутренний номер — и один вопрос: Marta Ferreira needs a call back about her ticket. What is the direct line extension for that ticket?
Реестр каждый раз одинаковый. Модель каждый раз одинаковая. Меняется только то, в какой из двадцати пяти строк находится ответ.
| слот ответа | попадания | доля retrieval | 95 % интервал |
|---|---|---|---|
| 1 из 25 | 27/32 | 84 % | 68–93 % |
| 4 из 25 | 6/32 | 19 % | 9–35 % |
| 7 из 25 | 6/32 | 19 % | 9–35 % |
| 10 из 25 | 9/32 | 28 % | 16–45 % |
| 13 из 25 | 8/32 | 25 % | 13–42 % |
| 16 из 25 | 6/32 | 19 % | 9–35 % |
| 19 из 25 | 6/32 | 19 % | 9–35 % |
| 22 из 25 | 3/32 | 9 % | 3–24 % |
| 25 из 25 | 7/32 | 22 % | 11–39 % |
Тридцать две попытки на строку, в каждой — другой тикет; интервалы Уилсона из Главы 4, потому что семнадцать из двадцати еще ничего ни от чего не отличают.
На первый слот модель отвечает правильно в 84 % случаев. Все остальные позиции лежат между 9 % и 28 %, и все восемь интервалов пересекаются, так что честное прочтение такое: сначала первый, потом все остальное. Liu et al. нашли U-образную форму — высоко на обоих концах, низко в середине, — но плечо недавности здесь явно не видно: 22 % в последнем слоте попадают в разброс средних. А вот что никуда не попадает — падение от слота 1 к слоту 4. Три строки.
context window этой модели — 32 768 token. prompt использует 853 из них, 2,6 %. Ничего не переполнилось, ничего не было обрезано, лимит не достигнут, предупреждение не появилось. Модель перестала находить строку, которую ей дали, потому что строка сдвинулась на три позиции вниз в списке из двадцати пяти.
Глава 16 считала стоимость context window и закончилась предупреждением: иметь миллион token — не значит использовать их. И отправила сюда. Это — сюда.
Показать детали
Что этой главе нужно из предыдущих.
- Глава 9 вывела self-attention и его стоимость . Каждый token attends к каждому другому, поэтому число парных отношений растет квадратично с длиной. Ниже этот факт используется, а не выводится заново.
- Глава 16 посчитала пять оплачиваемых корзин token и показала, что счет за разговор растет квадратично. Эта глава — о том, что с этим делать, не ломая agent.
- Глава 18 построила каталог инструментов и измерила, что двадцать инструментов не ухудшили выбор, но умножили prompt на шесть. Вот счет за них.
- Глава 19 построила retrieval. Just-in-time retrieval ниже — это та глава, примененная к собственной истории agent; chunking заново не объясняется.
- Глава 23 построила harness. Все в этой главе — policy, которая выполняется внутри его цикла, поэтому это TypeScript: артефакт — долгоживущий сервис с состоянием, а не notebook с тензорами.
Две задачи с похожими названиями
Ссылка на раздел: Две задачи с похожими названиямиAnthropic провела границу в сентябре 2025 года, и эти два предложения должны стоять рядом. Prompt engineering — это «методы написания и организации инструкций для LLM ради оптимальных результатов». Context engineering — это «набор стратегий для отбора и поддержания оптимального набора token (информации) во время inference LLM, включая всю прочую информацию, которая может попасть туда вне prompts».1
Ключевое различие — когда и кем. prompt пишется один раз человеком и проходит ревью. context собирается при каждом вызове кодом, на который никто не смотрит, из материала, который никто не писал вручную: сорок ходов истории, шесть результатов инструментов, четыре найденных фрагмента, профиль пользователя, двенадцать JSON-схем. Глава 15 измеряла, что дают лучшие инструкции. Эта глава — о других девяноста процентах token, которые приезжают сами.
Тот же документ называет ресурс, который все они тратят: у моделей «есть attention budget, из которого они расходуют ресурс при разборе больших объемов context. Каждый новый введенный token в некоторой степени истощает этот бюджет». И называет симптом: «по мере роста числа token в context window способность модели точно вспоминать информацию из этого context снижается» — context rot.1
Последнее предложение — утверждение о поведении, значит, его можно проверить, и таблица вверху страницы — эта проверка.
Как была сделана эта таблица
Ссылка на раздел: Как была сделана эта таблицаСорок строк против локального endpoint из Главы 22 — небольшой Python-сервер держит Qwen2.5-0.5B-Instruct на CPU и говорит в форме chat-completions, так что цикл остается в TypeScript, а тензоры — по другую сторону порта.
const DEPTHS = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1];
for (const d of DEPTHS) {
const slot = Math.round(d * (N - 1));
let hits = 0, other = 0;
for (let t = 0; t < TRIALS; t++) {
const recs = buildRecords(N, 1000 + t); // 25 unique tickets
const gold = recs[Math.floor(rng(7 + t)() * N)]; // a different one each trial
const rest = recs.filter((x) => x.ticket !== gold.ticket).slice(0, N - 1);
const lines = [...rest.slice(0, slot).map((x) => x.line),
gold.line,
...rest.slice(slot).map((x) => x.line)];
const r = await complete(prompt(lines, ask(gold.owner)), { maxTokens: 12 });
const said = /\d{4}/.exec(r.text)?.[0];
if (said === String(gold.ext)) hits++;
else if (said && recs.some((x) => String(x.ext) === said)) other++;
}
}Счетчик other превращает разочаровывающий результат в полезный: когда модель ошибается, она потерялась или уверена?
Ответ — уверена. По восьми позициям не в начале 136 из 205 неправильных ответов были внутренним номером другого тикета — реальным четырехзначным числом, правильно отформатированным и считанным с неверной строки. В слоте 1 таким был только один из пяти промахов; в слоте 7 — двадцать один из двадцати шести.
Именно это различие важно в production. Модель, которая говорит я не могу найти, — это баг, который вы заметите; модель, которая возвращает номер соседней строки, — это баг, который вы отгрузите, потому что на экране они выглядят одинаково. Это отказ, против которого Глава 19 строила проверяемые цитирования, только пришедший изнутри prompt, а не из индекса.
Дело не только в том, где. Дело еще и в том, сколько.
Ссылка на раздел: Дело не только в том, где. Дело еще и в том, сколько.Позиция — одна ось. Длина — другая, и ее проверить проще: держите ответ в середине и увеличивайте список.
| записей | token в prompt | попадания | доля | 95 % интервал | неверная строка | ни то ни другое |
|---|---|---|---|---|---|---|
| 1 | 97 | 18/20 | 90 % | 70–97 % | 0 | 2 |
| 3 | 159 | 11/20 | 55 % | 34–74 % | 9 | 0 |
| 8 | 315 | 3/20 | 15 % | 5–36 % | 17 | 0 |
| 20 | 695 | 2/20 | 10 % | 3–30 % | 16 | 2 |
| 40 | 1 324 | 3/20 | 15 % | 5–36 % | 15 | 2 |
| 80 | 2 587 | 1/20 | 5 % | 1–24 % | 18 | 1 |
| 140 | 4 477 | 2/20 | 10 % | 3–30 % | 18 | 0 |
Одна запись и 97 token: 90 %. Три записи и 159 token: 55 %. Восемь записей и 315 token: 15 %, а дальше — низкое плато до 140 записей и 4 477 token. Весь обвал происходит между первой и восьмой строкой списка.
Последний столбец — все, что не является ни правильным внутренним номером, ни номером другой записи; когда на странице одна запись, только туда и может попасть неправильный ответ. Два промаха при одной записи стоит показать, а не округлить прочь, потому что ни один не был отказом: один ответил 5806 для реестра, где единственная строка говорит 5805. На 97 token с единственным кандидатом эта модель все равно дважды из двадцати копирует цифру неправильно, и это нижний уровень, относительно которого измеряется все остальное.
Следуют две вещи. Больший context window покупает право отправить больше, а не гарантию, что это будет прочитано: у этой модели окно 32 768 token, а рабочий диапазон на этой задаче — несколько сотен token. И нет порога, нет обрыва, нет состояния «context заполнен» — деградация уже идет на третьей записи и завершается к восьмой, на одном проценте окна. Чем бы ни был лимит context, управляет этим не он.
Почему
Ссылка на раздел: ПочемуОбычно предлагают два механизма. Первый — арифметика из Главы 9, которую Anthropic формулирует в тех же терминах, что и этот курс: модели «основаны на архитектуре transformer, которая позволяет каждому token attend к каждому другому token во всем context. Это дает n² парных отношений для n token».1 Attention по более длинной последовательности — не та же операция, примененная к большему материалу; это один фиксированный бюджет вероятностной массы, распределенный между большим числом конкурентов. Второй механизм — обучение: модели видят куда больше коротких последовательностей, чем длинных, поэтому дальние позиционные паттерны — наименее натренированная часть сети. Это аргумент, а не измерение, и эта глава не может поставить в нем точку.
Что точно установлено, так это форма — и установлено с 2023 года. Liu et al. тестировали ответы на вопросы по нескольким документам и key-value retrieval на разных семействах и размерах моделей и обнаружили, что «качество часто выше, когда релевантная информация находится в начале или конце входного context, и заметно деградирует, когда моделям нужно обращаться к релевантной информации в середине длинных contexts, даже у явно long-context моделей».2 Глава 15 взяла из этой статьи правило позиции; Глава 19 — причину, почему двадцать retrieved chunks могут сработать хуже четырех. Практическая форма этого факта — единственное предложение здесь, по которому стоит действовать: это измеряется за пять минут на вашей модели с вашими данными, и никакая опубликованная кривая не заменит вашу.
Никто не знает, что находится в его окне
Ссылка на раздел: Никто не знает, что находится в его окнеСпросите команду, что заполняет context их agent, и получите оценку, потому что ни один API не возвращает ответ: response дает вам prompt_tokens, одно число для всего.
Разбивку можно восстановить четырьмя подсчетами и тремя вычитаниями — весь отрендеренный prompt, он же без определений инструментов, отдельно system-сообщение с ними и без них, и все без результатов инструментов:
async function buckets(messages: Msg[]) {
const sys = messages.slice(0, 1);
const withoutResults = messages.filter((m) => m.role !== "tool");
const [total, sysWithTools, sysNoTools, noResults] = await Promise.all([
countPrompt(messages, CATALOGUE), // everything
countPrompt(sys, CATALOGUE), // system + scaffolding + schemas
countPrompt(sys), // system + scaffolding
countPrompt(withoutResults, CATALOGUE), // everything but tool output
]);
return {
system: sysNoTools,
tools: sysWithTools - sysNoTools,
toolResults: total - noResults,
conversation: total - sysWithTools - (total - noResults),
total,
};
}countPrompt применяет собственный chat template модели перед tokenization, и это важнее, чем кажется: считается не ваш текст. Role markers, пролог для tool calling и рендеринг схем — все это token, за которые вы платите и которые никогда не печатали. Глава 7 строила tokenizer, а Глава 16 считала через js-tiktoken; здесь счетчик идет от той же модели, которая будет читать prompt, и это единственный счет, который ровно правильный.
Теперь пропустим через него реального agent: сорок ходов расследования инцидента, двенадцать инструментов, фейковая операционная среда, возвращающая реалистичные логи и ряды метрик.
| ход | system | определения инструментов | разговор | результаты инструментов | всего prompt | input, оплаченный на этом ходе |
|---|---|---|---|---|---|---|
| 1 | 85 | 1 817 | 155 | 490 | 2 547 | 4 370 |
| 2 | 85 | 1 817 | 282 | 529 | 2 713 | 5 275 |
| 5 | 85 | 1 817 | 647 | 1 870 | 4 419 | 8 093 |
| 10 | 85 | 1 817 | 946 | 2 141 | 4 989 | 4 951 |
| 20 | 85 | 1 817 | 1 500 | 2 943 | 6 345 | 6 316 |
| 30 | 85 | 1 817 | 2 187 | 4 000 | 8 089 | 8 059 |
| 40 | 85 | 1 817 | 3 053 | 5 677 | 10 632 | 21 090 |
Сравните первую строку с последней.
На ходе 1 prompt — 2 547 token, и 71 % в нем занимают определения инструментов. system prompt — 3 %. То, что набрал пользователь, — 6 %. agent еще ничего не сделал, а уже несет 1 817 token JSON-схемы.
К ходу 40 prompt — 10 632 token, и доли перевернулись: определения 17 %, разговор 29 %, результаты инструментов 53 %. Вывод инструментов обогнал определения на ходе 5; разговор не обогнал их до хода 25, так что первые шестьдесят процентов сессии каталог инструментов был больше всего, что было сказано.
Теперь итог. За 57 вызовов модели прогон выставил счет на 370 291 input token при финальном context в 10 632 — последний prompt был оплачен примерно тридцать пять раз, та самая квадратичность из Главы 16 с множителем agent сверху. Из этих 370 291 103 569, или 28 % всего оплаченного, были двенадцатью определениями инструментов, повторно отправленными byte-identical при каждом вызове.
Сколько стоит определение инструмента
Ссылка на раздел: Сколько стоит определение инструментаКаталог инструментов — крупнейшая фиксированная стоимость в agent, и она невидима, потому что вы ее не видите: вы передаете массив объектов, а provider рендерит его в prompt за вас. Измерено на тех же двенадцати инструментах:
system prompt + chat scaffolding, no tools: 85 tokens
all twelve definitions: 1,817 tokens
of which fixed tool-calling scaffolding: 126 tokens
three tools instead of twelve: 605 tokens
same twelve, one-sentence descriptions,
no parameter prose: 1,291 tokens (-29 %)На инструмент предельная стоимость идет от 80 token для get_current_time, который принимает одну строку, до 263 для search_tickets, который принимает четыре параметра с enum и предложением указаний для каждого. Это курс обмена за центральным советом Главы 18: описание — это API. Хорошее описание стоит около сотни token на каждом запросе всю оставшуюся жизнь agent. Три следствия.
Инструмент, который вы не используете, все равно выставляет счет. agent вызвал семь из двенадцати. Остальные пять стоили 697 token на каждом из 57 запросов — 39 729 всего, больше десятой части всего счета прогона, за возможности, которых он никогда не касался. Одна из пяти хранит самую острую деталь трейса: модель трижды пыталась вызвать read_log, которого не существует. Инструмент, который она хотела, был search_logs, вторым самым дорогим определением в каталоге — 237 token. Она заплатила за это определение 57 раз, ни разу его не использовала и ни разу не нашла его имя.
Обрезка прозы — самая дешевая доступная оптимизация, и это компромисс. Сокращение описаний до одного предложения и удаление документации параметров сэкономило 526 token на вызов, 29 процентов, не трогая ни строки логики, — и заставило модель хуже вызывать инструменты, что и измеряла Глава 18. Смысл в том, что обе стороны компромисса теперь выражены в одной единице.
В каком-то масштабе отправлять определения вообще перестает иметь смысл. Anthropic дала число в ноябре 2025 года: большой набор подключенных серверов означает обработку «сотен тысяч token» определений до того, как запрос будет прочитан, а замена этого исполнением кода — agent обнаруживает и загружает только нужные ему определения — «снижает использование token со 150 000 до 2 000, экономия времени и стоимости 98,7 %».3 Та же идея, что и в остальной главе, примененная к схемам вместо истории: держите индекс, разрешайте запись по требованию.
Ломаем намеренно
Ссылка на раздел: Ломаем намеренноВ тот сорокаходовый transcript были подложены две вещи. На ходе 2, до реальной работы, пользователь задает постоянное правило: любой тикет, который ты откроешь, нужно оформить под моим табельным номером, 4417. На ходе 19, в середине инцидента, факт: затронутый shard — pay-shard-7, подтверждено командой payments. На ходе 40 пользователь просит agent открыть тикет инцидента, для чего нужны оба факта. Каждый probe задается в шести разных формулировках и оценивается из шести — greedy decoding детерминирован, поэтому один вызов дает неповторяемое да или нет, а шесть дают долю.
Затем transcript воспроизводится под семью context policies. Именно воспроизводится, а не запускается заново, намеренно: сообщения, tool calls и результаты инструментов byte-identical во всех семи, так что единственная переменная — что каждая policy решила оставить. Глава 16 показала, почему sliding window — плохой экономический ход, потому что он уничтожает cacheable prefix. Вот что он делает с поведением:
| context policy | input token за 40 ходов | prompt на ходе 40 | правило хода 2 | факт хода 19 |
|---|---|---|---|---|
| полная история | 370 291 | 10 632 | 6/6 | 5/6 |
| sliding window, последние 12 сообщений | 157 578 | 2 922 | 5/6 | 0/6 |
| удалять результаты инструментов старше 4 ходов | 243 445 | 6 311 | 6/6 | 3/6 |
| сжатие каждые 6 ходов | 195 515 | 3 220 | 6/6 | 0/6 |
| сжатие плюс заметки, написанные моделью | 200 849 | 3 286 | 6/6 | 0/6 |
| закрепить собственные ходы пользователя в начале | 168 550 | 3 559 | 6/6 | 5/6 |
| закрепить собственные ходы пользователя в конце | 168 835 | 3 564 | 6/6 | 6/6 |
| контроль: только два хода и ничего больше | — | 1 981 | 6/6 | 6/6 |
Строки сжатия включают стоимость самого сжатия: 18 581 input token за семь summaries и еще 3 392 за note-taker. Контрольная строка нужна, чтобы ноль можно было читать как ноль — с двумя сообщениями в 1 981-token prompt эта модель идеально отвечает на оба probe, значит, ни одна строка не упирается в чрезмерную сложность задачи.
Полная история помнит и является самым дорогим вариантом в таблице: 370 291 input token за сессию, чье долговечное содержание — два предложения.
Это отвечает на вопрос, который начало оставило открытым. Почему transcript на 10 632 token держит факт, который теряет реестр на 853 token? Потому что длина — неправильная переменная. Реестр содержит двадцать пять четырехзначных внутренних номеров в двадцати пяти одинаковых предложениях — двадцать четыре почти идеальные приманки для того, что вам нужно. transcript содержит ровно один табельный номер и одно имя shard. Context rot — это интерференция раньше, чем объем, поэтому 136 из 205 неправильных ответов выше были соседним значением. Полезный вопрос об окне — не насколько оно длинное, а сколько в нем вещей, похожих на ответ.
Sliding window на 57 % дешевле и потерял инцидент. Табельный номер выжил только потому, что agent повторил его в недавних ходах. Shard, сказанный один раз на ходе 19, не входит в последние двенадцать сообщений — и модель этого не говорит. В шести запросах она ответила «the affected payment shard is shard 4417», потянувшись к табельному номеру, единственному другому идентификатору, оставшемуся в ее окне, и дважды — «pool», взятому из строки pool_exhausted в логе.
Сжатие дешево и потеряло тот же факт. Семь summaries, написанных моделью по явной инструкции сохранять идентификаторы, числа, постоянные инструкции и открытые вопросы, — и pay-shard-7 нет ни в одном из нужных; шесть догадок были shard 1, pay_shard_1 и pool. Сжатие не падает громко. Оно производит гладкую, правдоподобную, намного более короткую сессию, которая тихо выронила одну строку.
Три строки получили 0/6 по факту хода 19 — sliding window, сжатие и сжатие с заметками. Восемнадцать неправильных ответов между ними, и ни один не был «я не знаю».
Затем строка, за которую должно быть неловко. Сохранение собственных сорока сообщений пользователя дословно, плюс последние четыре хода полностью и больше ничего, стоит 168 550 token — на 54 % меньше полной истории — и отвечает на оба probe не хуже полной истории или лучше. Без summariser, без note-taker, без второй модели: фильтр по role === "user". Слова пользователя — самые дешевые высокоценные token в окне agent, и большинство дизайнов выбрасывает их вместе со всем остальным.
Последние две строки — снова таблица из начала, только внутри agent. Тот же закрепленный блок, перенесенный из system message в конец prompt: 5/6 становится 6/6. На шести попытках это не значимая разница, и она не подается как значимая — это напоминание, что где является параметром, который вы задаете независимо от того, знаете вы об этом или нет.
Четыре способа тратить меньше окна
Ссылка на раздел: Четыре способа тратить меньше окнаЧетыре стратегии ниже — стратегии Anthropic, в ее порядке, хотя только последние три входят в ее long-horizon list.1 Все четыре — вариации одной инструкции: не носите то, что можно fetch, и не носите сырым то, что можно носить сжатым.
Just-in-time retrieval
Ссылка на раздел: Just-in-time retrievalНе загружайте контент заранее. Держите идентификаторы — путь к файлу, запрос, номер тикета, имя инструмента и его аргументы — и разрешайте их, когда нужно. Крупнейшая корзина в agent выше — вывод инструментов, который был прочитан один раз, использован один раз, а затем носился еще тридцать ходов. Заменить каждый результат старше четырех ходов заглушкой, говорящей, что это было и как вернуть это назад, — шесть строк:
const elide: Policy = (h) => [SYSTEM, ...h.flatMap((turn, ti) =>
turn.map((m) => (ti < h.length - 4 && m.role === "tool"
? { role: "tool", name: m.name,
content: `[${m.name} result from turn ${ti + 1}, ${m.content.length} chars, ` +
`elided; call ${m.name} again with the same arguments to re-read it]` }
: m)))];Это Глава 19, где корпус заменен собственным прошлым agent. Механизм retrieval уже есть — это каталог инструментов.
Сжатие
Ссылка на раздел: СжатиеКогда transcript проходит порог, замените его самую старую часть summary, написанным моделью, и продолжайте. prompt, который пишет summary, — это весь дизайн, и именно в нем сжатие выигрывается или проигрывается: сохранять идентификаторы, числа, постоянные инструкции и открытые вопросы; удалять любезности и вывод инструментов, который можно re-fetch.
Сжатие по конструкции с потерями; что именно оно теряет, за вас выбирает модель, и ничто не выдает ошибку, когда выбор неверен. Оно также не бесплатно: каждое сжатие — дополнительный вызов, чей input — то, что сжимается.
Структурированное ведение заметок
Ссылка на раздел: Структурированное ведение заметокДержите небольшой store вне context и целиком re-inject его на каждом ходе. В отличие от summary, он append-only и адресуемый: правило, записанное на ходе 2, дословно остается там на ходе 400. Измеренная здесь версия после каждого сообщения пользователя спрашивает модель, содержит ли оно что-то долговечное:
const r = await complete([
{ role: "system", content:
"You keep a durable note file for a support session. Given one user message, " +
"output one short note ONLY if it states a standing rule, an identifier or a fact " +
"that must survive the rest of the session. Otherwise output exactly NONE." },
{ role: "user", content: `Turn ${i + 1}: ${user}` },
], { maxTokens: 40 });
if (!/^none\b/i.test(r.text.trim())) notes.push(`turn ${i + 1}: ${r.text.trim()}`);У этой стратегии здесь самый высокий потолок, и именно она провалилась в измерении. За сорок сообщений пользователя note-taker сохранил три заметки и ни одной из двух важных: строку совета из runbook, объявление о завершении сессии и Europe/Madrid сейчас 13:45 — время, которое он выдумал, потому что инструмент, который он пересказывал, вернул 09:52 UTC. Note-taker — это модель, и все в этой главе относится к нему тоже.
Sub-agents
Ссылка на раздел: Sub-agentsДайте сфокусированной задаче собственное окно — собственный system prompt, собственный маленький каталог, никакой истории parent — и верните короткий ответ, а не transcript. Глава 23 поставила один за схемой инструмента и оставила счет здесь; счет таков: ответ child — единственная часть окна child, за которую parent когда-либо платит.
Sub-agent нет в таблице выше, потому что он не работает сорок ходов: он запускается один раз, в окне, которое кто-то для него сузил. Получив system prompt, ходы 17–19 и ничего больше — 2 737 token — он ответил на shard probe 6/6, лучше любой policy в таблице, и на employee probe 0/6, потому что этого числа нет в трех ходах, которые ему дали.
Вот sub-agents в двух числах: чистое окно — не интеллект, а область действия, и эту область заранее задает код, который уже должен знать, какие ходы важны. В этих ответах стоит сохранить еще одну вещь. Это была единственная policy, которая ответила «None available» вместо того, чтобы что-то выдумать. Модель с маленьким, связным context знает, чего ей не хватает; модель с большим, шумным — нет.
Три памяти
Ссылка на раздел: Три памятиПочти каждый запутанный разговор о памяти agent — это три механизма под одним словом. У них разные сроки жизни, владельцы и режимы отказа, и система, которая держит их в одном месте, имеет проблему, которую еще не заметила.
| история разговора | retrieval | постоянная память пользователя | |
|---|---|---|---|
| хранит | что было сказано в этой сессии | документы, которыми вы владеете | факты о человеке |
| живет | одну сессию | пока не переиндексировано | во всех сессиях, навсегда |
| записывается кем | циклом, автоматически | ingestion pipeline | моделью, намеренно |
| попадает в prompt | полностью, при каждом вызове | четыре фрагмента, когда query совпадает | полностью, при каждом вызове |
| ломается через | рост до rot | retrieval неправильного chunk | запоминание неверного факта о вас |
| построено в | Глава 23 | Глава 19 | эта глава |
Академическая рамка здесь — CoALA, которая организует language agents вокруг «модульных компонентов памяти» и отделяет working memory от episodic, semantic и procedural stores.4 MemGPT берет ту же идею буквально, заимствуя virtual memory из операционных систем: быстрый уровень внутри окна, медленный уровень вне его, а сама модель перемещает данные между ними через function calls.5 Обе работы заставляют задать вопрос, на который продукту все равно придется отвечать: не сколько я могу сохранить, а к какому store это относится и когда истекает.
Практический тест — один вопрос на факт: что должно оставаться правдой завтра? Результат инструмента с хода 12 — ничего. Summary сессии — до конца сессии. То, что табельный номер пользователя 4417, — пока он не сменит работу. Три ответа, три stores.
Куда дальше
Ссылка на раздел: Куда дальшеТеперь вы можете измерить, что находится в окне, решить, что остается в нем, и отличить agent, который что-то забыл, от agent, который это нес, но не посмотрел.
Последняя из четырех стратегий здесь не помещается. Sub-agent — не context policy, а второй agent, и как только их двое, нужно решить, что проходит между ними и кто главный. Глава 25 именно об этом: пять паттернов orchestration и откуда на самом деле взялись их названия; две топологии, которые путают, — попросить sub-agent и получить ответ обратно против передать ему разговор и не получить его обратно; и измеренный результат, что на задаче, которую она оценивает по стоимости, более простое устройство выигрывает, — а затем тест, когда оно перестает выигрывать.
Она также наследует ровно то, что эта глава только что измерила. Sub-agent возвращает summary. Summary — это сжатие, которое вы не писали, произведенное моделью, чье окно вы не видите, и parent не может отличить хорошее от уверенно неверного — то же различие, которое разделяло 84 % и 19 % вверху страницы и превратило восемнадцать отсутствующих фактов в восемнадцать выдуманных. Итак: когда sub-agent ошибается, на что именно parent может посмотреть?
Источники и методика
Ссылка на раздел: Источники и методикаКаждое число здесь произведено на этой машине, и ни одно не оценивалось приблизительно. Модель — Qwen2.5-0.5B-Instruct в float32 на CPU с greedy decoding, обслуживается через loopback небольшим Python endpoint, который говорит в форме chat-completions и exposes token-count route — снова шов из Главы 14, тензоры на стороне Python, цикл на стороне TypeScript, — так что каждый подсчет — собственный tokenizer этой модели, примененный к ее собственному chat template. Таблица позиций — 288 вызовов, девять позиций по тридцать две попытки с другим тикетом в каждой; таблица длины — 140 вызовов; прогон agent — 57 вызовов модели за 43 минуты wall clock; таблица policies — тот же transcript, воспроизведенный под семью policies. Интервалы — Уилсона, из Главы 4. Ни один платный API не вызывался, поэтому в главе нет ни одной цены: подсчеты token точны, а ставки, на которые вы бы их умножили, — в Главе 16.
Сноски
Ссылка на раздел: Сноски-
Anthropic, Effective context engineering for AI agents, 29 сентября 2025 года,
anthropic.com/engineering/effective-context-engineering-for-ai-agents, прочитано 7 сентября 2026 года. Источник двух определений, процитированных в начале, «attention budget» и утверждения, что каждый новый token его истощает, описания context rot, формулировки n² парных отношений и стратегий, использованных как каркас этой главы. Три из них — ее long-horizon list: сжатие, структурированное ведение заметок и multi-agent architectures; just-in-time retrieval появляется раньше в той же статье, в разделе context retrieval и agentic search, и здесь сгруппирован с ними. ↩ ↩2 ↩3 ↩4 -
Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. and Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 июль 2023, v3 ноябрь 2023). Цитируется в главах 15, 16 и 19 и измеряется здесь. Цитата взята из abstract; две задачи статьи — ответы на вопросы по нескольким документам и key-value retrieval, а вывод, что эффект сохраняется у явно long-context моделей, — важная часть для продуктового решения. ↩
-
Anthropic, Code execution with MCP: building more efficient agents, 4 ноября 2025 года,
anthropic.com/engineering/code-execution-with-mcp, прочитано 7 сентября 2026 года. Источник сокращения со 150 000 до 2 000 token и числа 98,7 %, а также наблюдения, что определения инструментов, загруженные заранее, занимают context до того, как запрос будет прочитан. ↩ -
Sumers, T. R., Yao, S., Narasimhan, K. and Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Организует language agents вокруг «modular memory components, a structured action space to interact with internal memory and external environments, and a generalized decision-making process to choose actions» и делит memory на working, episodic, semantic и procedural. Глава 22 использовала ее taxonomy для learning agent; таблица трех stores выше — ее практическая тень. ↩
-
Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. and Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (октябрь 2023). Предлагает «virtual context management, a technique drawing inspiration from hierarchical memory systems in traditional operating systems», где сама модель перемещает данные между быстрым уровнем внутри окна и медленным уровнем вне него. Самое ясное из известных формулирований того, почему окно — cache, а не memory. ↩