Загрузка...

Сколько токенов съедает сама обвязка агента: Claude Code, Codex, Cline и OpenCode на одной задаче

Когда агент решает задачу, счёт растёт не только от вашего кода и вопросов. На каждом шаге в модель снова уходят системный промпт самого агента и описания всех его инструментов, и это часто весит больше, чем ваши файлы. Мы прогнали одну и ту же задачу на одном проекте и одной модели, anthropic/claude-sonnet-5.5, в четырёх агентах: Claude Code, Codex, Cline и OpenCode. Все запросы шли через RouterAI, поэтому токены и рубли считались по одному прайсу и по полю usage из ответов API.

Эта статья дополняет сравнение моделей на одном агенте: там менялась модель, здесь модель одна, а меняется агент.

Коротко

  • Модель, проект и задача одинаковые, все проверки пройдены, а счёт отличался в 4,6 раза: от 2,49 ₽ (OpenCode) до 11,52 ₽ (Codex) в повторных прогонах.
  • На обвязку (системный промпт и описания инструментов) приходится от 73% до 92% байтов запросов за сессию. Один «пустой» запрос стоит от 4,4 тыс. токенов у Cline до 18 тыс. у Claude Code.
  • Кэш промпта влияет на счёт сильнее, чем размер обвязки: Claude Code с отключённым кэшем потратил 5,60 ₽ вместо 2,75 ₽.
  • Три стандартных MCP-сервера добавили в OpenCode 6,9 тыс. токенов к каждому запросу. В Claude Code те же серверы добавили 0,4 тыс.: он держит схемы инструментов в стороне и подгружает по требованию.
  • Через Responses API с моделью Claude мы увидели две странности: MCP-инструменты Codex не доходят до модели, а к каждому запросу добавляется 1,05 ₽. Подробности и оговорки в разделе про то, что мы не смогли измерить честно.

Методика

Дата замеров: 31 октября 2026 года. Окружение: одноразовый контейнер node:24-bookworm, агенты ставились из npm, права и подтверждения отключены флагами, потому что контейнер изолирован.

Агент Версия Как запускали
Claude Code 2.1.316 claude -p, Anthropic Messages API
Codex 0.166.0 codex exec, Responses API
Cline CLI 3.0.74 (пакет cline) cline -y, OpenAI-совместимый провайдер
OpenCode 1.19.5 opencode run, OpenAI-совместимый провайдер

Cline здесь консольный, а не расширение для VS Code, поэтому его системный промпт может отличаться от того, что вы видите в редакторе. Kilo Code и Hermes Agent в замеры не вошли.

Модели. Основная: anthropic/claude-sonnet-5.5. Для сравнения: anthropic/claude-haiku-5.5. Цены из каталога RouterAI на 31 октября 2026 года, ₽ за 1M токенов: Sonnet 5.5 — вход 209,45, выход 1047,24, чтение из кэша 10,47, запись в кэш 261,81; Haiku 5.5 — 10,47, 52,36, 1,05 и 13,09. Актуальные значения смотрите на карточках моделей.

Проект и задача. Демо-проект Invoices: три файла на Node.js и тест, 42 строки. Промпт одинаков для всех агентов:

В этом Node.js-проекте добавь в invoices.js функцию overdueInvoices(), которая возвращает счета со статусом overdue, экспортируй её и добавь тест в invoices.test.js. Запусти node --test и убедись, что тесты проходят. В конце ответь одной фразой.

Результат считается верным, если node --test проходит и overdueInvoices() возвращает ровно один счёт, с id 3. Качество кода мы не оценивали, только эту проверку.

Как считали. Между агентом и RouterAI стоял прозрачный прокси. Он пересылал запросы без изменений и записывал для каждого из них размер тела, число инструментов, размер системного промпта и поле usage из ответа. Один запрос к модели считаем одним шагом. Цену задачи берём как разницу баланса до и после (GET /api/v1/credits); для Codex и Cline она совпала с суммой usage.cost из ответов. Sonnet прогонялся по три раза на агента, Haiku по два, везде берём медиану. Код прокси, скрипт прогона и сводки приведены в конце статьи.

Результаты

Задача на Sonnet 5.5, медиана трёх повторов; во всех 12 прогонах проверка прошла.

