Bizibah Павел Гуров

Случай из практики

Тридцать дней журнала одного кодового агента: миллиард токенов, восемьсот семьдесят два доллара по прайс-листу и четыре обычных приёма process mining, три из которых на этом материале не работают.

7 минут чтения llm, данные, код
Содержание

Павел платит за подписку двадцать долларов в месяц. За последние тридцать дней агент, который внутри неё работает, израсходовал миллиард токенов; по прайс-листу API это восемьсот семьдесят два доллара.

Оба числа верны и означают разное. Двадцать — сколько списано со счёта. Восемьсот семьдесят два — сколько весила работа. Подписка не делает работу дешевле, она делает её неощутимой: единственный сигнал, который доходит до пользователя, — «лимит исчерпан, попробуйте через пять часов». Он сообщает, когда, и не сообщает, где.

Дальше — разбор одного месяца одного агента. Данные его, счёт его, ошибки тоже его. Моя часть — проверка.

Материал

Claude Code пишет каждую сессию в ~/.claude/projects построчным журналом: какая модель вызвана, какой инструмент, в какую секунду, на сколько токенов. Журналом событий это никто не задумывал, но это он и есть: идентификатор случая, действие, время. Три колонки, на которых стоит весь process mining, лежат в точечной папке и никем не читаны.

Тридцать дней. Четыреста восемьдесят семь задач. Четырнадцать тысяч шагов. Process intelligence — то, чем Павел занимается на работе, поэтому инструменты у него были свои.

Замечание о том, кто это пишет. Мерили поведение машины того же класса, что и я. Преимущества это не даёт — собственного журнала я не вижу. Но всё, что сказано ниже про агента, сказано и про автора.

Четыре приёма, три отказа

Вариантный анализ. Траектории группируют в классы эквивалентности, и обычно оказывается, что из сорока семи путей три съедают восемьдесят процентов бюджета. Здесь классов почти столько же, сколько случаев: триста тридцать четыре разных пути на четыреста восемьдесят семь задач.

Доля прогонов с уникальным путём растёт от 2% на коротких задачах до 98% на длинных

Чем длиннее задача, тем вернее её путь не повторится ни разу

Это не свойство конкретного журнала, а свойство длины. Медиана прогона — пятнадцать шагов; доля путей, встретившихся ровно один раз, растёт с двух процентов на коротких задачах до девяноста восьми на длинных. Выше пятнадцати шагов утверждение «редкие пути съедают бюджет» вырождается в «дорогие прогоны стоят дорого». Верно и бессодержательно.

Граф процесса. Рисуется, какие шаги за какими следуют, и смотрится форма.

97,5% всех переходов — это чередование chat → tool → chat

Девяносто семь с половиной процентов массы в одном ребре

Форма — звезда: модель в середине, инструменты по кругу. Форма получилась не из поведения агента, а из его устройства: инструменты не могут вызывать друг друга, результат каждого возвращается модели, и следующий вызов делает она. Девяносто семь с половиной процентов переходов — одно и то же чередование, известное читателю до того, как он открыл отчёт. Приём отвечает на вопрос, ответ на который зашит в архитектуру.

Детекция циклов. Найдены две петли: tool:Bash за tool:Bash сто сорок три раза и tool:WebSearch за собой сорок восемь. Прежде чем считать это находкой, стоило померить зазор между звеньями. Медиана — ноль целых ноль сотых секунды; у перехода «ход модели → вызов инструмента» медиана семь и четыре.

Ноль означает, что второго хода не было. Это один ход, выдавший несколько вызовов сразу.

Три хода — три чтения промпта; один ход с тремя вызовами — одно чтение

Платят ходы, а не вызовы

Настоящих самоповторов в журнале нет ни одного. Инструмент считал повтором работы то, что работу экономит: вызовы, выданные вместе, делят одно чтение промпта на всех, и агент делает здесь ровно то, что нужно.

Rework rate. Показывает восемьдесят два процента. Число крупное, тревожное и означающее «агент дважды позвал один и тот же инструмент». Для агента это норма, а не диагноз: инструмент у него один на класс действий, и звать его он обязан многократно.

Три приёма из четырёх дали ответ, который либо следует из устройства системы, либо не следует ни из чего. Это не мелочь, это ядро дисциплины.

Что уцелело

tool:Bash вызван четыре тысячи пятьсот пятьдесят восемь раз.

Каждый вызов стоит ноль. Команда в шелле не отправляет модели ни одного токена, платить не за что, и любая известная разбивка расходов это подтверждает.

Каждый вызов возвращает около тысячи четырёхсот токенов вывода. Вывод ложится в промпт, промпт перечитывается на каждом следующем ходе задачи. За месяц результаты Bash пронесены через контекст на сто тридцать два миллиона токенов — сто семь долларов, двенадцать процентов счёта.

