757 lines
20 KiB
Markdown
757 lines
20 KiB
Markdown
# Codex Sessions Token Audit
|
||
|
||
Дата анализа: 2026-08-26
|
||
|
||
## Контекст
|
||
|
||
Анализ выполнен по rollout-сессиям Codex за день для pet-проекта, где используется:
|
||
|
||
- SDD (Spec-Driven Development);
|
||
- OpenSpec;
|
||
- `AGENTS.md`;
|
||
- skills;
|
||
- subagents;
|
||
- многошаговый workflow от discovery/design до implementation/review.
|
||
|
||
Цель аудита — понять, почему Codex расходует лимиты слишком быстро, определить основные источники token usage и сформировать практические направления оптимизации процесса разработки.
|
||
|
||
---
|
||
|
||
# Executive Summary
|
||
|
||
Разобраны все 9 rollout-файлов. Fork/subagent-сессии были учтены отдельно, чтобы не посчитать унаследованную историю дважды.
|
||
|
||
Главный вывод:
|
||
|
||
> **Проблема действительно есть, и она почти не связана с генерацией кода как таковой. Основной расход создаёт большое количество последовательных model ↔ tool циклов на уже разросшемся контексте.**
|
||
|
||
## Общая статистика
|
||
|
||
| Работа | Model calls | Input | Cached input | Uncached input | Output |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| Аудит SDD/OpenSpec + subagents | **254** | **26.51M** | 25.70M | 812K | 112K |
|
||
| Выбор UI skill | 2 | 53K | 4K | 49K | 1K |
|
||
| Редизайн карточки акции + Curie | **120** | **13.37M** | 12.90M | 469K | 41K |
|
||
| Редизайн операций + Faraday | **182** | **20.95M** | 20.42M | 534K | 80K |
|
||
| **Итого** | **558** | **60.88M** | **59.02M** | **1.86M** | **234K** |
|
||
|
||
Ключевые цифры:
|
||
|
||
- **96.9% всего input — cached input**;
|
||
- всего около **3.1% input был новым**;
|
||
- output модели — около **0.38% относительно input**;
|
||
- reasoning — около **66K токенов**, то есть не является основным источником расхода;
|
||
- средний model call получал примерно **109 000 input-токенов**;
|
||
- из них в среднем:
|
||
- около **105 770 cached**;
|
||
- около **3 341 новых**.
|
||
|
||
Иными словами, очередной `rg`, `sed`, `git diff` или другой tool call приводит к новому model call с огромным уже накопленным контекстом.
|
||
|
||
---
|
||
|
||
# 1. Главная проблема — слишком много model round-trips
|
||
|
||
В SDD-сессии:
|
||
|
||
```text
|
||
254 model calls
|
||
26.51M input tokens
|
||
≈104K input / call
|
||
```
|
||
|
||
Карточка акции:
|
||
|
||
```text
|
||
120 model calls
|
||
13.37M input
|
||
≈111K / call
|
||
```
|
||
|
||
Операции:
|
||
|
||
```text
|
||
182 model calls
|
||
20.95M input
|
||
≈115K / call
|
||
```
|
||
|
||
Получается почти линейная зависимость:
|
||
|
||
```text
|
||
большой context
|
||
×
|
||
много model calls
|
||
=
|
||
огромный cumulative input
|
||
```
|
||
|
||
Типичный дорогой паттерн:
|
||
|
||
```text
|
||
model
|
||
↓
|
||
sed ...
|
||
↓
|
||
model ← опять ~130K input
|
||
↓
|
||
rg ...
|
||
↓
|
||
model ← опять ~140K
|
||
↓
|
||
git diff
|
||
↓
|
||
model ← опять ~150K
|
||
↓
|
||
sed ...
|
||
↓
|
||
model ← опять ~160K
|
||
```
|
||
|
||
Более экономный вариант:
|
||
|
||
```text
|
||
model
|
||
↓
|
||
├─ rg ...
|
||
├─ git diff --stat
|
||
├─ sed relevant-range...
|
||
└─ ...
|
||
↓
|
||
model
|
||
```
|
||
|
||
То есть **batch/parallel tool calls — один из самых сильных рычагов оптимизации**.
|
||
|
||
Хороший контрольный пример есть прямо в логах: сессия «какой skill выбрать» выполнила **8 tool calls всего за 2 model calls**. Это значительно более экономный паттерн.
|
||
|
||
---
|
||
|
||
# 2. Контекст реально разрастается до 200K+
|
||
|
||
Максимальный input одного model call:
|
||
|
||
| Сессия | Median | Max | Context window |
|
||
|---|---:|---:|---:|
|
||
| SDD/OpenSpec | ~128K | **216.5K** | 258.4K |
|
||
| Карточка акции | ~133K | **213.5K** | 258.4K |
|
||
| Операции | ~119K | **231.0K** | 258.4K |
|
||
|
||
Одна из сессий дошла примерно до:
|
||
|
||
```text
|
||
231K / 258K ≈ 89% context window
|
||
```
|
||
|
||
Codex уже был вынужден делать context compaction.
|
||
|
||
Особенно показательно распределение cumulative input:
|
||
|
||
- в основной SDD-сессии **83.6%** input пришлось на вызовы, где контекст уже был больше 100K;
|
||
- в карточке акции — **83.5%**;
|
||
- в операциях — **77.3%**.
|
||
|
||
Если чисто математически ограничить model calls уровнем около 100K input, потенциально можно было бы убрать порядка:
|
||
|
||
```text
|
||
~16.4M input tokens
|
||
```
|
||
|
||
Это не означает, что нужно вводить жёсткий hard-cap 100K, но цифра показывает масштаб проблемы.
|
||
|
||
---
|
||
|
||
# 3. Длинная сессия «одна feature от начала до конца» слишком дорогая
|
||
|
||
Текущий flow приблизительно выглядит так:
|
||
|
||
```text
|
||
research
|
||
↓
|
||
design
|
||
↓
|
||
OpenSpec proposal
|
||
↓
|
||
delta specs
|
||
↓
|
||
design
|
||
↓
|
||
tasks
|
||
↓
|
||
implementation
|
||
↓
|
||
tests
|
||
↓
|
||
fix
|
||
↓
|
||
review
|
||
↓
|
||
docs
|
||
↓
|
||
archive
|
||
```
|
||
|
||
Если всё это живёт в одной conversation, implementation в конце тащит за собой:
|
||
|
||
```text
|
||
весь research
|
||
+ старые tool outputs
|
||
+ обсуждение дизайна
|
||
+ предыдущие ответы
|
||
+ OpenSpec
|
||
+ прочитанный source code
|
||
+ git diff
|
||
+ test output
|
||
+ skills
|
||
+ instructions
|
||
+ ...
|
||
```
|
||
|
||
Хотя для конкретной операции, например:
|
||
|
||
```text
|
||
исправить BrokerageOperationRow
|
||
```
|
||
|
||
большая часть этого контекста уже не нужна.
|
||
|
||
## Рекомендуемый workflow
|
||
|
||
Не отказываться от SDD. Наоборот, использовать OpenSpec как естественную границу контекста:
|
||
|
||
```text
|
||
Session 1 — Discovery / Design
|
||
↓
|
||
proposal + specs + design
|
||
|
||
Session 2 — Planning
|
||
↓
|
||
approved artifacts
|
||
↓
|
||
tasks.md
|
||
|
||
Session 3 — Implementation
|
||
↓
|
||
читает только approved OpenSpec
|
||
+ affected source files
|
||
|
||
Session 4 — Verification / Review
|
||
↓
|
||
git diff
|
||
+ approved specs/design/tasks
|
||
|
||
Session 5 — Archive
|
||
```
|
||
|
||
Каждая следующая сессия получает **результат предыдущей в структурированной форме**, а не всю историю того, как к нему пришли.
|
||
|
||
Это хорошо сочетается с SDD: артефакт становится интерфейсом между агентными сессиями.
|
||
|
||
---
|
||
|
||
# 4. Слишком много полного чтения файлов
|
||
|
||
В командах за день часто встречались:
|
||
|
||
```text
|
||
SKILL.md 35 раз
|
||
tasks.md 35
|
||
AGENTS.md 32
|
||
spec.md 30
|
||
git diff 24
|
||
design.md 23
|
||
proposal.md 21
|
||
schema.yaml 20
|
||
engineering-governance.md 15
|
||
audit-remediation.md 16
|
||
domain-glossary.md 11
|
||
system-overview.md 10
|
||
```
|
||
|
||
Это не означает, что каждый файл каждый раз читался полностью, но хорошо показывает характер поведения агента.
|
||
|
||
Особенно заметна root-инструкция:
|
||
|
||
> перед работой прочитать engineering-governance, system-overview и domain-glossary
|
||
|
||
В результате каждый новый агент снова читает эти документы.
|
||
|
||
Например, одни и те же governance-файлы читали:
|
||
|
||
```text
|
||
root
|
||
Kierkegaard
|
||
Nash
|
||
Curie
|
||
Faraday
|
||
...
|
||
```
|
||
|
||
Это цена текущего governance-подхода.
|
||
|
||
Сам `AGENTS.md` при этом небольшой — примерно 2230 символов. Его размер не является проблемой.
|
||
|
||
## Что лучше изменить
|
||
|
||
Вместо обязательного чтения нескольких больших документов перед любой работой:
|
||
|
||
```text
|
||
AGENTS.md
|
||
|
||
Before work:
|
||
1. Determine affected repositories.
|
||
2. Read their AGENTS.md.
|
||
3. Consult docs/development/engineering-governance.md
|
||
only for the relevant gate/policy.
|
||
4. Read system-overview only for cross-service/
|
||
architectural changes.
|
||
5. Read domain-glossary only when domain semantics
|
||
are involved.
|
||
```
|
||
|
||
То есть сделать документацию **lazy context**, а не mandatory context.
|
||
|
||
---
|
||
|
||
# 5. Некоторые tool outputs слишком большие
|
||
|
||
В SDD-сессии встречались результаты команд размером:
|
||
|
||
```text
|
||
40 137 chars
|
||
36 937 chars
|
||
34 621 chars
|
||
32 936 chars
|
||
32 874 chars
|
||
...
|
||
```
|
||
|
||
В одном случае:
|
||
|
||
```text
|
||
Warning: truncated output
|
||
original token count: 15,592
|
||
Total output lines: 1006
|
||
```
|
||
|
||
То есть агент запросил больше тысячи строк.
|
||
|
||
Другой пример:
|
||
|
||
```bash
|
||
bash -x scripts/verify-openspec-planning.test.sh
|
||
```
|
||
|
||
дал:
|
||
|
||
```text
|
||
566 lines
|
||
original token count: 14,118
|
||
```
|
||
|
||
`bash -x` для обычной успешной verification — дорогой паттерн.
|
||
|
||
## Более эффективный подход
|
||
|
||
Вместо:
|
||
|
||
```bash
|
||
sed -n '1,320p' file1
|
||
sed -n '1,380p' file2
|
||
sed -n '1,300p' file3
|
||
```
|
||
|
||
лучше:
|
||
|
||
```text
|
||
rg / symbol search
|
||
↓
|
||
identify relevant section
|
||
↓
|
||
sed -n '120,180p'
|
||
```
|
||
|
||
То есть `rg` должен быть основным инструментом discovery, а `sed` — точечным чтением найденного диапазона.
|
||
|
||
---
|
||
|
||
# 6. `git diff` — ещё один заметный источник расхода
|
||
|
||
`git diff` встречается минимум **24 раза**.
|
||
|
||
Некоторые outputs достигают:
|
||
|
||
```text
|
||
16K tokens
|
||
14K tokens
|
||
11K tokens
|
||
...
|
||
```
|
||
|
||
Иногда diff перечитывается почти целиком несколько раз.
|
||
|
||
## Рекомендуемый стандарт
|
||
|
||
```text
|
||
git status --short
|
||
↓
|
||
git diff --stat
|
||
↓
|
||
git diff --name-only
|
||
↓
|
||
только затем:
|
||
git diff -- path/to/relevant/file
|
||
```
|
||
|
||
Полный relevant diff имеет смысл один раз читать независимому reviewer.
|
||
|
||
Нежелательно выполнять:
|
||
|
||
```bash
|
||
git diff
|
||
```
|
||
|
||
на multi-repo workspace после большой реализации без предварительного narrowing.
|
||
|
||
---
|
||
|
||
# 7. Subagents стоят токенов, но не являются главной проблемой
|
||
|
||
После удаления унаследованных cumulative counters:
|
||
|
||
## SDD audit
|
||
|
||
Основной agent:
|
||
|
||
```text
|
||
20.45M input
|
||
```
|
||
|
||
Kierkegaard:
|
||
|
||
```text
|
||
+1.07M
|
||
```
|
||
|
||
Peirce:
|
||
|
||
```text
|
||
+4.26M
|
||
```
|
||
|
||
Nash:
|
||
|
||
```text
|
||
+0.73M
|
||
```
|
||
|
||
Итого:
|
||
|
||
```text
|
||
26.51M
|
||
```
|
||
|
||
Subagents добавили примерно:
|
||
|
||
```text
|
||
~6.06M input
|
||
≈23% workload
|
||
```
|
||
|
||
Это существенно, но запрещать subagents не стоит.
|
||
|
||
У них есть важное преимущество: собственный context обычно меньше:
|
||
|
||
```text
|
||
Kierkegaard max ~102K
|
||
Peirce max ~112K
|
||
Nash max ~79K
|
||
Curie max ~62K
|
||
Faraday max ~79K
|
||
```
|
||
|
||
Иногда выгоднее:
|
||
|
||
```text
|
||
200K root
|
||
↓
|
||
spawn focused reviewer with 30–70K
|
||
```
|
||
|
||
чем заставлять root делать ещё несколько десятков model calls с 200K-контекстом.
|
||
|
||
## Важное ограничение
|
||
|
||
Subagent должен получать **узкую задачу**.
|
||
|
||
Нежелательно без необходимости использовать:
|
||
|
||
```text
|
||
fork_turns="all"
|
||
```
|
||
|
||
В первом SDD workflow именно этот режим использовался и требует оптимизации.
|
||
|
||
---
|
||
|
||
# 8. Skills влияют, но не являются проблемой №1
|
||
|
||
Простой запрос:
|
||
|
||
```text
|
||
какой skill мне использовать?
|
||
```
|
||
|
||
имел первый input примерно:
|
||
|
||
```text
|
||
20 479 tokens
|
||
```
|
||
|
||
То есть в Codex Desktop уже существует около **20K+ стартового context overhead** до серьёзной работы.
|
||
|
||
В него входят:
|
||
|
||
- Codex app instructions;
|
||
- tool schemas;
|
||
- environment;
|
||
- plugin information;
|
||
- workspace state;
|
||
- AGENTS;
|
||
- другие системные данные.
|
||
|
||
Например, только Codex app-context занимает около 35K символов, а список `recommended_plugins` — ещё примерно 6.7K символов.
|
||
|
||
Это почти невозможно оптимизировать на уровне проекта.
|
||
|
||
Но skills добавляют дополнительный overhead.
|
||
|
||
`ui-ux-pro-max` инжектировал примерно:
|
||
|
||
```text
|
||
~16 036 символов skill content
|
||
```
|
||
|
||
Первый model call после этого был около:
|
||
|
||
```text
|
||
26 796 tokens
|
||
```
|
||
|
||
## Рекомендуемая структура больших skills
|
||
|
||
```text
|
||
SKILL.md
|
||
↓
|
||
короткий orchestration/router
|
||
↓
|
||
references/
|
||
├── colors.md
|
||
├── typography.md
|
||
├── tables.md
|
||
├── finance.md
|
||
└── ...
|
||
```
|
||
|
||
Reference-файлы читаются только при необходимости.
|
||
|
||
Этот подход особенно полезен для собственных больших skills.
|
||
|
||
---
|
||
|
||
# 9. Reasoning effort пока не стоит оптимизировать первым
|
||
|
||
За весь набор:
|
||
|
||
```text
|
||
Input 60,883,487
|
||
Output 233,968
|
||
Reasoning 66,327
|
||
```
|
||
|
||
Reasoning составляет очень небольшую часть общего расхода.
|
||
|
||
Даже сильное уменьшение reasoning не решит проблему с десятками миллионов input tokens.
|
||
|
||
Для механических операций вроде:
|
||
|
||
```text
|
||
npm test
|
||
lint
|
||
git status
|
||
mechanical implementation
|
||
```
|
||
|
||
high reasoning действительно может быть избыточным.
|
||
|
||
Но по приоритету эта оптимизация значительно ниже context management.
|
||
|
||
---
|
||
|
||
# 10. Реальный рост Codex quota
|
||
|
||
В rollout записывается primary rate limit:
|
||
|
||
```text
|
||
window_minutes: 10080
|
||
```
|
||
|
||
10080 минут = 7 дней.
|
||
|
||
За исследованный кусок дня показатель изменился примерно так:
|
||
|
||
```text
|
||
начало первой сессии: 33%
|
||
после неё: 47%
|
||
после карточки: 53%
|
||
конец последней: 62%
|
||
```
|
||
|
||
То есть:
|
||
|
||
```text
|
||
33% → 62%
|
||
```
|
||
|
||
или около:
|
||
|
||
```text
|
||
+29 процентных пунктов 7-дневного лимита
|
||
```
|
||
|
||
Ощущение, что Codex слишком быстро расходует quota, подтверждается логами.
|
||
|
||
---
|
||
|
||
# Приоритеты оптимизации
|
||
|
||
| Priority | Изменение | Потенциальный эффект |
|
||
|---|---|---|
|
||
| 🔴 P0 | **Разделять длинную feature на SDD / implementation / review sessions** | Очень высокий |
|
||
| 🔴 P0 | **Сокращать количество model ↔ tool round-trips** | Очень высокий |
|
||
| 🔴 P0 | **Batch/parallel независимые tool calls** | Очень высокий |
|
||
| 🟠 P1 | Не читать governance/docs полностью перед каждой работой | Высокий |
|
||
| 🟠 P1 | `rg → targeted sed`, а не большие `sed/cat` | Высокий |
|
||
| 🟠 P1 | `git diff --stat/name-only → targeted diff` | Высокий |
|
||
| 🟠 P1 | Ограничивать test/build output | Средне-высокий |
|
||
| 🟡 P2 | Не использовать `fork_turns=all` без необходимости | Средний |
|
||
| 🟡 P2 | Большие skills разбить на lazy references | Средний |
|
||
| 🟢 P3 | Снижать reasoning для механической работы | Низкий относительно остального |
|
||
|
||
---
|
||
|
||
# Предлагаемые token budgets
|
||
|
||
Для дальнейшей разработки можно использовать ориентиры:
|
||
|
||
```text
|
||
Healthy session
|
||
|
||
initial context: 20–40K
|
||
normal working context: <100K
|
||
warning: >120K
|
||
restart/handoff: >150K
|
||
|
||
model calls / phase: желательно <50
|
||
tool output / call: желательно <3–5K tokens
|
||
```
|
||
|
||
Эти значения следует воспринимать как практические budgets для текущего workflow, а не как жёсткие ограничения Codex.
|
||
|
||
---
|
||
|
||
# Основной принцип оптимизации
|
||
|
||
Не стоит использовать compaction только как последнее средство.
|
||
|
||
В SDD естественной точкой compaction/handoff должен стать **готовый артефакт**.
|
||
|
||
Например:
|
||
|
||
```text
|
||
долго обсуждали
|
||
↓
|
||
получили approved design.md
|
||
↓
|
||
старый разговор больше не нужен
|
||
↓
|
||
NEW SESSION
|
||
↓
|
||
Implement change X according to approved
|
||
proposal/specs/design/tasks
|
||
```
|
||
|
||
То есть:
|
||
|
||
> **SDD artifact должен быть interface между агентными сессиями, а не только документацией внутри одной огромной сессии.**
|
||
|
||
Это позволяет сохранить качество и одновременно удалить значительную часть исторического шума.
|
||
|
||
Implementation-agent получает не всю историю обсуждений, а только авторитетные артефакты и необходимый код.
|
||
|
||
---
|
||
|
||
# Предлагаемое направление: Token-Efficient SDD v2
|
||
|
||
Следующий этап оптимизации имеет смысл строить вокруг следующих вопросов:
|
||
|
||
1. Где именно должны находиться границы Codex sessions.
|
||
2. Какие OpenSpec-артефакты должны передаваться между фазами.
|
||
3. Какие документы обязательны для чтения, а какие должны загружаться лениво.
|
||
4. Когда использовать root agent, а когда focused subagent.
|
||
5. Какой context передавать subagent.
|
||
6. Какие ограничения ввести для:
|
||
- `sed`;
|
||
- `cat`;
|
||
- `git diff`;
|
||
- test output;
|
||
- build output;
|
||
- debug tracing.
|
||
7. Как batch-ить независимые tool calls.
|
||
8. Когда автоматически рекомендовать завершить session и начать новую.
|
||
9. Какие token budgets использовать как guardrails.
|
||
10. Как измерять эффективность изменений по rollout-файлам.
|
||
|
||
---
|
||
|
||
# Итог
|
||
|
||
Текущая проблема не выглядит как:
|
||
|
||
```text
|
||
Codex слишком много думает
|
||
```
|
||
|
||
или:
|
||
|
||
```text
|
||
OpenSpec сам по себе слишком дорогой
|
||
```
|
||
|
||
Основная проблема выглядит так:
|
||
|
||
```text
|
||
большой накопленный context
|
||
×
|
||
очень много model calls
|
||
×
|
||
повторное чтение больших outputs/files
|
||
=
|
||
огромный cumulative input usage
|
||
```
|
||
|
||
Поэтому максимальный эффект даст не сокращение качества спецификаций и не отказ от SDD, а изменение **agent execution model**:
|
||
|
||
```text
|
||
короче sessions
|
||
+ artifact handoff
|
||
+ lazy context
|
||
+ targeted reads
|
||
+ narrow diffs
|
||
+ compact tool output
|
||
+ batched tool calls
|
||
+ focused subagents
|
||
```
|
||
|
||
Это должно стать основой следующей версии SDD workflow.
|