docs: activate token-efficient agent workflow

This commit is contained in:
2026-08-26 16:44:02 +03:00
parent 35c5302e78
commit 42fd8940dc
7 changed files with 904 additions and 1 deletions
@@ -0,0 +1,756 @@
# 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.