Как фронтендер из Bay Area, который почти не пишет код руками, сделал на Rust трекер расходов для ИИ-агентов — и зачем
Дисклеймер
Я фронтенд-разработчик. Работаю в Bay Area, в компании, которая выдаёт всем инженерам корпоративные подписки на Claude Code и Cursor. То есть лично из кармана я за токены не плачу — счёт уходит работодателю. Это важная деталь, потому что без неё дальше непонятно: зачем человеку, который ни копейки не тратит, было пилить три месяца open-source инструмент для подсчёта чужих денег.
Если коротко — стало любопытно.
Если чуть длиннее — из этого любопытства выросла целая экосистема репозиториев, два пивота, один выкинутый в мусорку RAG-движок, плагин для JetBrains на Kotlin, расширение для VS Code на TypeScript и Rust-демон, который я бы сам, без ИИ, не написал никогда в жизни.
Это статья про то, как и зачем я всё это сделал. И почему фронтендер, который последний год почти не пишет код руками, всё равно может зашипить вполне серьёзный системный инструмент — если правильно выстроить процесс.
Откуда вообще взялся вопрос
Поздней осенью прошлого года я заметил, что мой рабочий день изменился. Раньше я открывал VS Code, читал тикет, гуглил, писал код, отлаживал, ревьюил. Теперь я формулирую задачи для Claude Code, читаю его диффы, тыкаю в Cursor с вопросом «почему это не работает», и иногда — да, иногда — всё ещё открываю файл и правлю руками. Но это уже исключение.
Меня это устраивает. Скорость выросла, рутина исчезла, голова занята проектными решениями, а не точкой с запятой. Но в какой-то момент я открыл /cost в Claude Code, увидел свою сессию и подумал: «А сколько я вообще трачу-то?»
Claude Code показывает текущую сессию. Всё. Никакой истории. Никакой разбивки по репозиториям. Никакого ответа на вопрос «сколько денег ушло на этот тикет».
Cursor показывает чуть больше, но в своём кабинете, и тоже без привязки к тому, что я реально делал.
И тут меня зацепило. Я работаю с несколькими репозиториями одновременно: основной продукт, пара побочных проектов, экспериментальные ветки. Какой из них съедает больше всего токенов? Какой тикет оказался самым «дорогим»? Сколько Opus я случайно сжёг там, где спокойно хватило бы Sonnet? Эти вопросы интересны не потому, что я хочу сэкономить — повторюсь, плачу не я. Они интересны потому, что без ответов я не понимаю, как именно я использую инструмент, который занимает 80% моего рабочего времени.
В индустрии это называется громко — «наблюдаемость». В моей голове это было проще: «хочу видеть, куда уходит».
Первая попытка: оптимизатор, который ничего не оптимизировал
Изначально я хотел сделать оптимизатор стоимости. План был наивным и красивым: написать прослойку, которая будет смотреть на каждый промпт перед отправкой и решать, можно ли сделать его дешевле — выкинуть лишний контекст, переключить модель, что-то закешировать.
Я начал писать. Через пару недель упёрся в очевидное: невозможно оптимизировать то, чего ты не видишь. У меня не было базовой картины — сколько уходит сейчас, на что именно, в каких разрезах. Я пытался оптимизировать чёрный ящик, причём не глядя в него.
Это был первый пивот. Я сказал себе: окей, забудем про оптимизацию. Сначала сделаем видимость. Просто покажем, куда идут токены. А оптимизация — потом, если получится.
Так появилось имя — budi. Это была шутка про «buddy», приятель-помощник, который сидит рядом и говорит, на что ты тратишь деньги. Имя прижилось.
Почему Rust, если я фронтендер
Под капотом budi — Rust. Демон в реальном времени следит за транскриптами ИИ-агентов, парсит JSONL-файлы, обогащает каждое сообщение git-контекстом и пишет в локальный SQLite. Латентность на хуках — меньше миллисекунды.
Если бы вы спросили меня в 2023 году, могу ли я написать такое — я бы засмеялся. Я знаю TypeScript, React, немного Node.js. Никакого Rust, никаких системных языков, никакого опыта с файл-вотчерами и асинхронными рантаймами.
Но в 2026 году ограничение «я не умею писать на X» работает иначе. Я выбрал Rust по двум причинам: во-первых, демон должен быть лёгким — никто не захочет постоянно держать в памяти процесс на 200 МБ; во-вторых, мне было интересно проверить, насколько далеко можно зайти, если язык выбирает не разработчик, а задача.
Claude Code писал большую часть Rust-кода. Я писал требования, дизайн, архитектуру, ревьюил каждый PR, тыкал палочкой в места, где модель выдавала непонятные мне идиомы, и заставлял её объяснять. По факту я выучил Rust в процессе написания на нём продакшен-инструмента. Не идеальный путь обучения, но рабочий.
Эксперимент с RAG, который пришлось убить
Прежде чем я пришёл к нынешней архитектуре, у меня было ещё одно ответвление, на которое я угрохал несколько недель — RAG-движок для Claude Code.
Идея звучала красиво. Перед каждым промптом в Claude Code хук молча подмешивает релевантный контекст из репозитория. Tree-sitter парсит код в AST. Векторный поиск находит подходящие куски. Cross-encoder делает реранкинг. Всё это на Rust, быстро, локально. Меньше походов модели за файлами — меньше токенов — меньше денег.
Я даже довёл это до рабочего состояния. И собственный аналитический модуль budi (которого тогда ещё не было целиком, но базовые метрики уже считались) показал мне жестокую правду.
49% промптов получали инъекции контекста. Всего 2% этих инъекций были подтверждены — то есть Claude реально использовал то, что я ему подсунул. Остальные 47% — это были токены, которые я тратил на вброс контекста, который модель проигнорировала и пошла читать файлы сама.
Оптимизатор, который не оптимизирует. Инструмент, который не доказывает свою пользу. И главное — пользователь даже не видит, что эта штука вообще что-то делает.
Я выкинул весь RAG-движок. Оставил только хуки, базу и парсинг. Это был второй пивот — обратно к простой идее «просто покажем, куда идут токены». Самое ироничное: решение развернуться я принял по данным, которые собрал мой же аналитический модуль. Иногда лучшая фича — та, которую ты выпилил.
Что в итоге
Сейчас budi выглядит так.
Демон сидит на 127.0.0.1:7878. Он смотрит, куда Claude Code, Codex CLI, Cursor, Copilot CLI и Copilot Chat (VS Code, JetBrains) сами пишут свои транскрипты. Это обычные JSONL-файлы на диске, которые агенты ведут для себя — никаких хаков, никакого перехвата трафика, никакого проксирования API. Файлы уже там, я их просто читаю.
Каждое сообщение обогащается: активная ветка git, репозиторий, тикет (вытащенный из имени ветки JIRA-1234-fix-something); пути к файлам, к которым агент обращался через инструменты; классификация сессии (багфикс, рефакторинг, фича, ревью); разбивка по моделям (Opus / Sonnet / Haiku и аналоги у Codex / Cursor); разделение токенов на input / output / cache / thinking; стоимость по актуальному прайс-листу LiteLLM.
Всё это попадает в локальный SQLite. CLI — это просто HTTP-клиент к демону, который никогда не лезет в базу напрямую. На моих ~1.1 ГБ транскриптов и ~$9000 накопленных расходов запрос полной истории занимает 40 мс при пиковом потреблении 11 МБ памяти. Я специально сравнивал с ccusage — отличным инструментом от другого автора, который меня и вдохновил, но работает stateless и потому на тех же данных тратит 740 мс и 322 МБ.
Что вы получаете:
budi status — сегодняшние расходы и здоровье демона
budi stats projects — репозитории, отсортированные по тратам
budi stats branches — ветки по тратам
budi stats tickets — тикеты по тратам, моё любимое
budi stats files — файлы, которые «дороже» всего трогать
budi stats models — разбивка по моделям
budi sessions latest — детали последней сессии + vitals
Плюс статус-лайн прямо в Claude Code, Cursor и JetBrains. В нижнем правом углу IDE висит маленькая строчка: budi · $2.34 1d · $12.50 7d · $48.10 30d.
Накопительные суммы за день, неделю и месяц. Не календарный сброс в полночь — именно скользящее окно. Когда я вижу там $80 за день — это сигнал, что я делаю что-то странное, и стоит остановиться и подумать. Эту строку можно настроить под любые слоты — сессия, последнее сообщение, ветка, проект, провайдер.
Экосистема — почему один репо превратился в шесть
Когда я начинал, всё было одним репозиторием на GitHub. Чем больше budi обрастал интеграциями, тем сильнее рос репозиторий, тем нервнее становились релизы и медленнее — CI. Поэтому я разнёс всё по отдельным репозиториям, по принципу «одна аудитория — один артефакт»:
budi (github.com/siropkin/budi) — ядро. Rust-демон и CLI. То самое, что вы ставите через brew install. Здесь живёт пайплайн ингеста, схема базы, аналитика, статус-лайн и API. Это сердце продукта.
budi-cloud (github.com/siropkin/budi-cloud) — облачный дашборд на app.getbudi.dev. Next.js 16, React 19, Supabase, Tailwind. Команды могут видеть общую картину расходов по людям, репозиториям, моделям. Важно: туда уходят только агрегаты — числовые метрики, идентификаторы веток, хеши репозиториев. Никогда не уходят промпты, код или ответы ИИ. Никогда. Это не маркетинговая фраза, это структурно невозможно — в коде синка просто нет полей для этих данных.
budi-cursor (github.com/siropkin/budi-cursor) — расширение для VS Code и Cursor. TypeScript. Тот самый виджет в статус-баре, но в редакторе. Опубликовано в VS Marketplace и Open VSX.
budi-jetbrains (github.com/siropkin/budi-jetbrains) — плагин для JetBrains IDE. Kotlin. Опубликован в JetBrains Marketplace. Для меня это был отдельный экзистенциальный опыт — Kotlin я знаю на уровне «видел в чужих PR», но Claude Code и здесь вытащил.
homebrew-budi (github.com/siropkin/homebrew-budi) — Homebrew tap. Просто формулы. Без него brew install siropkin/budi/budi не работает.
getbudi.dev (github.com/siropkin/getbudi.dev) — лендинг. Next.js. Лицо проекта, документация, ссылки на установку.
Все шесть репозиториев написаны мной в паре с Claude Code. Если посмотреть на git log — в коммитах сотни упоминаний «Co-Authored-By: Claude». Это не маркетинговый трюк, это честная атрибуция. Без ИИ я бы вытащил один репозиторий — может быть, два. Шесть — нет.
Что я понял про работу с ИИ-агентами на этом проекте
Самое сильное наблюдение — с ИИ-агентом нужно выстраивать процесс, а не просто кидать ему задачи. Когда я работал в режиме «напиши мне модуль для X» — получалась куча несогласованного кода, который через неделю было больно поддерживать. Когда переключился на режим «вот SOUL.md проекта, вот его архитектура, вот контракт данных, реализуй задачу в этих рамках» — начали получаться нормальные модули.
В репозитории budi сейчас лежит файл SOUL.md — единый источник правды для агента и людей. Архитектура, поток данных, контракт атрибуции, схема релизов, что нельзя трогать. Claude Code в первую очередь читает его. И уже после этого открывает любой код.
Второе наблюдение — данные о собственной работе с ИИ сильно меняют решения. Я выкинул RAG не потому, что мне разонравилась идея, а потому что цифры показали, что она не работает. Без этих цифр я бы шлифовал RAG ещё месяца три и в итоге всё равно пришёл бы к тому же ответу — только позже и дороже.
Это, кстати, отдельная мета-петля: я делал инструмент для измерения работы с ИИ, гонял его на самом себе, и его же данные меняли продукт, который я им и измерял. Когда я впервые это заметил, стало немного не по себе.
Третье — про «не плачу из своего кармана». Изначально я так и думал, но оказалось неточно. Когда видишь, что один тикет съел $80 в Opus, а другой такой же — $12 в Sonnet, разница в твоих привычках сразу бросается в глаза. Я перестал по умолчанию запускать Opus на простые задачи. Не потому, что меня кто-то заставил — а потому, что просто увидел разницу. Видимость меняет поведение, даже если деньги не твои.
Куда оно идёт
Сейчас в budi 6 поддерживаемых агентов, в роадмапе — Gemini CLI, Amp и Goose. В облаке уже есть команды и разрезы по пользователям, и я потихоньку добавляю инсайты — не просто «вы потратили $X», а «вы тратите 40% на репозиторий Y, и половина из этого — Opus там, где справился бы Sonnet».
Параллельно с фичами я учусь продукту. И это, наверное, отдельная статья — фронтенд-разработчик, который умеет делать инструменты, но не умеет их продавать. Я смотрю на open-source-метрики (звёзды, скачивания, упоминания) и пытаюсь понять, где у меня не хватает того, что в индустрии называется storytelling. Я бы написал ещё про это, но сначала надо набить шишек.
Если хочется попробовать
Дальше пользуйтесь Claude Code, Cursor, Codex как обычно — budi сам найдёт их транскрипты и начнёт считать. Через минуту запустите budi stats и увидите свою картину. Если у вас уже есть месяцы истории — budi db import импортирует всё за один проход.
Никаких аккаунтов, никаких подписок, MIT-лицензия, 100% локально по умолчанию. Облако — опционально и только агрегаты.
GitHub: github.com/siropkin/budi — Сайт: getbudi.dev
Спасибо, что дочитали. Если вы тоже фронтендер, который последний год почти не пишет код руками — мне будет интересно услышать, какие у вас вопросы про собственные расходы. И если вы их тоже не задавали — попробуйте, это неожиданно отрезвляюще.