Агент Запросов Вход за задачу, токенов Выход, токенов Цена в повторах, ₽ Цена первого прогона, ₽ Время, с Обвязка в запросах
Claude Code 6 ≈114 тыс. (оценка) 1 131 2,75 7,08 25,7 92%
Codex 3 37 378 522 11,52 11,53 16,5 90%
Cline 7 ≈40 тыс. (оценка) 1 291 4,24 8,60 30,7 73%
OpenCode 7 ≈70 тыс. (оценка) 1 481 2,49 5,44 27,6 90%

Как читать таблицу:

  • «Вход за задачу» считается по размеру тела всех запросов, делённому на число байтов на токен. Этот коэффициент мы сняли с первого запроса каждого агента, где usage точен: от 2,55 до 3,36 байта на токен. Для Codex это значение прямо из usage. Почему не из usage у остальных, объясняем ниже.
  • «Обвязка в запросах» — доля системного промпта и описаний инструментов в байтах тела запросов за всю сессию. Остальное — история диалога, файлы и результаты команд. У Cline доля ниже, потому что у него самая маленькая обвязка, а история за семь шагов выросла с 13,8 до 22,3 КБ.
  • Первый прогон и повторы. Системный промпт и инструменты одинаковы от запуска к запуску, и провайдер кэширует эту часть. В первом, холодном прогоне те же задачи стоили 7,08 / 11,53 / 8,60 / 5,44 ₽, в повторах — 2,75 / 11,52 / 4,24 / 2,49 ₽. У Codex цена не менялась ни в одном прогоне: попаданий в кэш мы у него не увидели.
  • OpenCode делает семь запросов, один из них служебный, без инструментов, на 0,8 тыс. токенов.

Больше всего вход у Claude Code, а в повторах он вдвое дешевле Cline, у которого вход втрое меньше. Больше всего платит Codex, хотя шагов у него меньше всех. Размер обвязки сам по себе счёт не объясняет, дальше разберём почему.

В других замерах порядок тот же. Systima в июле 2026 года на Claude Sonnet 4.5 насчитала около 33 тыс. токенов в первом запросе Claude Code против около 7 тыс. у OpenCode. Agentic Control Plane в сентябре сравнили первые запросы по байтам: 68 КБ у Claude Code, 37 КБ у Codex, 29 КБ у OpenCode. У нас те же агенты в более новых версиях: 46, 39 и 31 КБ, и 13,5 КБ у Cline.

Сколько стоит «пустой» запрос

Чтобы отделить обвязку от задачи, мы просили агента ответить одним словом: «готово». Это первый запрос с холодным кэшем, токены здесь точные.

Агент Токенов в запросе Инструментов Схемы инструментов Системный промпт Цена, ₽
Claude Code 18 029 12 29,5 КБ 15,0 КБ 3,7
Codex 11 744 9 17,3 КБ 19,8 КБ 3,5
OpenCode 10 507 10 20,8 КБ 9,5 КБ 2,9
Cline 4 388 4 8,4 КБ 4,6 КБ 2,0 (два запроса)

Токены Claude Code измерены с DISABLE_PROMPT_CACHING=1, иначе часть запроса уходит в запись кэша и считается отдельно. Для Sonnet 5.5 один такой запрос в 18 тыс. токенов по цене входа 209,45 ₽ за 1M даёт 18 029 × 209,45 / 1 000 000 = 3,78 ₽. Мы заплатили 3,78 ₽. Та же обвязка при чтении из кэша (10,47 ₽ за 1M) стоила бы около 0,19 ₽: поэтому кэш и важнее размера.

Что убирается и что нет

Те же замеры для Claude Code с разными флагами (первый запрос без кэша, токены из usage):

Конфигурация Токенов в запросе Цена слова «готово», ₽
По умолчанию 18 029 3,78
+ 3 MCP-сервера (filesystem, memory, sequential-thinking) 18 434 3,87
--disable-slash-commands 21 696 4,55
--tools=Bash,Read,Edit 3 359 0,72
--bare 2 282 0,48

Три вывода из этой таблицы:

  1. Ограничение набора инструментов даёт минус 81% токенов первого запроса (--tools=Bash,Read,Edit). Режим --bare по справке claude --help отключает хуки и другие необязательные части и урезает запрос до 2,3 тыс. токенов. Задача с --bare прошла проверку все три раза.
  2. --disable-slash-commands запрос не облегчил, а утяжелил: схемы инструментов выросли с 29,5 до 44,7 КБ. Мы измерили это на 2.1.316 и не проверяли причину. Не выключайте скиллы «для экономии», не проверив на своём агенте.
  3. MCP в Claude Code почти ничего не добавил: в теле запроса остались только имена 24 инструментов, а схемы подгружаются через ToolSearch. В OpenCode такие же три сервера добавили 27 инструментов и подняли первый запрос с 10 507 до 17 402 токенов, то есть на 66%. Для Cline мы MCP не измеряли.

