Кеш промптів
Чи ламає rtok кеш промптів?
Ні — це виміряно, а не обіцяно. rtok stats на цій машині (2026-09-18) показує
hit=97.5% — 5 620 803 600 токенів читання з кешу проти 145 402 240 токенів створення кешу і
667 038 некешованих вхідних токенів за 910 сесій, — а розділ Cache у rtok report на
ту саму дату не має жодного рядка про скидання кешу в усьому журналі обліку: нуль зафіксованих скидань кешу промптів.
Причина структурна, для кожного інтерфейсу нижче: побайтово стабільне вставлення, переписування поза
робочим краєм розмови і хуки, які торкаються кожного результату один раз. Відтворіть обидва числа:
rtok stats 2>/dev/null | head -4
rtok report 2>/dev/null | sed -n '/[Cc]ache/,+6p'
Хуки — фільтрування один раз, далі байтами володіє хост
cmd і read працюють на PreToolUse, до виклику: вивід скорочується один раз, і
хост зберігає цей текст у своєму транскрипті. Кожен наступний хід повторює власні збережені
байти хоста — rtok уже не бере участі, тож ніщо з того, чого він торкався, між ходами не змінюється. Та сама
логіка, що й в аргументі rtk щодо кешу, плюс архів: усе, що вирізано, можна отримати, а
байти, що лишаються, незмінні протягом усієї сесії.
inject — побайтово стабільний на кожному ході
Вставлення SessionStart обчислюється заново на кожному ході, тож воно лишається в кешованому префіксі,
лише якщо байти ніколи не зсуваються. І вони не зсуваються: два запуски з незміненим станом дають ідентичний
вивід, що закріплено тестом three_500_budget_800_drops_one_and_is_byte_stable
(src/plugins/inject/mod.rs), а session_start_has_nudges_once_and_stable покриває
шлях підказок (nudge). Будь-що в inject, що залежить від часу чи лічильників, — це баг за власним
інваріантом плагіна, а не компроміс.
archive / proxy — переписування лише поза keep_turns, побайтово ідентичні вказівники
Фільтр archive на боці проксі переписує результат інструмента у вказівник на архів, лише коли
хід старший за archive.keep_turns; system, tools і найновіші ходи
ніколи не змінюються, тож робочий край — частина, яку провайдер ще записує в
кеш, — лишається недоторканим. Два тести в src/plugins/archive/mod.rs закріплюють стабільність:
six_turn_fixtures_archive_only_turns_1_and_2_on_every_wire (із шести ходів переписуються лише 1–2,
для кожного формату протоколу) і live_blobs_shrink_stably_outside_the_working_edge
(вказівник переписаного блоку побайтово ідентичний, коли його переписують знову).
Виміряно на цій машині, 2026-09-18 — mise exec -- cargo run --quiet -- stats 2>/dev/null | head -4:
sessions 910 lines 433211 malformed 0
usage input=667038 cache_create=145402240 cache_read=5620803600 output=27472613 hit=97.5% median_context=63829
api input cache_create cache_read output hit
codex 12370533 0 243051392 671350 95.2%
і mise exec -- cargo run --quiet -- report 2>/dev/null | sed -n '/[Cc]ache/,+6p':
## Cache
Prompt-cache busts by cause, from the proxy's `usage` rows (whole ledger).
No rows in window.
Це весь журнал обліку, зібраний проксі: попри те, що archive переписує старіші результати інструментів
у трафіку, жодного скидання кешу ніколи не зафіксовано, а частка влучань становить 97.5% (95.2% для api
codex, яке повідомляє 0 токенів створення кешу).
По смугах — частка влучань і replay-тест
Коли проксі обслужив трафік поза смугою agent (bulk, internal, …), rtok stats додає поруч з
api таблицю lane з тими самими лічильниками та часткою влучань у кеш промпту для кожної смуги
(lanes у --json). Сховище лише з ходами агента такої таблиці не друкує. Стабільність смуги
agent закріплена тестом tests/proxy_cache_replay.rs: він програє одну зростаючу розмову через
проксі з усіма ввімкненими переписуваннями й перевіряє, що tools, system і кожне
повідомлення до живого краю попереднього ходу доходять до upstream побайтно однаковими.
guard — відмови не додають байтів
Відмова guard — це рішення PreToolUse, а не вміст: вона блокує повторний виклик
із фіксованою однорядковою причиною duplicate; rtok expand <id> і не додає байтів результату інструмента
до жодного ходу. За результат, у якому вона відмовляє, уже заплатили один раз, і його можна отримати за цим
id, тож модель ніколи не платить за другу копію, — а транскрипт, який вона повторює, лишається
незмінним, що й потрібно для кешу.
Збереження без втрат не коштує кешу
Усе описане вище скорочує байти; ніщо їх не втрачає. Кожні скорочені дані архівуються
до вирізання, а expand <id> відновлює оригінал (--lines, --grep). Вказівник
у транскрипті побайтово стабільний, тож можливість отримати дані ніколи не переписує префікс: кеш
зберігає свої влучання, а ви — повний текст.
Sticky-маршрутизація проти Batch / Flex
Влучання в кеш промптів провайдера потребують стабільного байтового префікса і, для upstream із кількома pod,
прив'язки до того самого бекенду, що тримає кеш (I-84 / sticky-маршрутизація). Це ортогонально до
Batch (асинхронний pass-through; жодного спільного живого KV сесії з інтерактивним агентом) і
Flex (service_tier на тому самому синхронному протоколі — правила кешу діють і далі, знижка дається
рівнем). rtok не перетворюватиме синхронний хід агента на завдання Batch лише заради економії; робіть це
тільки з явним клієнтом Batch. Подробиці: batch-flex.md.
# Запланований прапорець sticky у [proxy.routing] (сьогодні не завантажується) — закріплює upstream для прив'язки кешу.
# Flex — це [proxy.flex]; спостереження за Batch — [proxy.batch]. Жоден із них не переписує кешовані
# байти system/tools/живого краю так, як це зробило б необережне стиснення.
[proxy.routing]
sticky = true