Контекст инструментов и кэш промптов
О каждом запросе, который делает встроенный харнесс, верны две вещи: определения инструментов — самая крупная постоянная статья расходов в нём, и почти ни один инструмент не будет использован. Эта страница объясняет, что с этим делает Control Center и почему ответ не сводится к «отправлять меньше инструментов».
Проблема во внимании, а не в байтах
Заголовок раздела «Проблема во внимании, а не в байтах»Control Center регистрирует около 126 инструментов. Если отправить их целиком, определения обходятся примерно в 23 000 токенов на каждом запросе — расход, до которого не добраться никаким сжатием, потому что определения инструментов идут отдельно от разговора, в другой части запроса.
Счёт за токены — очевидная претензия, и при кэшировании промптов она же и меньшая из двух. Настоящая цена — точность выбора. Опубликованные оценки вызова инструментов сходятся в том, что модели надёжно выбирают нужный инструмент примерно до 30–50 инструментов в контексте, а дальше постепенно деградируют. Называемая причина — не количество токенов, а семантическое пересечение: как только в каталоге появляется несколько инструментов с похожими описаниями, модель выбирает между близнецами, а не вспоминает возможность.
При 126 инструментах агент выходит за эту полосу на каждом ходу — включая множество ходов, где ему нужно было всего лишь прочитать файл.
Двухуровневая поверхность
Заголовок раздела «Двухуровневая поверхность»Поэтому запуску показывают две вещи:
- резидентный набор — примерно два десятка инструментов, которые отправляются с полными схемами в каждом запросе;
- индекс имён всего остального, сгруппированный под заголовками вроде «Tickets and projects» или «Memory and knowledge» и стоящий несколько сотен токенов на весь каталог.
По замерам на текущем каталоге это уменьшает блок инструментов с ~23,1 тыс. токенов до ~5,0 тыс., примерно на 78 %, и помещает всегда видимый набор в полосу, где выбор надёжен.
Резидентный набор — это инструменты, которые запуск использует в большинстве запусков: словарь файлов и оболочки (read, write, edit, search, bash, …), инструменты обнаружения, контрольный список задач, поиск по памяти и тот глагол, который текущий режим должен вызвать, чтобы выдать свой результат. Собственный глагол вывода режима всегда резидентен — запуск никогда не должен разыскивать тот единственный вызов, который создаёт его результат.
Отложенный не значит недоступный
Заголовок раздела «Отложенный не значит недоступный»Именно это делает конструкцию безопасной, а не просто дешёвой. Отложенный инструмент можно вызвать с первого хода. Скрыта только его схема.
Агент видит имя в своём промпте. Если он вызывает это имя напрямую, харнесс загружает схему и выполняет инструмент тем же шагом — без ошибки, без лишнего круга. Модели не нужно знать, что инструмент когда-либо был «выгружен».
Когда агент знает задачу, но не знает имени, search_tools принимает описание на обычном языке («назначить тикет на кого-нибудь»), ранжирует всю поверхность запуска и возвращает совпадения с уже загруженными схемами, так что уже следующий ход может вызвать одно из них. Если поиск ничего не находит, он прямо говорит об этом и предлагает другую формулировку или более широкий поиск — намеренно, потому что агент, который воспринимает пустой поиск как «такой возможности нет», придумает замену вместо того, чтобы поискать снова.
search_tools есть только во встроенном харнессе. У внешних клиентов MCP вместо него search_tool_bm25, который ранжирует тот же индекс, но лишь описывает совпадения — эти клиенты уже получили все схемы из tools/list, так что загружать нечего.
Чего отложенная загрузка не делает никогда
Заголовок раздела «Чего отложенная загрузка не делает никогда»Отложенная загрузка применяется после фильтра инструментов режима, а не вместо него. Она скрывает схему, но не может открыть инструмент, который режим запретил. Активированный инструмент всё равно проходит запрос на подтверждение и ограничения действий точно так же, как резидентный, и инструмент не может загрузить имя, которого изначально не было на поверхности запуска.
Поверхность MCP, которую видят внешние клиенты, при этом не затрагивается. tools/list по-прежнему возвращает полный каталог. Более ранняя попытка её урезать сломала агентов начисто: клиенты MCP сверяют имена инструментов со своим кэшированным списком и отказываются от всего, чего в нём нет, даже не спрашивая сервер, поэтому «скрытый, но вызываемый» инструмент оказывался просто недостижим. Отложенная загрузка живёт в харнессе, где загрузить инструмент посреди запуска — это то, что харнесс действительно может сделать.
Как её отключить
Заголовок раздела «Как её отключить»--tool-deferral=off (или CC_SERVER_TOOL_DEFERRAL=off) снова делает резидентным каждый допущенный инструмент, порождая ровно те запросы, которые сервер делал до появления отложенной загрузки. См. справочник по CLI cc_server.
Кэширование промптов
Заголовок раздела «Кэширование промптов»Нагрузка агентов перекошена: они отправляют огромные промпты и получают маленькие ответы, ход за ходом, каждый раз с одним и тем же префиксом. Провайдеры кэшируют этот префикс, и чтение из кэша стоит примерно десятую часть свежего. Поэтому доля попаданий в кэш — полноценное свойство харнесса, а не оптимизация; а в Anthropic она ещё и даёт пропускную способность, потому что кэшированные токены не идут в зачёт поминутного лимита ввода.
Кэширование работает по точному совпадению префикса, и из этого следует одно главное правило.
Никогда не переписывайте то, что уже отправлено
Заголовок раздела «Никогда не переписывайте то, что уже отправлено»Любой изменившийся байт сбрасывает кэш начиная с этого места. Поэтому харнесс всегда только дописывает: новые сообщения в конец, а только что активированные схемы инструментов — после кэшированного блока инструментов, а не внутрь него. Именно этот порядок и делает активацию дешёвой — кэшированный префикс остаётся неизменным, и запуск платит только за те схемы, которые только что загрузил.
Цикл также вырезает устаревший вывод инструментов из старых ходов, чтобы вернуть контекст. Он ждёт, пока не наберётся достаточно для возврата, чтобы перезапись того стоила, поэтому вырезание — редкая глубокая перезапись, а не непрерывный промах кэша.
Где ставятся точки кэширования
Заголовок раздела «Где ставятся точки кэширования»Провайдер допускает ограниченное число маркеров кэша, и Control Center расходует их осознанно:
| Маркер | Что покрывает | Время жизни |
|---|---|---|
| Последний резидентный инструмент | Блок инструментов | 1 час |
| Последний системный блок | Инструменты + системный промпт | 1 час |
| Хвост предыдущего хода | История до последнего запроса | 5 мин |
| Хвост текущего хода | Вся история | 5 мин |
Последние два — скользящая пара, и причина этой пары неочевидна: поиск в кэше просматривает назад ограниченное число блоков в поисках того, что сохранил более ранний запрос. Один ход, выполняющий много инструментов параллельно, может породить больше блоков, чем это окно, и тогда один из хвостовых маркеров тихо промахивается, а запрос платит полную цену, и в ответе ничто об этом не говорит. Пометка точного места, на котором остановился предыдущий запрос, делает попадание структурным, а не гонкой.
Префикс «инструменты и система» получает долгое время жизни, потому что он постоянен на протяжении всего запуска, разделяется каждым запуском и субагентом той же формы и потому что отсчёт начинается, когда запрос начинается: ход, который стримит несколько минут, уже израсходовал большую часть короткого окна до того, как сформируется следующий запрос.
Субагенты делят один префикс
Заголовок раздела «Субагенты делят один префикс»Субагенты одного типа порождают байт-в-байт одинаковые префиксы промптов, поэтому они должны читать одну запись кэша, а не каждая писать свою. Но запись становится читаемой только после того, как записавший её запрос начнёт отвечать, поэтому при веерном запуске, начатом целиком, каждый дочерний запуск переплачивает за общий для всех них префикс.
Харнесс даёт стартовать первому дочернему запуску данной формы, а затем освобождает остальные, как только тот начинает стримить. Ожидание ограничено: медленный первый дочерний запуск стоит одного попадания в кэш, но никогда — самого веерного запуска. По той же причине каждый субагент получает один и тот же резидентный набор инструментов независимо от своего профиля: разный набор по профилям дробил бы общий префикс без всякой выгоды, ведь профиль уже решил, что дочерний запуск может вызывать.
Как это увидеть в работе
Заголовок раздела «Как это увидеть в работе»И то и другое можно наблюдать, а не предполагать:
- Обозреватель контекста в разговоре показывает резидентные инструменты, отложенный индекс и то, сколько стоила бы каждая отложенная схема; всё это строится тем же путём в коде, что и реальный запуск.
- Каждый запуск записывает, какие отложенные инструменты он загрузил и что это вызвало, поэтому поиск, который ничего не нашёл, виден как промах поиска, а не растворяется в агенте, тихо делающем что-то смежное.
- Наблюдаемость показывает Доля кэша — отношение чтений из кэша ко всем обработанным токенам промпта, включая записи в кэш: запуск, который постоянно перестраивает свой префикс, получает низкий показатель, а не такой, как у запуска, которому кэш вообще не был нужен.