В повторных прогонах основной задачи с включённым кэшем выигрыш скромнее: Claude Code с тремя инструментами — 2,51 ₽ вместо 2,75 ₽, в режиме --bare — 2,12 ₽ и 13,8 с вместо 25,7 с.

Что не удалось измерить честно

usage занижен при попадании в кэш. На POST /api/v1/messages мы отправили три одинаковых запроса с cache_control. Первый вернул cache_creation_input_tokens: 8494, а второй и третий — cache_read_input_tokens: 37, хотя читали из кэша те же 8,5 тыс. токенов; списали при этом 2,23 ₽, 0,014 ₽ и 0,006 ₽. В агентных прогонах Claude Code на втором шаге input_tokens равен сотням при теле запроса в 46–52 КБ. Похожее мы увидели у OpenCode и Cline на тёплом кэше: в первом прогоне usage у OpenCode показывал 62 тыс. токенов, в повторе с тем же размером запросов — 16 тыс. Через Chat Completions и Responses на холодных запросах usage корректен. Поэтому токены за задачу мы оценили по размеру запросов, а цену взяли по балансу.

Codex и MCP. Codex при включённых MCP-серверах прислал 15 инструментов, четыре из них — группы (namespace): три сервера и multi_agent_v1. Мы спросили у самой модели, какие инструменты она видит. anthropic/claude-sonnet-5.5 перечислила 11 — группы до неё не дошли. Тот же набор на openai/gpt-5.4-mini дошёл полностью, включая mcp__filesystem.read_file. Поэтому «+610 токенов от MCP в Codex» в наших замерах означает не дешёвые MCP, а то, что инструменты потерялись по дороге. Если вы запускаете Codex с моделью Claude, проверьте, видит ли она ваши MCP-инструменты.

Доплата 1,05 ₽ за запрос в Codex. Расхождение с ценой токенов у Codex постоянно: 1,0475 ₽ на каждый запрос, ровно столько стоит web_search в каталоге. Мы нашли условие: доплата появляется, когда в запросе одновременно есть web_search и любая группа инструментов; с функциями и web_search по отдельности её нет. За три шага задачи это 3,14 ₽ из 11,52 ₽, то есть 27%. Отключение web_search в Codex проблему не решило: агент перестал выполнять задачу (3 из 3 прогонов не прошли проверку). Мы фиксируем это как наблюдение за конкретной связкой Codex, Responses API и Claude, причину нужно уточнять у RouterAI.

Малая выборка. Три повтора на Sonnet и два на Haiku, одна задача, проект на 42 строки. На большой кодовой базе история диалога вырастет, и доля обвязки упадёт. Разброс в повторах заметный: у Claude Code от 2,62 до 4,19 ₽, у Cline от 3,54 до 5,16 ₽, у OpenCode от 2,41 до 2,55 ₽.

Модель или обвязка

Те же четыре агента на anthropic/claude-haiku-5.5, медиана двух прогонов, все 8 проверок прошли:

Агент Sonnet 5.5, ₽ Haiku 5.5, ₽ Запросов на Haiku Время на Haiku, с
Claude Code 2,75 0,41 3 10,3
Codex 11,52 3,59 3 16,8
Cline 4,24 0,29 3,5 11,1
OpenCode 2,49 0,27 5 17,8

Разница между агентами на Haiku достигает 13 раз (0,27 против 3,59 ₽), на Sonnet — 4,6 раза. Из 3,59 ₽ у Codex 3,14 ₽ приходится на ту самую доплату за web_search, токены стоят около 0,45 ₽. Поэтому Sonnet в OpenCode (2,49 ₽) и в Claude Code (2,75 ₽) обошёлся дешевле, чем Haiku в Codex (3,59 ₽).

Это ровно то, что вы получаете, не глядя на агента. Но обобщать осторожно: дешёвая модель в нашей выборке выигрывает в каждом агенте, а «дорогая в бережливой обвязке дешевле дешёвой в жирной» верно только для пары с Codex, где виновата не размер контекста, а доплата.

