18 KiB
Context Usage Audit
Дата: 2026-04-18
Статус: Research
Goal: проверить, как в проекте сейчас считается usage контекста, сверить это с official docs и с реальными логами, и зафиксировать, что нужно менять для понятного и точного UI
Executive Summary
Главный вывод:
- ✅ Для Anthropic prompt-side input текущая базовая формула
input_tokens + cache_creation_input_tokens + cache_read_input_tokensкорректна. - ❌ Для "процент занятого контекста" текущий UI смешивает несколько разных сущностей:
- total prompt input
- visible/debuggable context
- full context used in the turn
- guessed context window
- ❌ Кнопка открытия context panel на team screen сейчас показывает не процент занятого контекста, а смесь
visible context / total tokens, при этом подписывает это какof input. - ❌ Live lead context usage в team runtime не учитывает
output_tokens, хотя Anthropic docs явно пишут, что input и output components count toward the context window. - ⚠️ Для Codex текущие локальные session logs часто вообще не содержат usable input-side token telemetry: в
.jsonlвиденoutput_tokens, аinput_tokens/cache_*остаются нулями. То есть "точный процент" для Codex из текущего источника правды пока получить нельзя. - ⚠️ Для Anthropic context window size нельзя опираться только на
"[1m]"suffix. По актуальным docs/релиз-ноутам окно зависит от конкретной модели: native1Mуже есть у новых raw model ids вродеclaude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6, тогда как часть legacy путей остаётся на200kили временном beta-path.
1. Что сейчас считается в коде
1.1 Live lead context в team runtime
Источник:
src/main/services/team/TeamProvisioningService.ts
Текущая формула:
currentTokens = input_tokens + cache_creation_input_tokens + cache_read_input_tokens
percent = currentTokens / contextWindow
Это значение эмитится как lead-context.
Что важно:
- это total prompt input
- это не full context used for the completed turn
output_tokensсейчас исключены
1.2 Context button на экране команды
Источник:
src/renderer/components/team/TeamDetailView.tsx
Текущее поведение:
- собирается
visibleContextTokens = sumContextInjectionTokens(allContextInjections) - затем считается
visibleContextPercentLabel = formatPercentOfTotal(visibleContextTokens, lastAiGroupTotalTokens) - при этом
lastAiGroupTotalTokensсейчас =input + cache_read + cache_creation + output - но helper
formatPercentOfTotal()возвращает строку вида"X% of input"
Итог:
- знаменатель уже не input
- числитель это вообще visible subset
- label говорит of input
- кнопка выглядит как будто это общий context usage
То есть тут сразу 3 semantic mismatch.
1.3 Session Context Panel / Token popover
Источники:
src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsxsrc/renderer/components/common/TokenUsageDisplay.tsx
Сейчас в проекте одновременно существуют 3 разных процента:
visible_estimated / total_inputvisible_estimated / (input + output + cache)prompt_input / context_window
Но в UI они местами называются почти одинаково.
2. Что говорят official docs
2.1 Anthropic: что такое input_tokens при caching
Official docs:
Ключевые факты:
input_tokens- это только токены после последней cache breakpoint- total prompt input считается как:
total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens
Источник:
- docs lines 491-500, 493-500, 495:
input_tokensпредставляет только токены после последней точки разрыва кэшаtotal_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens
Вывод:
- текущая базовая формула runtime для Anthropic prompt input правильная
- жалоба пользователя на "input percent" логична, потому что
input_tokensalone действительно не равен общему prompt input
2.2 Anthropic: что вообще считается context window
Official docs:
Ключевые факты:
- context window refers to all text model can reference, including the response itself
- при tool use docs прямо говорят:
- all input and output components count toward the context window
Источник:
- lines 194-197
- lines 215-220
- lines 255-262
Вывод:
- если UI обещает показать именно "сколько контекста занято", то
output_tokensигнорировать нельзя - текущий live team formula under-reports occupied context for completed turn
2.3 Anthropic: thinking blocks
Official docs:
Ключевой факт:
- previous thinking blocks are automatically stripped from future context
Источник:
- lines 225-239, especially 228 and 237
Вывод:
- есть важная разница между:
- full context used during current turn
- context that will carry into future prompt
- usage fields alone не дают perfectly exact "future carried context" без доп. нормализации thinking
2.4 Anthropic: какие модели сейчас имеют 1M context window
Official docs:
Ключевые факты на дату проверки:
- current models overview показывает:
claude-opus-4-7-1Mclaude-sonnet-4-6-1Mclaude-haiku-4-5-200k
- release notes отдельно фиксируют:
- с
2026-03-131MGA дляClaude Opus 4.6иClaude Sonnet 4.6 2026-03-30объявлен retirement beta-path дляClaude Sonnet 4.5иClaude Sonnet 4на2026-04-30
- с
- context windows page также указывает, что native long-context matrix уже не сводится к одному beta-header сценарию
Вывод:
- inference размера окна для Anthropic надо делать по model matrix, а не только по
"[1m]"suffix - internal app-alias
"[1m]"всё ещё полезен как явный сигнал team UX, но для raw session model ids этого уже недостаточно
3. Что показывают реальные локальные логи
Проверены реальные ~/.claude/projects/*.jsonl.
3.1 Claude / Anthropic
Типичный реальный кейс:
"usage": {
"input_tokens": 3,
"cache_creation_input_tokens": 9284,
"cache_read_input_tokens": 63347,
"output_tokens": 8
}
Это значит:
input_tokens = 3совсем не означает "в prompt было 3 токена"- реальный total prompt input здесь:
3 + 9284 + 63347 = 72634
То есть UI, который визуально намекает на "input %" без явного объяснения caching breakdown, будет выглядеть багованным даже если арифметика частично правильная.
3.2 Codex / OpenAI path в локальных session logs
Проверены реальные Codex entries в ~/.claude/projects/-Users-belief-dev-projects-claude-claude-team/**/*.jsonl.
Типичный кейс:
"usage": {
"input_tokens": 0,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 650
}
Повторяется много раз на msg_codex_*.
Вывод:
- текущий
.jsonlsource для Codex у нас часто не даёт usable prompt-side usage - значит из текущих session logs нельзя честно строить accurate Codex context percent
- сначала нужен новый telemetry source или нормализация raw usage
4. Codex: что говорят official OpenAI docs
4.1 Context windows
Official docs:
Ключевые факты на дату проверки:
GPT-5-Codex-400,000 context windowcodex-mini-latest-200,000 context window
4.2 Cached prompt accounting
Official docs:
Ключевой факт:
- usage exposes
prompt_tokens_details.cached_tokens
Это означает:
- на уровне OpenAI API нужная prompt-side telemetry в принципе существует
- но наш текущий local session source её, похоже, не сохраняет/не нормализует
5. Конкретные проблемы в текущем проекте
5.1 Semantic mismatch: "visible context" vs "context used"
Сейчас рядом живут две разные сущности:
- Visible Context - то, что мы можем debug/reduce
- Context Used - сколько окна реально занято
Это не одно и то же.
Visible Context:
- это subset prompt-side content
- может сравниваться с total prompt input
Context Used:
- это usage against context window
- для Anthropic completed turn это ближе к
total_input + output
5.2 Неправильный label на context button
Текущая button label на team screen:
- выглядит как общий context usage
- но фактически это visible subset percent
Это и есть один из главных user-facing bugs.
5.3 Inconsistent denominators
Сейчас по коду используются разные denominators:
totalInputTokensinput + output + cachecontextWindow
Без явного переименования метрик UI всегда будет путать.
5.4 Early-run guessed context window
В TeamProvisioningService размер окна сначала может быть guessed:
200KдляlimitContext=true- иначе по model-specific matrix:
- internal Anthropic
"[1m]"alias ->1M - native long-context Anthropic raw ids (
claude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6) ->1M GPT-5.4/GPT-5.4 pro->1.05Mcodex-mini-latest->200K- остальные текущие GPT-5/Codex team models ->
400K
- internal Anthropic
Потом он обновляется из modelUsage.contextWindow, если это поле пришло.
Значит:
- ранний live percent может быть временно неточным
5.5 Shared default drift
В shared utils есть:
DEFAULT_CONTEXT_WINDOW = 200_000
Но team Anthropic UX по умолчанию исходит из 1M.
Это не обязательно immediate arithmetic bug, но это source of drift для разных экранов и helper'ов.
6. Рекомендованная metric model
Если делать UI понятным и точным, нужно разделить минимум 3 разные метрики.
6.1 Prompt Input Used
Для Anthropic:
prompt_input_used =
input_tokens +
cache_creation_input_tokens +
cache_read_input_tokens
Назначение:
- честный size текущего prompt
- хорошая база для Visible Context %
6.2 Context Window Used
Для Anthropic completed turn:
context_window_used_approx =
prompt_input_used +
output_tokens
Почему approx:
- previous thinking blocks auto-strip from future turns
- exact future carried context нельзя получить из raw usage perfectly
Но если UI обещает "занятое окно прямо сейчас/на этом ходе", эта формула ближе к docs, чем текущая.
6.3 Visible Context Share
visible_context_share = visible_context_estimated / prompt_input_used
Назначение:
- debug metric
- объясняет, какая часть prompt-а понятна и управляемая пользователю
Это не percent occupied context window.
7. Рекомендованный UI language
Вместо одного размыто слова Context лучше использовать разные подписи:
Context Used- percent of context windowPrompt Input- current prompt-side tokensVisible Context- debuggable subset of prompt
Тогда пользователь сразу видит:
- сколько занято всего
- сколько из этого prompt
- сколько из prompt мы реально понимаем по breakdown
8. Top 3 implementation options
1. Развести 3 разные метрики и переименовать UI честно
🎯 10 🛡️ 9 🧠 7
Примерно 180-260 строк изменений
Что сделать:
- team button показывает только
Context Used - panel header отдельно показывает:
Visible ContextPrompt InputContext Window Used
Visible Contextвсегда считается только как доля prompt input
Плюсы:
- минимальный semantic debt
- почти все пользовательские жалобы закрываются сразу
- легче потом добавить Codex
Минусы:
- надо аккуратно переподписать UI в нескольких местах
2. Оставить один главный процент, но считать его по docs как prompt + output
🎯 8 🛡️ 8 🧠 6
Примерно 120-180 строк изменений
Что сделать:
- live team percent =
(input + cache_read + cache_creation + output) / contextWindow Visible Contextоставить только внутри sidebar/panel
Плюсы:
- очень понятная одна главная цифра
- максимально близко к official Anthropic context-window semantics
Минусы:
- future carried context всё равно не perfectly exact из-за thinking blocks
- нужен fallback wording, когда usage incomplete
3. Минимальный fix только label-ов и знаменателей
🎯 6 🛡️ 6 🧠 3
Примерно 40-90 строк изменений
Что сделать:
- перестать писать
of input, если denominator не input - button переименовать в
Visible - panel header явно разделить
VisibleиTotal
Плюсы:
- быстро
- дешево
Минусы:
- не решает core semantic debt
- live lead percent всё ещё останется under-reported
9. Recommended next step
Рекомендую идти по варианту 1.
Почему:
- он закрывает и math, и naming, и UX confusion
- он не завязан только на Anthropic
- он даёт clean foundation для будущего Codex support
Practical plan
- Вынести явные type/terms для 3 метрик:
promptInputTokenscontextWindowUsedTokensvisibleContextTokens
- Исправить live Anthropic runtime formula и wording.
- Перестать использовать label
of inputтам, где denominator неprompt input. - Для Codex временно показывать:
- window size, если модель известна
context usage unavailableилиoutput only- пока не появится raw prompt telemetry
10. Bottom line
Главная проблема сейчас не в одной строчке арифметики, а в том, что проект смешал:
- prompt input
- visible debuggable context
- full context window usage
В Anthropic path базовая input formula уже в целом нормальная, но UI поверх неё даёт неправильный смысл.
В Codex path проблема глубже:
- official API supports cached prompt accounting
- но наш текущий local session telemetry этого не доносит
- поэтому "точный % занятого контекста" для Codex пока нельзя обещать без нового data source