Пульс твоих ИИ-агентов. Одно место, где видно, что происходит с агентами: сколько они едят, живы ли, принимают ли запросы, есть ли проблемы.
Продукт-хаб, не привязанный к конкретному вендору: сегодня это Claude Code, завтра — любые другие агенты (OpenAI и т.д.).
Ранняя стадия. Начинаем с простого — расход токенов Claude Code. Это первая «витал-метрика».
- Модуль «Токены»
- Нативное macOS-приложение (
app/) — открыл по иконке, посмотрел, закрыл. Вкладка «Обзор», выбор периода, живое обновление. - Стоимость инструментов — эксперимент за фичефлагом, выключен по умолчанию.
- Счетчик в меню-баре — сегодняшний расход без открытия окна.
- Вкладки «Все сессии» и «Таймлайн» в приложении.
- Модуль «Здоровье» — доступность агентов (Claude / OpenAI / …): принимают ли запросы, латентность, инциденты, аптайм.
agent-heart/
app/ # нативное macOS-приложение (SwiftUI)
Sources/AgentHeart/
Core/ # чтение транскриптов, кеш, агрегация, прайсы
UI/ # вкладка «Обзор», график, таблицы
make-app.sh # сборка agent-heart.app
analyzer/cc_dashboard.py # HTML-дашборд: 3 вкладки, независимая проверка цифр
shared/prices.json # ОБЩИЙ прайс-лист — читают и app, и analyzer
Сгенерированный dashboard.html в репозиторий не попадает: он содержит
названия сессий (то есть формулировки твоих задач), пути к проектам и суммы
расхода. То же касается папки swarm-report/. Обе позиции в .gitignore.
Собрать и положить в app/build/:
./app/make-app.shСобрать сразу в «Программы»:
./app/make-app.sh /ApplicationsНужен Xcode (Swift 6). Зависимостей нет. Подпись ad-hoc — для своей машины этого достаточно; нотаризация понадобится, только если раздавать приложение другим.
- Вкладка «Обзор» — KPI, разбор входа по типам токенов, расход по дням, разбивка по проектам / моделям / главному циклу против сабагентов.
- Периоды — сегодня, 7 дней, 30 дней, этот месяц, все время, произвольный диапазон. Переключение мгновенное: все вызовы держатся в памяти, пересчет не читает файлы заново.
- Шаг разбивки подстраивается под период: сегодня — по часам, 7/30 дней и месяц — по дням, все время — по месяцам. Для произвольного диапазона по его длине: до двух суток часы, до квартала дни, дальше месяцы. Меняются и график, и таблица под ним.
- Настройки (
⌘,) — выключатели для того, что вкусовщина: значки сравнения с предыдущим периодом на плитках и подпись со средним над графиком. - Стоимость инструментов — эксперимент, выключен по умолчанию
(
Настройки → Эксперименты). Держится за флагом сознательно: это оценка по косвенным данным, а не измерение, и смотреть на нее постоянно тяжело — включай, когда разбираешься с расходом предметно. Подробности ниже. - Живое обновление — FSEvents следит за
~/.claude/projects, цифры двигаются сами, пока ты работаешь. В простое CPU не тратится. - Сравнение с предыдущим периодом на плитках. Если предыдущий период начинается раньше самых первых данных, дельта не показывается — там «пусто» означает «учета еще не было», и рост был бы враньем.
- Проваливание вглубь — клик по проекту открывает его карточку со списком
сессий за тот же период, клик по сессии — что в ней происходило: разбивка по
инструментам (Bash, Edit, Read, MCP…), ход по часам, модели, сабагенты.
Возврат — кнопкой «назад» или
⌘[. - Названия сессий берутся из транскриптов: заданное руками важнее автоматического, автоматическое важнее первого промпта. Источник помечен значком у названия.
- Группировка по проектам — рабочие директории поднимаются до корня
git-репозитория, регистр схлопывается. Запуски из
agent-heart/appиagent-heart/analyzerпопадают в одну строку, аvoicyиVoicyне двоятся.
Прямой цены у инструмента нет — платят только за токены. Но результат вызова оседает в контексте и перечитывается на каждом последующем запросе сессии. Поэтому настоящая стоимость это:
размер результата × (запись в кеш + число перечитываний × цена cache read)
Отсюда два независимых множителя: насколько велик результат и насколько рано в сессии он появился. Второй обычно важнее — один и тот же вызов в сессии на 500+ ходов обходится вчетверо дороже, чем в короткой.
Три секции в «Обзоре»:
- во что обошлись инструменты — с колонкой
$/вызов; - самые дорогие отдельные вызовы — с проваливанием в сессию. Решения принимаются по выбросам, а не по средним: медианный результат ~300 токенов, а верхний процент вызовов дает около четверти всех денег;
- стоимость и длина сессии — проверка тезиса «длинные сессии дороже» на собственных данных.
Это оценка, а не бухгалтерия. Размер результата в транскрипте не записан и выводится из прироста контекста между соседними вызовами. Доля оцененных вызовов и причины пропусков показаны прямо под таблицей (сейчас ~81%; не попадают вызовы сабагентов — у них свой контекст, последние ходы сессий и случаи, где контекст не вырос). Компактизация контекста не учитывается, поэтому длинные сессии скорее завышены.
# сверить движок с Python-анализатором (должны совпасть до последней цифры)
./app/build/agent-heart.app/Contents/MacOS/agent-heart --selftest
# отрендерить «Обзор» в PNG без открытия окна
./app/build/agent-heart.app/Contents/MacOS/agent-heart \
--snapshot /tmp/overview.png --range last30
# то же, но с секциями стоимости инструментов независимо от настройки
# (голый бинарник запускается без Info.plist и читает не тот домен
# UserDefaults, что бандл, — поэтому нужен явный флаг)
./app/build/agent-heart.app/Contents/MacOS/agent-heart \
--snapshot /tmp/overview.png --range last30 --tool-costs
# подробный лог сканирования в stderr
AGENT_HEART_DEBUG=1 ./app/build/agent-heart.app/Contents/MacOS/agent-heartСкорость на 325 файлах / 250 МБ транскриптов: холодный разбор ~1.5 с,
дальше инкрементально ~20 мс (кеш в ~/Library/Caches/AgentHeart/).
Остается как независимая проверка цифр и как источник вкладок, которых пока нет в приложении.
python3 analyzer/cc_dashboard.py # собрать dashboard.html и открыть
python3 analyzer/cc_dashboard.py --serve # http://127.0.0.1:8899Прочие флаги: --no-open, --since 2026-07-20, --until 2026-08-01,
--out путь.html. Зависимостей нет — только стандартная библиотека Python 3.
--selftestсравнивает «сырую» группировку поcwd, без схлопывания подпапок в репозитории. Поэтому число проектов там совпадает с Python, а в окне приложения оно меньше — это не расхождение, а более умная группировка.
shared/prices.json — единственный источник цен, его читают оба модуля.
Не дублируй цифры в коде: разъедутся. Формат — USD за 1 млн токенов, ключ
матчится подстрокой в идентификаторе модели (claude-opus-4-5-2025… →
opus-4-5), при нескольких совпадениях выигрывает самый длинный ключ.
MIT — см. LICENSE. Бери, форкай, переделывай.
Читает локальные транскрипты Claude Code из ~/.claude/projects/**/*.jsonl.
Никуда ничего не отправляет, все считается на машине.
Стоимость — оценка по прайс-листу Claude API (не выставленный счет; на подписке Max/Pro это эквивалент «во сколько обошлось бы через API»).
Совет: в
~/.claude/settings.jsonстоитcleanupPeriodDays: 3650, чтобы старые сессии не удалялись авто-очисткой (дефолт — 30 дней).