Практические выводы

  1. Ограничьте инструменты. В Claude Code это --tools=Bash,Read,Edit или --bare. Для задач без поиска по вебу, подагентов и планировщика остальные инструменты просто лежат в каждом запросе. Проверяйте результат по прокси: например, --disable-slash-commands у нас сделал хуже.
  2. Не подключайте MCP-серверы «на всякий случай». В OpenCode три сервера добавили 27 инструментов и 6,9 тыс. токенов к каждому запросу. У каждого сервера в секции mcp конфига OpenCode есть поле enabled: выключайте то, чем не пользуетесь в этой сессии. Claude Code прячет схемы за ToolSearch, там цена ниже, но имена всё равно уходят в запрос.
  3. Следите за кэшем. Смотрите в usage поле cached_tokens (или cache_read_input_tokens). Claude Code с кэшем стоил 2,75 ₽ против 5,60 ₽ без него, Sonnet 5.5 читает кэш за 10,47 ₽ вместо 209,45 ₽ за 1M. Если у агента cached_tokens всегда ноль, он, скорее всего, не размечает кэш. Но помните: на тёплом кэше usage занижает токены, цену проверяйте по балансу. Как устроено кэширование, описано в глоссарии.
  4. Одна задача — одна сессия. История растёт с каждым шагом: от первого шага к последнему тело запроса выросло у Cline на 62% (7 шагов), у OpenCode на 22% (7 шагов), у Claude Code на 5% (3 шага), у Codex на 8% (3 шага). Число шагов в этих прогонах разное, поэтому цифры сравнивайте осторожно.
  5. Выбирайте агента и модель вместе. Прогоните свою типичную задачу в двух-трёх агентах на одной модели, прежде чем сравнивать модели между собой.

Как заранее оценить бюджет сессии

Для одного запроса:

цена ≈ токены_из_кэша × цена_чтения + новые_токены × цена_входа + выход × цена_выхода

Один раз за сессию к этому добавляется запись префикса в кэш (у Sonnet 5.5 она дороже входа: 261,81 против 209,45 ₽ за 1M). Сессия — сумма по шагам. Практический порядок такой:

  1. Запустите агента на пустой задаче («ответь одним словом») через прокси или посмотрите usage первого запроса: это ваш базовый размер обвязки H.
  2. Прогоните одну типичную задачу и запишите число шагов N и размер запроса на последнем шаге.
  3. Умножьте: без кэша счёт сессии порядка N × (H + средняя история) × цена_входа, с кэшем та же часть H дешевле в 10–20 раз.

После сессии разницу с планом покажет GET https://routerai.ru/api/v1/credits: этот способ описан в статье про Claude Code и используется в статус-баре RouterAI.

Как повторить замеры

Нужны Docker, Node.js 22+ и ключ из личного кабинета. Агенты подключаются к RouterAI по инструкциям: Claude Code, Codex, Cline, OpenCode. Отличается только базовый адрес: он указывает на прокси, а первый сегмент пути (/claude, /codex, /cline, /opencode) прокси отрезает и пересылает остальное на routerai.ru.

npm install -g @anthropic-ai/claude-code@2.1.316 @openai/codex@0.166.0 opencode-ai@1.19.5 cline@3.0.74
export ROUTERAI_API_KEY=sk-xxxxxxxxxxxxxxxx
export MODEL=anthropic/claude-sonnet-5.5

# Claude Code: переменные окружения (их выставляет bench.sh)
#   ANTHROPIC_BASE_URL=http://127.0.0.1:8787/claude/api
#   ANTHROPIC_AUTH_TOKEN=$ROUTERAI_API_KEY   ANTHROPIC_API_KEY=

# Cline: один раз настроить провайдера
cline auth openai -k "$ROUTERAI_API_KEY" -m "$MODEL" -b http://127.0.0.1:8787/cline/api/v1

~/.codex/config.toml для Codex:

model_provider = "routerai"
model = "anthropic/claude-sonnet-5.5"

[model_providers.routerai]
name = "RouterAI"
base_url = "http://127.0.0.1:8787/codex/api/v1"
wire_api = "responses"
supports_websockets = false

[model_providers.routerai.auth]
command = "sh"
args = ["-c", "echo $ROUTERAI_API_KEY"]

~/.config/opencode/opencode.json для OpenCode:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "routerai": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "RouterAI",
      "options": {
        "baseURL": "http://127.0.0.1:8787/opencode/api/v1",
        "apiKey": "{env:ROUTERAI_API_KEY}"
      },
      "models": { "anthropic/claude-sonnet-5.5": { "name": "Sonnet 5.5" } }
    }
  }
}

