Модуль 1. Из чего состоит окно
Контекстное окно — это не «место для текста пользователя». Это бюджет, который делят между собой системный блок, схемы инструментов, результаты их вызовов, инъекции хуков и файлы. Задача модуля — научиться раскладывать окно на слагаемые и видеть, что съедает место на самом деле.
1.1 Что лежит в окне реальной агентской сессии
Anthropic прямо перечисляет состав контекстного окна агента: system instructions, tools, Model Context Protocol (MCP), external data, message history. Обрати внимание, чего в списке нет отдельной строкой — «сообщения пользователя» растворены внутри message history и в развитой агентской сессии обычно наименьшая по объёму часть.
- Системный блок — системный промпт, поведенческие инструкции, память/конфиги.
- Определения инструментов — схемы (имя, описание, параметры) всех подключённых инструментов и MCP-серверов, отдаются как обычный JSON-текст при каждом запросе.
- Результаты вызовов инструментов (tool results) — вывод команд, содержимое прочитанных файлов, ответы MCP. Самая быстрорастущая часть окна за один рабочий цикл.
- Инъекции хуков и напоминаний (system-reminder, memory-инъекции) — есть в реальных сессиях, но отдельного замера их доли в открытых источниках нет (см. врезку ниже).
- Содержимое файлов и история диалога — то, что накапливается по ходу сессии; при компакции срезается до сводки на 1–2 тыс. токенов.
- Реплики человека — как правило, наименьшая часть из всех перечисленных.
1.2 Замер по реальным сессиям: сколько это в процентах
Anthropic не публикует разбивку «типичной» сессии по корзинам — таких данных от вендора нет ни у одной из крупных лабораторий. Ниже — два независимых инженерных замера на конкретных сессиях. Их нельзя читать как «типичное значение для всех агентов», это иллюстрации порядка величины на конкретных конфигурациях.
- результаты вызовов инструментов — 49,7% (22 сообщения, 6 204 токена)
- ответы модели — 16,9%
- системный блок — 12,3%
Вывод автора замера дословно: «tool results eating half the window is the single most common thing».
- корзина System/Tools (инструкции + схемы MCP-инструментов + системный промпт + память) — 62,5 тыс. токенов = 31% окна ещё до первого рабочего хода
- отдельная оценка: 15+ подключённых инструментов ≈ 5 000–10 000 токенов только на их JSON-схемы, до единого вызова
1.3 Как считаются токены
Официальное правило OpenAI для английского текста: 1 токен ≈ 4 символа ≈ 0,75 слова (то есть ≈1,33 токена на слово). Это грубое приближение, а не свойство конкретного токенизатора Claude — Anthropic свой токенизатор публично не раскрывает, точный подсчёт доступен только через API.
1 токен ≈ 4 символа ≈ 0,75 слова (английский)
Русский текст может требовать больше токенов на то же смысловое содержание, чем английский; отношение зависит от токенизатора и текста. Надёжно — сам эффект неравенства токенизации между языками подтверждён академической работой (arXiv 2305.15425); менее надёжно — конкретная цифра «5,16 токена/слово у GPT-2 → 1,96 у GPT-4o» взята из вторичного блога и не проверена по первоисточнику (в заметках это отмечено явным пробелом).
Изображения у Claude считаются по визуальным токенам — блокам 28×28 пикселей:
токены = ⌈ширина / 28⌉ × ⌈высота / 28⌉
Схемы инструментов не имеют отдельного «тарифа» — это обычный JSON-текст, и длинные описания параметров стоят ровно столько символов, сколько занимают. Отсюда и наблюдаемые 5–10 тыс. токенов на 15+ инструментов из раздела 1.2.
1.4 Посчитай свой бюджет окна
Постоянная часть (системный блок + схемы инструментов) занимает окно ещё до первого хода. Каждый ход добавляет результат вызова. Формулы — ниже, поменяй входы и посмотри, сколько реально остаётся под работу.
constant = system·1000 + tools·schema
results = turns · result
remaining = window·1000 − constant − results
share = results / (constant + results) · 100%
При значениях по умолчанию (окно 200K, системный блок 12K, 15 инструментов по 400 токенов схема, 30 ходов по 3000 токенов результат) результаты вызовов — это уже больше 80% занятой части окна, и это ещё до того, как модель написала хоть слово ответа.
1.5 Когда окно заполнится
Тот же расчёт, но во времени: постоянная часть фиксирована с первого хода, а результаты вызовов растут линейно. График использует значения калькулятора выше: при постоянной части 18 тыс. токенов и результате 3 тыс. токенов за ход видно, где линия занятого окна пересекает предел в 200K.
При значениях по умолчанию предел достигается примерно на 61-м ходу; после 30 ходов остаётся ещё около 31. Это ровно тот расчёт, который стоит делать до запуска агента на длинную задачу, а не после того, как он упёрся в лимит и начал терять требования.
1.6 Практический вывод
Бюджет окна — это арифметика, которую можно и нужно прикинуть заранее: постоянная часть (система + схемы инструментов) известна до старта, средний размер результата вызова легко оценить по паре пробных ходов. Считать после того, как агент уже «забыл» требование из начала сессии, — поздно. Два самых дешёвых рычага по данным этого модуля — сократить схемы инструментов (разовая экономия) и обрезать/выносить результаты вызовов (постоянная экономия), а не сокращать текст самого запроса.
1.7 Практика: померить это у себя
Всё, что выше, — чужие замеры. Свой инструмент меряется за полчаса, и числа выходят
другие. Пример: Antigravity, замер 21.09.2026 — три прогона на вариант, промпт в одно
слово, читается metadata.modelUsage.inputTokens первого шага планировщика.
Пустая рабочая папка — 14 487 токенов занято до начала работы. Файл правил на 2 060 символов добавляет +771, причём имя файла не важно. Десять файлов кода на 90 КБ в папке — +6, то есть содержимое папки в стартовый контекст не попадает вовсе.
Первый прогон дал базовый разброс 8 143 токена между двумя одинаковыми пустыми папками — на таком фоне «правила стоят 771» было бы шумом. Причина: сравнивались разные типы шагов. После фиксации типа разброс стал 7. Сначала разброс, потом эффект.
1.8 Сколько весят сами инструменты
Тот же метод, свой рабочий инструмент: Claude Code 2.1.258, пустая папка, промпт в одно
слово, стартовое заполнение = сумма трёх полей usage первого ответа
(claude -p "ok" --output-format json). Две одинаковые руки дали 52 818 обе,
разброс 0 — только после этого меряли эффекты.
| Блок | Токенов | Как измерен |
|---|---|---|
| Системный блок с памятью | 6 178 | --tools "" и без MCP |
| Определения инструментов | 44 435 | разность с полным набором |
| MCP-серверы | 2 211 | --strict-mcp-config с пустым списком |
| Итого старт | 52 818 | прямой прогон |
Внутри блока инструментов вес распределён крайне неровно. Прогон «запретить все, кроме одного», минус пол:
| Инструмент | Токенов |
|---|---|
| Artifact | 16 689 |
| Skill | 11 302 |
| Workflow | 8 404 |
| Bash | 1 511 |
| Read | 900 |
| Edit | 641 |
Три инструмента дают 36 400 из 44 435 — 82% блока. Причина в устройстве:
Artifact — это 24 действия под одним именем плюс правила вёрстки и схема
примерно на 45 полей, то есть встроенная инструкция, а не сигнатура функции;
Skill тянет за собой листинг всех доступных скиллов.
--allowed-tools Read
окно не уменьшает вовсе — 50 608 против 50 607: это ограничение
прав, схемы всё равно уходят в промпт. Уменьшает --disallowed-tools (десять
запрещённых сняли 6 836) и --tools "" (падение до пола 6 178).Самый крупный эффект дала отложенная загрузка схем: с запретом инструмента поиска по инструментам окно выросло до 77 014, то есть механизм экономит 24 196 токенов — 31% стартового окна. Он же объясняет, почему MCP выглядит дешёвым: при активной отложенной загрузке весь блок стоит 2 211 токенов, без неё — 11 366.
Модуль 2 из 7 · Внимание и деградация
Внимание и деградация
В M1 мы разобрали, из чего вообще состоит контекстное окно: system prompt, схемы инструментов, tool results, память — и что всё это конкурирует за один и тот же бюджет. Теперь — вторая половина проблемы. Даже если нужный факт физически лежит внутри окна и никуда не вытеснен, модель может его не заметить. Задача этого модуля — научиться отличать заявленную длину окна («200K», «1M») от рабочей («сколько токенов реально можно занять и получить надёжный ответ») и знать, каким инструментом это вообще измеряют.
Оригинал: «Lost in the Middle», 2023
Liu et al. (TACL 2023) прогнали GPT-3.5-Turbo через multi-document QA с 20 документами, в которых ровно один документ содержал ответ, и двигали его позицию. Результат — знаменитая U-образная кривая:
75,8% (начало) → 53,8% (середина) → 63,2% (конец)
Но главный факт этой работы — не форма кривой, а сравнение с контрольной точкой. Без документов вообще (closed-book) модель отвечала на 56,1%. То есть результат в середине (53,8%) оказался хуже, чем если бы документов не было вовсе. Дать модели лишний, но плохо расположенный контекст — не нейтрально, это активный вред: он может вытеснить правильный ответ, который модель дала бы «из головы». Для сравнения: если дать только нужный документ (oracle) — 88,3%.
Что стало в 2026: U-форма исчезла, позиция — нет
Свежая работа (arXiv 2605.23170, май 2026) прогнала 9 моделей на 64K токенов со структурированным наполнителем — и не нашла симметричной U-формы. Вместо неё — устойчивое превосходство конца и деградация середины, причём размер эффекта разный у каждой модели до крайности:
DeepSeek-V3.2: 98% → 98% (0 п.п.) · Qwen 2.5-7B: 94% → 0% (-94 п.п.)
Разброс от 0 до −94 п.п. на одной и той же методике — это смена картины по сравнению с 2023 годом. Тогда провал середины выглядел как более-менее общее свойство трансформеров. Сейчас понятно: провал середины — это измеримая, но модель-специфичная характеристика, а не универсальный закон. Практический вывод для архитектора одинаков в обеих версиях истории: нельзя полагаться на то, что важное в середине будет замечено, — но проверять это нужно на своей модели, а не наследовать вывод из статьи 2023 года.
Заявленная длина против эффективной: разрыв растёт быстрее окна
NoLiMa (Adobe Research, 2025) убрала из задачи лексическое совпадение между иголкой и вопросом — модель обязана вывести связь по смыслу, а не сматчить строку. Порог «эффективной длины» — длина, на которой результат ещё держится на уровне ≥85% от базового (короткоконтекстного) результата модели. Разрыв между тем, что заявляет вендор, и тем, что показывает замер — на порядки:
Context rot: деградация при неизменной сложности задачи
Отчёт Chroma (июль 2025, 18 моделей — Claude Opus 4/Sonnet 4, GPT-4.1, o3, Gemini 2.5 Pro, Qwen3 и другие) показал: модели не используют контекст равномерно. Задача, решаемая идеально на 100 токенах входа, может не решаться на 1000 токенах — при поддержке окна 1M+.
Лучший контрфактуал из всех измерений — пара focused/full на бенчмарке LongMemEval. Сложность задачи и сам нужный факт зафиксированы, меняется только объём окружения вокруг него:
focused ≈ 300 токенов vs full ≈ 113 000 токенов
Контринтуитивная деталь того же отчёта: модели показывают результат лучше на перемешанном «стоге сена», чем на логически связном тексте — и это воспроизводится на всех 18 моделях. Связный длинный документ (весь репозиторий, длинная спека) — худший формат фона, не лучший. Косвенно это оправдывает выжимки и структурированные заметки вместо «закинуть в контекст всё целиком».
Проверь себя
Цена длины: считать заранее, а не после
M3 из 7 · Prefill, decode и KV-кеш
В M2 мы увидели, что модель по-разному видит токены контекста — внимание деградирует неравномерно. Здесь — другая сторона той же длины: не что модель видит, а во что она обходится. Обходится она в двух разных валютах — вычислениях и памяти — и они растут по разным законам. Не различая их, легко заказать TTFT на глаз и ошибиться в разы.
Две фазы одного ответа: prefill и decode
Каждый ответ модели состоит из двух непохожих друг на друга этапов.
Prefill
Модель за один параллельный проход «прочитывает» весь промпт целиком и строит из него KV-кеш (см. ниже). Загруженные веса при этом переиспользуются сразу на всех токенах промпта — это похоже на то, как один и тот же станок за один проход штампует сразу целую партию деталей. Упирается в вычисления (compute-bound): GPU почти всё время считает, а не ждёт данные.
Decode
Дальше модель рождает ответ по одному токену за проход: на каждый новый токен нужно заново прочитать из памяти все веса и весь накопленный KV-кеш, а посчитать — совсем немного (по сути одна строка матрицы на вектор). Это как станок, который каждый раз перезаряжается ради одной детали. Упирается в пропускную способность памяти (memory-bandwidth-bound), а не в мощность счёта.
KV-кеш: что копится в памяти
Пока модель проходит через промпт, она сохраняет по каждому слою и каждой KV-голове внимания векторы K (key) и V (value) для каждого уже обработанного токена — чтобы на decode не пересчитывать их заново, а просто прочитать. Это и есть KV-кеш, и он линейно растёт с длиной контекста и с числом одновременных пользователей (батчем) сразу.
KV_bytes = 2 · layers · kv_heads · head_dim · seq_len · batch · bytes
МАТЕМАТИКА — следует прямо из устройства трансформера, не зависит от конкретного стека.Посчитанный пример: Llama 3.1 70B (80 слоёв, 8 KV-голов благодаря группированному вниманию — GQA, head_dim 128), BF16 (2 байта на число), один пользователь, 128K контекста. Здесь и в калькуляторах K = 1000 токенов, M = 1 000 000 токенов, ГБ = 10⁹ байт:
| Конфигурация | 32K | 128K | 1M |
|---|---|---|---|
| Llama 3.1 70B, GQA (8 KV-голов) | 10.5 ГБ | 41.9 ГБ | 328 ГБ |
| то же, без GQA (64 KV-головы) | 84 ГБ | 336 ГБ | 2.6 ТБ |
МОЯ АРИФМЕТИКА по приведённой формуле и указанным единицам.
Отсюда — ключевой вывод: KV-кеш — это произведение длины на батч. Удвоив контекст, вы вдвое режете число одновременных пользователей на той же железке. Значит длинный контекст дорог не потому, что «токенов много», а потому, что он забирает место у других запросов — бьёт по пропускной способности всей системы, а не только своей собственной.
Прогноз до запуска
Прежде чем отправлять запрос, полезно прикинуть на пальцах: сколько ждать первого токена и сколько это займёт памяти. Ниже — калькулятор на двух формулах выше.
TTFT(s) ≈ TTFT_ref · (s / s_ref)^1.47
Рост времени: между линией и квадратом
У Meta есть две измеренные точки для Llama3 405B на H100 (context parallelism, arXiv:2411.01783): prefill 128K токенов — 3.8 с, prefill 1M токенов — 77 с.
степень ≈ log(77 / 3.8) / log(1000 / 128) ≈ log(20.3) / log(7.8) ≈ 1.47
МОЯ АРИФМЕТИКА по двум точкам одного замера одной команды на одном железе — а не опубликованный закон масштабирования. Настоящая форма кривой — сумма линейного члена (проходы через веса) и квадратичного (само внимание, QKᵀ и AV): a·s + b·s². На коротких промптах доминирует линейный член, на очень длинных (≥512K по данным Meta) — квадратичный. Показатель 1.47 — удобный рабочий ориентир для диапазона 100K–1M, не физика.
Что на самом деле даёт FlashAttention
Частое заблуждение: «поставили быстрое ядро внимания — квадратичность исчезла». Это не так.
МАТЕМАТИКА
Число операций (FLOPs) внимания остаётся квадратичным по длине — O(s²). FlashAttention этого не меняет и не может: доказано, что ни один точный алгоритм внимания не способен асимптотически снизить число обращений к памяти при всех размерах SRAM.
РЕАЛИЗАЦИЯ
Обращения между HBM и быстрой on-chip SRAM: с tiling они падают с O(s²) до O(s). Именно это позволяет длинному контексту вообще поместиться в железо и посчитаться за разумное время — ускорение wall-clock есть, но оно побочный эффект того, что внимание было упёрто в память, а не в счёт.
Ловушка планирования: цена и время расходятся
У Anthropic для моделей поколения Claude 4.6+ нет наценки за длину контекста: запрос на 900K токенов тарифицируется по той же ставке за токен, что и запрос на 9K. Счёт растёт строго линейно с числом токенов. А время до первого токена, как мы только что посчитали, растёт как ~s^1.47 — заметно быстрее линии.
Значит длинную сессию нельзя спланировать одной моделью «на глаз по прайс-листу» — нужны две разные:
Проверь понимание
Кеш промпта
Модуль 4 из 7 — где именно ломается кеш и как посчитать, окупается ли он на твоей нагрузке
В M3 мы посчитали цену длины: каждый лишний токен в промпте стоит времени и денег на каждом вызове. Кеш промпта — единственный рычаг против этой цены, который не требует укорачивать контекст. Но у Anthropic это ставка, а не подарок: запись в кеш платная, и ломается кеш в конкретных, предсказуемых точках. Если не знать этих точек — легко платить премию за кеш, который ни разу не сработает.
Механизм: почему правка в начале обнуляет всё после неё
Кешируется не текст промпта, а вычисленные KV-тензоры внимания, разбитые на блоки. Хэш каждого блока строится из хэша предыдущего блока — это цепочка. Сдвинь один токен в раннем блоке — его хэш изменится, и все блоки-наследники окажутся недостижимы, даже если их собственное содержимое не менялось. Переиспользуется только точный побайтовый префикс: как только два запроса разошлись хотя бы в одном токене, дальше этой точки кэширования для них уже нет. Суффиксного кэша не существует ни у одного провайдера — по этой же причине: состояние токена зависит от всех предыдущих, кешировать «конец» физически нечего.
Отсюда жёсткое правило порядка. У Anthropic оно закреплено в самом API:
tools → system → messages
Anthropic: параметры кеша (проверено 2026-09-21)
Документировано в platform.claude.com/docs/en/build-with-claude/prompt-caching
и в разделе Pricing:
- До 4 точек разметки (breakpoints) на запрос — на практике это 4 слоя стабильности: tools → system → крупный статичный контекст → «замороженный» хвост истории. Больше слоёв спроектировать нельзя, придётся сливать соседние.
- Минимальная длина кэшируемого префикса не монотонна по моделям: 512 токенов у Opus 5 и Fable/Mythos 5/5.1, 1024 у Sonnet 5, 2048 у Haiku 3.5, но 4096 у Opus 4.5/4.6 и у Haiku 4.5. «Старшая» модель не значит меньший порог — смотреть таблицу под конкретную модель, а не полагаться на интуицию.
- Множители к базовой цене input: запись на 5 минут — 1.25×, запись на 1 час — 2×, чтение (попадание) — 0.1× (у Fable 5.1 / Mythos 5.1 чтение ещё дешевле, 0.025×).
- Время жизни продлевается бесплатно при каждом попадании: «the cache is refreshed for no additional cost each time the cached content is used». Отсчёт TTL идёт от начала запроса, который пишет или читает запись, а не от конца ответа.
- Просмотр назад ограничен 20 блоками: «the system checks at most 20
positions per breakpoint, counting the breakpoint itself as the first». Если за один ход
агента (например, пачка результатов инструментов) в промпт добавилось больше 20 content-блоков
до точки разметки — система её не находит. Ошибки при этом нет: это тихий промах,
видимый только по нулевому
cache_read_input_tokensв usage.
cache_control сверху запроса) — разумный
дефолт для чат-агента, система сама двигает точки разметки. Explicit breakpoints нужны, когда
есть большой документ или набор tools, который обязан оставаться в кеше независимо от роста
истории.Матрица инвалидации: что именно ломает кеш
Anthropic публикует явную таблицу — что уцелело (✓), а что инвалидировано (✘) при каждом типе изменения:
| Что изменилось | Tools | System | Messages |
|---|---|---|---|
| Определения инструментов | ✘ | ✘ | ✘ |
| Web search / citations / speed — переключатель | ✓ | ✘ | ✘ |
| tool_choice | ✓ | ✓ | ✘ |
| Картинки в сообщении | ✓ | ✓ | ✘ |
| Метка времени в начале system-блока | ✓ | ✘ | ✘ |
Смена набора инструментов обнуляет вообще всё — это самая дорогая операция,
которая существует в кешируемой петле. Отсюда правило: набор tools фиксируется на всю сессию;
если инструменты нужно выбирать динамически — это делается фильтрацией на стороне оркестратора
между сессиями, а не изменением tools внутри одной. Перестановка блоков местами
действует так же, как правка: расхождение начинается с той позиции, где префиксы перестали
совпадать побайтово — дальше по цепочке всё инвалидировано, даже если сами блоки не изменились,
просто поменялись местами.
Экономика: кеш — это ставка, а не бесплатный выигрыш
Запись в кеш у Anthropic платная, поэтому у ставки есть точка окупаемости. Из документированных множителей выводится порог доли попаданий, ниже которого кеш обходится дороже, чем его отсутствие:
h_break = (w − 1) / (w − r)
Контраст с другими провайдерами резкий. У OpenAI и DeepSeek запись не тарифицируется вовсе — риска переплаты нет, порога окупаемости считать не нужно, достаточно правильного порядка блоков. У Google в явном режиме — третья модель: платится не запись и не число чтений, а хранение по времени. Счёт капает, даже если по кешу вообще не было ни одного обращения.
| Anthropic | OpenAI / DeepSeek | Google (явный кеш) | |
|---|---|---|---|
| Плата за запись | есть: 1.25× / 2× | нет | нет отдельной |
| Плата за хранение | нет | нет | есть — $/1M ток. в час, капает при нулевом трафике |
Что реально даёт кеш под агентской нагрузкой
Независимое измерение (рецензируемая работа «Don't Break the Cache», arXiv:2601.06007, январь 2026, 500+ агентских сессий на DeepResearch Bench, ~10 000 API-вызовов, провайдеры OpenAI/Anthropic/Google): кеш снижает стоимость на 41–80% и время до первого токена на 13–31%.
Вендорская заявка (Anthropic, анонс, 2024): до −90% по стоимости и −85% по latency. Но эти цифры измерены на статичных workload-ах («chat with a book», many-shot prompting) — большой неизменный префикс и короткий запрос, без агентской петли, которая постоянно дописывает волатильный хвост и вызывает инструменты.
Разрыв объясняется разницей нагрузок, а не тем, что один источник врёт. Для бюджета агентской системы бери независимые 41–80%, а не вендорские 90% — и не жди четырёхкратного ускорения по latency, реальная агентская петля даёт 13–31% TTFT, а не 75–79%.
Проверь себя
Недетерминизм
В M4 мы считали, окупается ли кеш промпта. Здесь — прицельно другой вопрос: почему два запуска ОДНОГО И ТОГО ЖЕ эксперимента с одним и тем же промптом дают разный ответ, что с этим можно сделать, а что нельзя сделать никогда.
Задача модуля простая и прикладная: после него ты умеешь объяснить коллеге, почему рерун иногда «чинит» расхождение, а иногда — нет, и что записывать в лог прогона, чтобы сравнение через месяц не оказалось сравнением шума с шумом.
Сэмплинг коротко: что каждая ручка делает с распределением
Модель на каждом шаге выдаёт логиты — по одному числу на каждый токен словаря. Дальше их превращают в распределение вероятностей и выбирают токен. Ручки сэмплера управляют именно этим превращением:
p_i = exp(z_i / T) / Σ exp(z_j / T)
Top-k, top-p и min-p работают иначе: они не трогают форму распределения, а усекают хвост с низкой вероятностью, потом пересчитывают (renormalize) то, что осталось, и уже из этого сэмплируют. Различаются они только правилом, где резать хвост:
- top-k — оставить k токенов с наибольшей вероятностью. Слабость: фиксированный k либо тащит почти-нулевые токены (когда модель уверена), либо отрезает разумные варианты (когда распределение плоское).
- top-p (nucleus) — оставить минимальный набор токенов, чья суммарная вероятность ≥ p. При высокой температуре распределение становится настолько плоским, что top-p может впустить очень маловероятные токены.
- min-p — относительный порог: оставить токены не ниже заданной доли от вероятности топ-токена. Авторы заявляют устойчивое превосходство над top-p на высоких температурах; независимый критический разбор возражает, что при сопоставимом тюнинге min-p «практически неотличим» от top-k/top-p — спор не закрыт. Коммерческие API (OpenAI, Anthropic, Google) min-p не экспонируют.
Штрафы (frequency/presence/repetition) — отдельная категория: они правят логиты по уже сгенерированной истории, а не по самому распределению. Это единственная группа ручек, которая делает генерацию зависящей от префикса: одно расхождение токена меняет штрафной вектор — и все последующие логиты вместе с ним.
Что происходит при температуре 0, честно: сэмплирование как случайный выбор выключается вообще. Вместо него — argmax: берём токен с максимальным логитом. Это математическая функция, а не случайный процесс. Именно на этом честном факте держится вся дальнейшая путаница модуля.
Три уровня «детерминизма», которые обычно путают
Дальше — рамка, без которой любой разговор про воспроизводимость превращается в спор о разном. Есть три РАЗНЫХ утверждения:
1. Математически детерминированный выбор. argmax по логитам — это функция: при фиксированных весах, входе и точной арифметике ответ один. Это верно всегда.
2. Детерминизм при идентичных условиях обслуживания. Побитово одинаковый результат при том же железе, той же версии рантайма и том же составе батча запросов. Это достижимо инженерно — и стоит throughput'а.
3. Воспроизводимость через публичный API. Повторный запрос завтра вернёт тот же ответ. Это не гарантирует ни один вендор.
Главный механизм: не «атомарные операции на GPU», а отсутствие batch invariance
Популярное объяснение — «GPU параллелит вычисления, порядок сложений float меняется, отсюда и шум» — Thinking Machines Lab (сентябрь 2025) опровергла напрямую: отдельное ядро GPU run-to-run детерминировано, повторный запуск одного и того же матричного умножения на тех же данных всегда даёт побитово равный результат. Атомарные операции почти не используются — вычисления параллелятся по batch-измерению, а не гонкой потоков.
Настоящая причина — ядра не batch-инвариантны: численный результат зависит от того, какого размера батч сейчас обрабатывается, потому что порядок редукции (в каком порядке складываются частичные суммы) меняется вместе с размером батча. А размер батча, в котором окажется именно ваш запрос, определяется не вами — а тем, сколько чужих запросов сервер обрабатывает рядом в эту же миллисекунду.
1000 прогонов, T=0 → 80 уникальных завершений; общий префикс ≈102 токена
Три операции пришлось переписать под фиксированный порядок редукции: RMSNorm, matmul (фиксированные тайлы, без динамического split-K — ≈20% потери против cuBLAS) и attention (самое сложное — фиксированный размер сплита вместо фиксированного числа сплитов). Это отдельный инженерный режим — «eval/RL-режим», а не то, в чём обычно работает прод: vLLM прямо документирует, что по умолчанию не гарантирует воспроизводимость результатов ради производительности.
Попробуй сам на имитации ниже: точки расходятся не сразу — сначала идёт общий префикс, потом веер вариантов.
Уникальных завершений: —
Общий префикс: —
Время выполнения (имитация): —
Что на самом деле фиксирует seed — и почему при T=0 он бесполезен
Seed фиксирует ровно одну вещь: источник псевдослучайности при выборе токена из распределения (PRNG сэмплера). Он не фиксирует ни сами логиты, ни порядок редукций, ни состав батча, ни версию ядер.
- OpenAI: seed — «best effort», система должна сэмплировать детерминированно, но не гарантирует; отслеживать смену бэкенда предлагается через
system_fingerprint, который меняется в том числе при апдейтах инфраструктуры вендора. - Google Gemini: seed документирован в
GenerationConfig, но детерминизм прямо не гарантируется; сообщается о воспроизводимом недетерминизме даже при фиксированных seed и temperature. - Anthropic: параметра seed в Messages API нет вообще. И у моделей после Claude Opus 4.6
temperature— deprecated: значение 1.0 принимается для обратной совместимости, всё остальное отклоняется с ошибкой 400.
system_fingerprint — это не гарантия, а детектор: он даёт право сказать «условия изменились», но не право сказать «условия те же → результат тот же». Отсутствие seed у Anthropic в этом смысле честнее: оно не создаёт ложного ощущения контроля.
Насколько велик разброс на практике
Это не гипотетическая проблема на третьем знаке после запятой:
- Замер на 5 моделях, 8 задачах, 10 прогонах в «детерминированной» конфигурации (temperature 0, top_p 0): колебания точности до 15%, разрыв между лучшим и худшим исходом до 70% на части задач.
- Боевой A/B-замер на vLLM: два прогона одной модели, тем же промптом, тем же seed и temperature 0 разошлись в 4.4% решений на одном срезе данных и в 8.8% на другом. Идентичные конфигурации отличались до 0.55 процентных пункта при 95%-доверии — ровно того же порядка, что и эффект, который пытались измерить. Обнаружить эффект в такой постановке невозможно.
Подвигай ползунок: величина эффекта против измеренного базового разброса идентичных прогонов.
Базовый разброс между двумя идентичными прогонами (боевой A/B-замер на vLLM, 95%-доверие): 0.55 п.п. — это то, что вы получите, вообще ничего не меняя.
Правило для экспериментов: сначала мерь шум, потом эффект
Отсюда практическое правило, ради которого написан этот модуль: прежде чем сравнивать варианты, измерь базовый разброс двумя одинаковыми прогонами. Порог обнаружимости эффекта равен этому разбросу — если ожидаемый эффект меньше, через публичный API вы его в принципе не увидите: нужен либо self-host с batch invariance, либо сильно больше N, либо другой дизайн (парные сравнения на одинаковых условиях).
И держи в голове, что именно чинит рерун, а что — нет:
- Чинит: случайность сэмплера (при фиксированном seed/T=0) и разовые сбои.
- Уменьшает, но не устраняет: численный шум от состава батча — усреднение по N прогонов даёт оценку, а не устранение.
- Не чинит никогда: смену версии модели, смену версии рантайма/ядер, смену железа, изменение дефолтов API, дрейф определений инструментов. Это систематические различия, а рерун лишь маскирует их под шум.
Чтобы через месяц можно было сказать, сравниваете вы яблоки с яблоками, записывайте не «параметры», а полное определение условий прогона:
снапшот+дата · параметры сэмплера · байты промпта · схемы инструментов · версия кода · сырые ответы
- Точный ID снапшота модели, не алиас (снапшот — как checkout коммита, алиас — как слежение за main) + дата прогона.
- Все параметры сэмплирования явно, включая дефолты, которые вы не задавали — они меняются между версиями SDK.
- Байты промпта, а не шаблон: итоговый текст, включая system-промпт, порядок сообщений, пробелы. Хэш от байтов.
- Полные определения инструментов (JSON-схемы) — они входят в промпт, и переформулировка меняет вход.
- Версия кода/раннера;
system_fingerprint(если есть) или версия рантайма + ядер + железо (self-host). - N прогонов и разброс между ними, сырые ответы — не один результат и не только агрегат.
Модуль 6 из 7 · Следствия для архитектуры
Следствия для архитектуры
В M1–M5 мы разобрали механику: из чего состоит окно, почему внимание деградирует неравномерно, как растёт цена длины, что даёт кеш промпта и откуда берётся недетерминизм. Этот модуль — про решения, которые ты принимаешь каждый день, собирая мульти-агентную систему на Claude Code: сколько инструментов показывать, как считать бюджет системного промпта, как называть поломки контекста, когда резать сессию, а когда сжимать, строить ли рой субагентов и на что годится память между сессиями.
6.1 Сколько инструментов показывать на шаге
Вопрос не «сколько инструментов в реестре», а «сколько видно модели на конкретном шаге». Замер мая 2026 (arXiv:2605.24660, Meta Platforms) прогнал адаптивную по запросу глубину выдачи против фиксированной на BFCL (370 инструментов в реестре) и ToolBench (3 251 инструмент): покрытие почти не падает, а число показанных инструментов — драматически меньше.
BFCL+BM25: 90,3% при ~7,4 показанных · 90,8% при фиксированных 50
Downstream-проверка на Claude Sonnet 4.6 (тот же замер) показывает, зачем это важно не только для покрытия, но и для качества следующего шага: при адаптивной выдаче точность выбора правильного инструмента — 93,1% против 87,1% у фиксированной выдачи в 5 инструментов; на запросах средней сложности разрыв шире — 76,8% против 60,9%. Сам агент масштабирует выдачу от ~2,5 инструментов на лёгких запросах до ~6,9 на сложных — рабочий диапазон лежит в районе 3–7 на шаг.
Двигай ползунок — числа выше зафиксированы в замере, остальные точки между ними интерполированы для интуиции.
6.2 Размер системного блока: считай инструкции, а не токены
Единственное прослеживаемое до первоисточника измерение размера системного промпта (arXiv:2607.19257, июль 2026, Netanel Eliav, харнесс VeyraBench) меряло не длину в токенах, а число одновременных инструкций: N ∈ {10, 20, 40, 80, 120, 160} на пяти моделях (Claude Sonnet 5, Claude Haiku, Gemini Flash, Qwen 27B, Qwen 35B).
perfect-response rate → 0 к N=80 · порог редизайна ~40
Ни один формат не выигрывает стабильно — Qwen 35B, например, предпочитает plain text markdown'у. Эффект размещения правила (системный промпт vs пользовательский ход) сопоставим с эффектом формата или больше — до 8,7 п.п. при N=160, и направление зависит от модели.
Отдельная и контринтуитивная находка того же замера (эксперимент на синтетическом корпусе 512K токенов): у предела окна растут отказы модели (0% → 79–90%), а не выдумки — фабрикация не зафиксирована ни разу (0 из 5 760 проб). Значит мониторить у предела окна нужно refusal rate, а не только галлюцинации — это сдвиг относительно практик 2025 года.
6.3 Именованные способы испортить контекст
Таксономия Дрю Бройнига (2025) — четыре режима с именем, и под каждым есть конкретное измерение, а не только интуиция.
Пример: у агента Gemini 2.5, играющего в Pokémon, испорченная секция «goals» привела к тому, что модель зациклилась на недостижимых целях.
Признак: модель многократно цитирует попавшую в контекст ошибку как установленный факт.
Пример: точность Llama 3.1 405B в long-context RAG начинает падать уже примерно на 32K токенов; у Gemini-агента после 100K токенов растёт склонность повторять действия из истории вместо нового плана.
Признак: модель опирается на накопленную историю в ущерб тому, что знает из обучения, и повторяет прошлые шаги.
Пример: квантованная Llama 3.1 8B (бенчмарк GeoEngine) провалилась с 46 инструментами и справилась с 19 — при том что обе конфигурации умещались в окно 16K, дело не в переполнении.
Признак: лишняя, нерелевантная информация не игнорируется, а активно используется и портит ответ.
Пример: те же данные, поданные по частям в диалоге, а не одним блоком (Microsoft/Salesforce) — средняя просадка 39%, счёт OpenAI o3 упал с 98,1 до 64,1.
Признак: ранние ошибочные попытки остаются в контексте, новая информация им противоречит, и модель «теряется и не восстанавливается».
6.4 Резать сессию или сжимать
Асимметрия, которую стоит закрепить как правило: `/clear` стоит ноль. Компакция — не гигиена, а сама по себе большой запрос (нужно прочитать и суммаризовать весь разговор) плюс гарантированный сброс кеша — Claude Code засчитывает переписанный компакцией разговор как ожидаемую перестройку, то есть как промах кеша.
структурная компакция: +29…39% качества, −84% токенов
Это измерение относится именно к структурной компакции — очистке устаревших tool-результатов по правилу плюс вынос в файлы. У обычной суммаризации диалога опубликованных измерений выигрыша нет, зато есть репортящиеся регрессии: пользователи сообщают, что после авто-компакции агент «полностью теряет осведомлённость об активно использовавшихся Skills», забывает их процедуры и повторяет ошибки, которые эти скиллы должны были предотвращать — вплоть до «идеально соблюдает правила до компакции, нарушает 100% времени после».
6.5 Субагенты: незакрытый спор
Два поста от разных команд с разницей в один день (12 и 13 июня 2025) прямо противоречат друг другу, и спор не разрешён до сих пор.
Anthropic: +90,2% ценой ×15 токенов · Cognition: «не стройте мульти-агентов», 0 цифр
Важно: сама Anthropic прямо пишет, где мульти-агентный паттерн не работает — задачи с общим контекстом у всех агентов, плотные зависимости между ними и большинство кодинг-задач, где мало распараллеливаемых частей. Cognition иллюстрирует свой тезис примером Flappy Bird: один субагент рисует фон в стиле Super Mario, другой — несовместимого спрайта птицы; финальный агент не может это согласовать, потому что субагенты не видят допущений друг друга.
6.6 Память между сессиями: для старта, не для интерактива
LongMemEval-V2 (arXiv:2605.12493, май 2026, UCLA) сравнил стратегии памяти на трейсах веб-агентов: побеждает не векторный поиск, а файлы плюс агент-контроллер, который сам по ним ходит.
74,9% (файлы+агент) vs 58,6% (структ. поиск) vs 42,8% (обычный RAG) · 108с vs 0,1с
Вывод для архитектора прямой: это ровно то, что делают CLAUDE.md / MEMORY.md / State-реестры — практика получила измерение. Но цена честная: 108 секунд на запрос не годится для интерактивной латентности. Это инструмент стартовой ориентации сессии (агент один раз проходит по файлам в начале), а не что-то, что вызывается на каждом ходу диалога. Приём recitation (Manus) — периодически переписывать todo.md, чтобы цель оставалась ближе к концу контекста — решает ту же проблему «уезжающей из фокуса цели», что и перечитывание процедур после компакции (6.4): это единственная найденная контрмера к потере процедурного знания.
6.7 Диагност решения
Собери всё модуля в один инструмент: ответь на четыре вопроса о своей задаче и получи рекомендацию — одиночный агент или рой, резать сессию или сжимать, сколько инструментов держать на шаге — с указанием, на какой замер она опирается.
1. Задача — исследовательская или кодовая?
2. Подзадачи независимы или связаны общим состоянием?
3. Контекст растёт от результатов инструментов или от диалога?
4. Результат нужен целиком в том же окне?
/clear или сжатие сессии?6.7 Измеренный пример: как сжимает Antigravity
Команды «сжать контекст» там нет, и это не пробел: сжатие идёт само. Периодически
появляется шаг CORTEX_STEP_TYPE_CHECKPOINT, в нём includedStepIndexEnd
(до какого шага покрыто) и sessionSummary — «Continuation Summary». Дальше
работа идёт от сводки, а не от сырой истории.
Замер на прогоне в 239 шагов (122 вызова модели), 21.09.2026:
- Пять чекпоинтов — на шагах 53, 84, 109, 160, 195, то есть каждые 25–50 шагов.
- Сводка 10 800–16 700 символов, порядка 4–6 тысяч токенов.
- После чекпоинта вход следующего вызова падает до 2–8 тысяч токенов.
- Контекст не растёт линейно: медиана вызова за весь прогон — 5 560 токенов. Всплески (33K, 72K, 80K, 106K, 115K) — это чтение больших файлов, а не разросшаяся история; на пике из 115 153 токенов входа 114 195 пришли из кеша.
Разделы сводки: невыполненные просьбы пользователя · что знает пользователь · что сделано · что знает модель · файлы, отдельно изменённые и отдельно просмотренные. То есть сжатие структурное, а не пересказ диалога — ровно тот тип, у которого в разделе 6.4 был измеренный выигрыш.
Модуль 7 из 7 · Что не подтвердилось · зачёт
Что не подтвердилось · зачёт
В M1–M6 мы разбирали, что измерено, что задокументировано поставщиком и что посчитано из опубликованных величин. Этот модуль — зеркальная сторона того же курса: список цифр, которые звучат в точности как измерение, но при проверке источника рассыпаются. Он полезнее раздела с подтверждёнными цифрами по одной причине: подтверждённое число ты используешь один раз и забываешь, а неподтверждённое — то самое, которое кочует по чужим слайдам, докладам и самому этому курсу, если не проверить его лично. Умение отличить измерение от вендорской заявки, от чужой арифметики и от фольклора — это не декоративная методология, это единственная защита от того, чтобы стать следующим звеном в цепочке пересказов «98,3% → 71%», у которой давно потерян первоисточник.
Ходовые цифры, которые не подтвердились
Каждая из них цитируется как факт в блогах и презентациях. При проверке по первоисточнику ни одна не прослеживается.
«Claude 3.5 Sonnet: 98,3% точности при ≤5 инструментах → 71% при
25+, бенчмарк Anthropic, февраль 2025»
Первоисточник не найден — только во вторичных блогах. Такого бенчмарка у Anthropic нет.
«15–20 инструментов — порог активной ротации»
Блоговая агрегация, не измерение. Реальный измеренный ответ другой: адаптивно 2,5–6,9 показанных инструмента на шаг (arXiv:2605.24660).
«Системный промпт деградирует после 2 500–3 000 токенов»
SEO-блоги без эксперимента. Измеренная величина — не длина в токенах, а число одновременных инструкций: к N=80 perfect-response падает до нуля у всех моделей (arXiv:2607.19257).
«RAG дешевле полного контекста в 1 250 раз»
Вендорский блог без описанной методики — не прослеживается до первоисточника.
«Порог авто-компакции Claude Code — 95% окна»
Было верно на середину 2025 (LangChain). В документации 2026 года окно авто-компакции настраиваемое, не фиксированное число.
«Минимальный кешируемый чанк у DeepSeek — 64 токена»
В проверенной документации DeepSeek этого числа нет.
Где расходятся сами источники
Четыре места, где серьёзные стороны — не блогеры — не согласны друг с другом. Тут неправильно выбирать сторону произвольно: нужно держать спор открытым и знать, что именно его закроет.
1. Провал середины в 2026 году
2. Ускорение от спекулятивного декодирования
3. Изоляция кешей между организациями
4. Один агент против роя
Главный пробел темы
Через все шесть модулей курса проходит одна и та же оговорка: методики, которыми измерены провал середины (NoLiMa, RULER, arXiv:2605.23170), масштабирование latency (Meta, только Llama3 405B) и вариативность при T=0 (Thinking Machines, только open-weight модели под vLLM), ни разу не прогонялись публично на флагманских моделях 2026 года — Claude 4.x/5, GPT-5.x, Gemini 3.x. Всё, что курс говорит про конкретную модель этого поколения — это перенос вывода с других моделей и других лет, а не замер именно на ней.
Сортировщик утверждений
Восемь утверждений из этого курса. Для каждого выбери одну метку — измерение (независимый замер с раскрытой методикой), заявка поставщика (задокументированное поведение или собственный замер вендора) или фольклор (блог-пост или практика без воспроизводимой методики). Потом нажми «проверить».
1. «Claude 3.5 Sonnet: 98,3% точности при ≤5 инструментах → 71% при 25+, бенчмарк Anthropic, февраль 2025»
2. «Кеш-хит у Anthropic стоит 10% от цены обычного входного токена»
3. «NoLiMa: Claude 3.5 Sonnet с заявленным окном 200K реально держит качество лишь до ~4K токенов»
4. «Системный промпт деградирует после 2 500–3 000 токенов»
5. «1000 одинаковых запросов при temperature=0 дали 80 разных завершений»
6. «RAG дешевле полного контекста в 1 250 раз»
7. «MCP-инструменты у Anthropic по умолчанию deferred — в контекст входят только имена и инструкции сервера, полная схема подгружается при первом использовании»
8. «На перемешанном „стоге сена“ модели показывают результат лучше, чем на логически связном тексте»
Зачёт
Четыре вопроса по всему курсу — числа из M1–M6, арифметика проверяется руками.
Готово 🎉
7 модулей пройдены. Ступень 0.1 роадмапа закрыта на уровне «могу объяснить и посчитать».
- Разложить окно контекста на слагаемые и назвать, что в нём занимает больше всего места.
- Отличить заявленную длину окна от рабочей и сказать, чем это меряют.
- Оценить порядок времени до первого токена и размер KV-кеша до запуска.
- Назвать точку, где ломается кеш промпта, и посчитать порог его окупаемости.
- Объяснить, почему два одинаковых прогона расходятся, и что записать для сравнимости.
- Выбрать число инструментов на шаге и размер системного блока по замерам, а не на глаз.
- Отделить измерение от вендорской заявки и от фольклора в чужом тексте.
Что читать дальше
- Стоимость токенов и эксплуатации ИИ — денежная сторона длинных диалогов и агентских циклов.
- Почему ИИ-агент работает нестабильно — симптомы дрейфа и проверка процесса.
- Harness Engineering — окружение, состояние и проверка результата агента.
Если нужна помощь с контекстом вашего ИИ-помощника, опишите задачу студии: какие условия теряются и на каком шаге.