Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Кэш промпта

Префикс-кэш провайдера живёт, пока префикс байт-в-байт совпадает, поэтому промпт собран по летучести:

  • системный промпт целиком стабилен между ходами (персона, правила, файлы проекта [project], списки навыков и наборов) и весь лежит под cache_control-breakpoint’ом. Файлы проекта ради этого читаются ОДИН раз на входе в тур: блок байт-стабилен между итерациями, а не перечитывается на каждой отправке;
  • инструменты лежат в префиксе перед system, поэтому смена набора рвёт кэш один раз, а scope: "turn" — ещё раз на следующем ходу, когда набор откатится. Потому дефолт — chat. Узкий набор при этом облегчает вход каждый ход, и на длинной сессии это окупается с запасом;
  • летучее — [now], recall памяти, память о чате — собрано в блок [state] и едет последним блоком последнего сообщения, то есть после всей истории: префикс «инструменты + system + история» переживает ход, и якорь кэша внутри истории попадает. Живи [state] в system, «сейчас» рвало бы весь префикс каждый ход;
  • атрибуция чужого хода едет отдельным якорем и переезжает на свежий tool_result каждой итерации: сводка перед циклом к концу тула-тяжёлого тура оказывается под десятками сообщений выхлопа, и «речь выше» становится ложью. Носитель якоря и так новый — кэш от переезда почти не страдает;
  • байтовое схлопывание тул-трафика (и результатов, и длинных строк входа — граница у них одна) — один раз на входе в тур: внутри тура история почти append-only, и каждая итерация агентного лупа читает префикс из кэша. Единственное исключение — поджатие длинного тура (context.turn_squeeze_percent): когда трафик тура перерастает долю порога компакции, одним проходом схлопываются и вытесненные копии перечитанного (тот же файл, та же выдача памяти), и старый выхлоп с длинными входами. Префикс рвётся ровно раз на срабатывание, повтор — на удвоенном весе, а проход, которому нечего схлопывать, кэша не касается вовсе. Пока тур легче порога, копии едут целиком: замена по капле на каждой итерации стоила промаха всего префикса у провайдера — дороже всей экономии;
  • якорь кэша — последнее сообщение, чьи байты уже не изменятся (перед elide-окном), плюс маркер на хвосте истории. Граница elide-окна считается ОДНОЙ функцией и для элизии, и для якоря: разойдись они, якорь встал бы на байтах, которые ещё поедут. Двигает её теперь не только счёт сообщений, но и байтовый бюджет (tool_result_keep_chars) — тяжёлый ход сдвигает её чаще, и это осознанная плата: занятость окна дороже промаха кэша;
  • телеграм-окно живой истории меряется репликами людей и схлопывается скачками, кратными history_limit (окно живёт в [limit, 2×limit) ходов) — префикс стабилен между скачками, а не рвётся каждый ход.

llm.prompt_cache: "5m" | "1h" включает (5m — запись в кэш 1.25×, 1h — вдвое дороже на запись, но переживает паузы между репликами); llm.prompt_cache_telegram переопределяет для телеграм-туров ("off" — заглушить только там). Без кэша меняется лишь расстановка маркеров — содержимое промпта то же. Экономику смотри в /v1/stats: cached_tokens (прочитано из кэша) и cache_write_tokens (записано, по наценке) — в итогах и в разрезах by_model/by_source. Записи без чтений — признак инвалидатора или кэша, включённого там, где он не окупается.