Прокси proxy.mjs (запуск: LOG_DIR=/work/logs node proxy.mjs; с SAVE_BODY=1 сохраняет тела запросов):

import http from 'node:http';
import https from 'node:https';
import fs from 'node:fs';
const LOG = process.env.LOG_DIR || '/work/logs';
const NL = String.fromCharCode(10);
fs.mkdirSync(LOG, { recursive: true });

function usageOf(text) {
  const u = {};
  const objs = [];
  if (text.trimStart().startsWith('{')) {
    try { objs.push(JSON.parse(text)); } catch {}
  } else {
    for (const l of text.split(NL)) {
      if (!l.startsWith('data:')) continue;
      const s = l.slice(5).trim();
      if (!s || s === '[DONE]') continue;
      try { objs.push(JSON.parse(s)); } catch {}
    }
  }
  u.raw = objs.map(o => o.usage || (o.message && o.message.usage) || (o.response && o.response.usage)).filter(Boolean).pop();
  return u;
}

let CUR = '';
http.createServer((req, res) => {
  if (req.url === '/health') { res.writeHead(200); res.end('ok'); return; }
  if (req.url.startsWith('/_label/')) { CUR = req.url.slice(8); res.writeHead(200); res.end(CUR); return; }
  const chunks = [];
  req.on('data', c => chunks.push(c));
  req.on('end', () => {
    const agent = req.url.split('/')[1];
    const path = req.url.slice(agent.length + 1);
    const label = CUR || agent;
    const body = Buffer.concat(chunks);
    let info = { bodyBytes: body.length };
    try {
      const j = JSON.parse(body.toString());
      const msgs = j.messages || j.input || [];
      const sysMsgs = Array.isArray(msgs) ? msgs.filter(m => m.role === 'system' || m.role === 'developer') : [];
      info = { bodyBytes: body.length, model: j.model, stream: !!j.stream, tools: (j.tools || []).length, toolsBytes: JSON.stringify(j.tools || []).length, sysBytes: JSON.stringify([j.system || '', j.instructions || '', sysMsgs]).length, msgs: Array.isArray(msgs) ? msgs.length : 1 };
    } catch {}
    if (process.env.SAVE_BODY) fs.writeFileSync(`${LOG}/${label}-req-${Date.now()}.json`, body);
    const headers = { ...req.headers, host: 'routerai.ru', 'accept-encoding': 'identity', 'content-length': body.length };
    delete headers.connection;
    const t0 = Date.now();
    const up = https.request({ host: 'routerai.ru', path, method: req.method, headers }, r => {
      res.writeHead(r.statusCode, r.headers);
      r.setEncoding('utf8');
      let text = '';
      r.on('data', c => { text += c; res.write(c); });
      r.on('end', () => {
        res.end();
        const rec = { agent, ts: new Date().toISOString(), path, status: r.statusCode, ms: Date.now() - t0, ...info, usage: usageOf(text) };
        if (r.statusCode !== 200) rec.err = text.slice(0, 300);
        fs.appendFileSync(`${LOG}/${label}.jsonl`, JSON.stringify(rec) + NL);
      });
    });
    up.on('error', e => { res.writeHead(502); res.end(String(e)); });
    up.end(body);
  });
}).listen(8787, '127.0.0.1');

Скрипт прогона bench.sh <агент> <метка>; эталонный проект должен лежать в /work/repo-orig:

#!/usr/bin/env bash
set -u
AGENT=$1; LABEL=$2; shift 2
M=${MODEL:?set MODEL}
PROXY=http://127.0.0.1:8787
PROMPT=${PROMPT:-'В этом Node.js-проекте добавь в invoices.js функцию overdueInvoices(), которая возвращает счета со статусом overdue, экспортируй её и добавь тест в invoices.test.js. Запусти node --test и убедись, что тесты проходят. В конце ответь одной фразой.'}

balance() {
  curl -s -m 10 -H "Authorization: Bearer $ROUTERAI_API_KEY" https://routerai.ru/api/v1/credits |
    python3 -c 'import json,sys; d=json.load(sys.stdin)["data"]; print(d.get("credits", d.get("total_credits", 0)))' 2>/dev/null
}