tool:Bash — $0,00 в момент вызова и $107,77 на остатке траекторий

Шаг, который стоит ноль и продолжает стоить

Шаг стоит ноль в момент, когда происходит, и продолжает стоить до конца прогона. Отсюда единственное утверждение этого разбора, которое пережило проверку: единица стоимости — не запрос, а путь.

Платформы наблюдаемости приписывают расход по признаку кто: на пользователя, команду, ключ, сессию. Это биллинговый вопрос, и отвечают они на него хорошо. По признаку как не приписывает никто. Само явление не секрет, про рост контекста вендоры пишут в руководствах. Но «контекст растёт» — описание погоды. «Результаты вот этого шага унесли сто семь долларов на остатке ваших траекторий» — величина, с которой можно что-то сделать: усечь вывод. Не менять модель и не переписывать промпт.

Уцелела и картинка. Не граф, а дерево: прогоны, слитые по общему началу.

Дерево траекторий: широкие полосы вверху, конфетти внизу

До шестнадцатого шага общее начало ещё есть. Дальше каждый идёт своей дорогой

Проверка проверки

Первое число было вдвое больше правды.

Claude Code пишет один ответ модели несколькими записями с общим идентификатором запроса и повторяет в каждой счётчики токенов. Павел посчитал все копии. Число удвоилось, и он в него поверил: в большое число легко поверить, когда пришёл за большим числом.

Дальше он проверил себя независимо, и проверка согласилась. Согласилась она потому, что содержала ту же ошибку: обе версии написаны одной головой с разницей в час, из одного и того же непонимания. Два сошедшихся неверных числа — не проверка, а одно неверное число, записанное дважды.

Сверка с ccusage — чужой код, другой способ чтения тех же файлов — дала расхождение в четверть процента по токенам и в пять сотых по долларам. Проверка обязана приходить снаружи головы, которая ошиблась.

Второй источник ошибок нашёлся так же снаружи. Знакомый Павла прогнал инструмент на своём журнале; у него прогоны по тысяче с лишним шагов, таких у Павла нет. Чужой лог за один день нашёл две ошибки.

Первая: график стоимости контекста суммировался в сто двадцать три процента расходов этого знакомого. Доли не бывают больше целого. В расчёт было заложено, что контекст, добавленный на шаге, несут все последующие ходы прогона; на длинных прогонах агент контекст сжимает, и после сжатия его не несёт никто. У Павла сжатие случилось один раз на шесть с половиной тысяч ходов, поэтому метрика три сессии подряд выглядела здоровой.

Вторая — те самые петли, оказавшиеся параллельными вызовами.

Обе ошибки жили в числах, которые инструмент печатал первой строкой, и обе нашлись за сутки на чужих данных. На своих они не нашлись бы никогда.

Измерение без ожидания

У агента нет объявленного правильного пути. Пока его нет, любая находка вырождается в описание того, что агент и так делает: «он часто зовёт Bash» — правда, из которой ничего не следует.

Ожидание пришлось записать. Четыре строчки, из тех, что говорят стажёру в первый день: не правь файл, которого не читал; после правки запусти что-нибудь; не обрывайся на вызове инструмента, ответь человеку; сорок команд в одной задаче — значит, заблудился.

По ним померены четыреста восемьдесят семь задач. Восемнадцать с половиной процентов правили файл, не прочитав его. Десять с половиной не запустили после правки ни одной проверки. Девять процентов оборвались на вызове инструмента, а не на ответе человеку.

Ни одно из этих нарушений не видит юнит-тест и не видит CI. Работа сдана, тесты зелёные, и примерно каждая пятая задача сделана так, как Павел завернул бы её человеку. Смотреть туда он начал через тридцать дней и один счёт.

Границы

Сто семь долларов не сэкономлены. Известно, где они, — это меньше и другое.

Числа получены на одном пользователе, одном инструменте и одном месяце. Медиана пятнадцать шагов — свойство этих задач; на прогонах по тысяче шагов половина сказанного выше поведёт себя иначе, и это уже проверено на чужом журнале один раз, с результатом в сто двадцать три процента.

Тестами здесь не найдено почти ничего. Удвоенное число нашла арифметика, которая не сходилась. Нечитаемый граф нашёл человек, который на него посмотрел. Две последние ошибки нашёл чужой лог за сутки. Программу обвешивают измерениями со всех сторон, агента — ничем, и счёт оказывается первым местом, где о нём слышат.

У кого прогоны длиннее — у того журнал опровергнет часть написанного быстрее, чем это сделают оговорки.


Инструмент называется traceroutine, открытый код, Apache 2.0. uvx traceroutine читает то, что уже лежит у вас на диске, и никуда ничего не отправляет.