WORK=/work/runs/$LABEL
rm -rf "$WORK" && mkdir -p "$WORK" && cp -r /work/repo-orig "$WORK/repo" && cd "$WORK/repo" || exit 1
curl -s "$PROXY/_label/$LABEL" > /dev/null
B0=$(balance); B0=${B0:-0}
T0=$(date +%s.%N)
case $AGENT in
  claude)
    ANTHROPIC_BASE_URL=$PROXY/claude/api ANTHROPIC_AUTH_TOKEN=$ROUTERAI_API_KEY ANTHROPIC_API_KEY= \
    ANTHROPIC_DEFAULT_SONNET_MODEL=$M ANTHROPIC_DEFAULT_HAIKU_MODEL=$M ANTHROPIC_DEFAULT_OPUS_MODEL=$M \
    CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 IS_SANDBOX=1 \
    timeout 900 claude -p "$PROMPT" --model "$M" --dangerously-skip-permissions --no-session-persistence \
      --output-format json "$@" > "$WORK/out.txt" 2>&1 ;;
  codex)
    timeout 900 codex exec --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox -m "$M" "$@" "$PROMPT" > "$WORK/out.txt" 2>&1 ;;
  opencode)
    timeout 900 opencode run -m "routerai/$M" --dir "$WORK/repo" "$@" "$PROMPT" > "$WORK/out.txt" 2>&1 ;;
  cline)
    timeout 900 cline -P openai -m "$M" -y -c "$WORK/repo" "$@" "$PROMPT" > "$WORK/out.txt" 2>&1 ;;
esac
T1=$(date +%s.%N)
sleep 3
B1=$(balance); B1=${B1:-0}

PASS=n/a
if [ "${CHECK:-1}" = 1 ]; then PASS=no
if node --test > "$WORK/test.txt" 2>&1 &&
   node -e 'const r=require("./invoices").overdueInvoices(); process.exit(r.length===1&&r[0].id===3?0:1)' 2> /dev/null; then PASS=yes; fi; fi
python3 -c "import json,sys; print(json.dumps({'label':'$LABEL','agent':'$AGENT','seconds':round($T1-$T0,1),'balance_delta':round(float('$B0')-float('$B1'),2),'check':'$PASS'}))" >> /work/logs/_runs.jsonl
tail -n 1 /work/logs/_runs.jsonl

Дополнительные флаги агента передаются третьим аргументом и дальше, например bench.sh claude trimmed --tools=Bash,Read,Edit. Сводка по логам, python3 summary.py <метка>:

import json, sys

for label in sys.argv[1:]:
    rows = [json.loads(l) for l in open(f"/work/logs/{label}.jsonl")]
    rows = [r for r in rows if r.get("status") == 200 and r.get("model")]
    body = sum(r["bodyBytes"] for r in rows)
    harness = sum(r["toolsBytes"] + r["sysBytes"] for r in rows)
    usage = [r["usage"].get("raw") or {} for r in rows]
    prompt = sum(u.get("prompt_tokens", u.get("input_tokens", 0)) for u in usage)
    out = sum(u.get("completion_tokens", u.get("output_tokens", 0)) for u in usage)
    cost = sum(u.get("cost") or 0 for u in usage)
    print(f"{label}: шагов {len(rows)}, тело запросов {body} Б, "
          f"обвязка {harness / body:.0%}, prompt по usage {prompt}, "
          f"выход {out}, cost по usage {cost:.2f} ₽")

Три предостережения при повторе. Во-первых, prompt по usage у агентов с тёплым кэшем занижен, как описано выше: сверяйте с изменением баланса. Во-вторых, замеры нужно делать по очереди, а не параллельно, иначе дельта баланса смешает разные прогоны. В-третьих, эндпоинт /credits изредка отвечает не JSON: в двух наших прогонах дельта вышла абсурдной (около 53 тыс. ₽), мы такие прогоны исключили.

Итог

На одной модели и одной задаче агент менял счёт в 4,6 раза, а на Haiku — в 13 раз. Но объяснение не сводится к «у кого обвязка толще»: у Claude Code она самая тяжёлая, а в повторах он вдвое дешевле Cline, потому что префикс читается из кэша. Практичнее всего оказались три шага: сократить набор инструментов, не держать лишние MCP-серверы и проверять в usage, что кэш действительно срабатывает. Цены, usage и баланс в RouterAI в рублях, работает из России без VPN, поэтому такие замеры можно повторить на своих задачах за вечер.

Все модели из статьи доступны в каталоге RouterAI: оплата в рублях, без VPN. Создайте аккаунт, прогоните скрипт на своей задаче и сравните агентов по реальному счёту.