Настроить cost tracking для агента
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить cost tracking для агента
1. Цель задачи
Научиться внедрять прозрачный учёт затрат (токенов и стоимости) в агентную систему на каждом шаге выполнения. Цель — создать дашборд, отображающий стоимость одной сессии (одного диалога/запроса), а также детализацию по каждому обращению к LLM, инструментам и внешним API. Ключевой результат Работающий дашборд в Grafana (или аналоге) с метрикой cost_per_session и возможностью drill‑down до отдельного шага агента.
2. Исходные данные
Перед началом необходимо иметь:
| Что нужно | Откуда взять |
|---|---|
| Агентная система (любая, с вызовами LLM и инструментов) | Собственный проект (например, LangGraph, CrewAI, AutoGPT) либо готовый код из pet‑проекта |
| API‑ключи для LLM (OpenAI, Anthropic и т. д.) и сторонних сервисов (если есть) | Личный аккаунт / тестовый бюджет |
| Prometheus / Grafana (или альтернатива: VictoriaMetrics + Grafana) | Установить локально или использовать облачный экземпляр |
| Python 3.9+ с библиотеками для сбора метрик | Установка через pip |
| Доступ к логам выполнения агента (хотя бы stdout / stderr) | Запуск агента с логированием |
Если нет реального инструмента — симулируем:
- Создать минимального агента на основе LangChain (или аналогичного фреймворка), который обращается к OpenAI GPT‑4o и вызывает один‑два инструмента (например, Wikipedia API, калькулятор).
- Вставить в код вызовы к Prometheus‑клиенту для регистрации потреблённых токенов и стоимости на каждом шаге.
- Запустить агента 10–20 раз с разными запросами, собрать метрики.
- Развернуть Grafana локально (docker compose) и импортировать готовый дашборд.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык программирования | Python 3.9+ | Разработка интеграции отслеживания |
| LLM API | OpenAI / Anthropic / любая платная модель | Вызовы, по которым считаем токены |
| Прокси для логирования | LangSmith / Weights & Biases / собственный middleware | Захват информации о вызовах |
| Метрики | Prometheus client (prometheus_client) | Экспорт метрик в push‑ или pull‑режиме |
| Визуализация | Grafana | Дашборд cost per session |
| База метрик (опционально) | Prometheus / VictoriaMetrics / InfluxDB | Хранение временных рядов |
| Контейнеризация (рекоменд.) | Docker + Docker Compose | Быстрая настройка Grafana + Prometheus |
4. Этапы выполнения
Этап 1: Подготовка агента и инфраструктуры (оценка времени: 1–2 часа)
Действия
- Создать (или взять готового) агента с вызовами LLM.
- Пример на LangChain: AgentExecutor с tool (например,
WikipediaQueryRun,Calculator), моделью ChatOpenAI(model="gpt-4o", temperature=0). - Убедиться, что агент делает минимум 2–3 шага (вызовы инструментов + повторные запросы к LLM).
- Пример на LangChain: AgentExecutor с tool (например,
- Подготовить docker‑стек для мониторинга
- docker-compose.yml с сервисами: prometheus (pull‑метрики), grafana.
- Пример конфигурации Prometheus (prometheus.yml) с scrape_configs для самого агента (порт 8000).
- Установить prometheus_client в Python (pip install prometheus-client).
- Написать простой HTTP‑сервер (Flask / FastAPI) в агенте для отдачи метрик, либо использовать push‑gateway для разовых сессий. Рекомендую pull‑модель – встроить в агент
start_http_server(8000).
Ожидаемый результат этапа Агент запускается, на порту 8000 отдаёт метрики (пока пустые). Grafana и Prometheus работают, дашборд пуст.
Этап 2: Инструментирование – захват токенов и стоимости на каждом шаге (оценка времени: 2–3 часа)
Действия
- Определить, как получить количество токенов и стоимость.
- Создать декоратор / middleware для каждого шага агента.
- На каждом обращении к LLM:
- Зафиксировать session_id, step_number,
tool_name(если используется инструмент). - Получить prompt_tokens, completion_tokens, cost.
- Увеличить счётчики Prometheus:
llm_calls_total,tokens_total(c labels: session_id, step),cost_total.
- Зафиксировать session_id, step_number,
- Для инструментов (например, Wikipedia API) также считать стоимость, если инструмент платный. Иначе фиксировать только факт вызова.
- На каждом обращении к LLM:
- Обернуть выполнение агента в блок счётчика сессии:
- Перед запуском сессии: создать уникальный session_id (UUID).
- После окончания: записать cost_per_session = sum(cost за все шаги) в гистограмму или summary.
- Проверить корректность
Пример кода (Python, фрагмент):
from prometheus_client import Counter, Gauge, Histogram, start_http_server
import uuid
# Метрики
cost_total = Counter('agent_cost_total', 'Total cost in USD', ['session'])
cost_per_session = Histogram('agent_cost_per_session', 'Cost per session in USD', buckets=(0.01, 0.05, 0.1, 0.5, 1.0))
def run_agent_session(query: str):
session_id = str(uuid.uuid4())
session_cost = 0.0
# Симуляция вызовов
for step in range(3):
# здесь реальный вызов LLM → получаем tokens
prompt_tokens, completion_tokens = 500, 200
step_cost = (prompt_tokens/1000)*5.0/1e6 + (completion_tokens/1000)*15.0/1e6 # упрощённо
session_cost += step_cost
cost_total.labels(session=session_id).inc(step_cost)
cost_per_session.observe(session_cost)
return session_id
start_http_server(8000)
Ожидаемый результат этапа Метрики agent_cost_total и agent_cost_per_session (гистограмма) корректно обновляются. Можно увидеть их через /metrics.
Этап 3: Сбор метрик в Prometheus и настройка дашборда (оценка времени: 1–2 часа)
Действия
- Убедиться, что Prometheus забирает метрики с агента.
- В
prometheus.ymlдобавить- job_name: 'agent'сtargets: ['host.docker.internal:8000'](если агент на хосте, Grafana в докере) илиtargets: ['agent:8000'](в одной сети).
- В
- Запустить несколько сессий агента (5–10 запросов).
- Проверить в Prometheus:
agent_cost_per_session_countдолжна быть >0. - Настроить дашборд в Grafana
- Создать новый дашборд (UID:
cost-tracking-agent). - Панель "Cost per session" – используйте
rate(agent_cost_total[1m])илиhistogram_quantile(0.95, sum(rate(agent_cost_per_session_bucket[5m])) by (le)). - Дополнительно: панель "Total cost over time" (counter).
- Панель "Top sessions by cost" (Grafana variable для session label).
- Создать новый дашборд (UID:
- Добавить переменную
$sessionдля drill‑down до конкретной сессии.
Ожидаемый результат этапа В Grafana отображается дашборд с как минимум одной панелью “Cost per session”. При клике на сессию видны детали по шагам (если настроены лейблы step).
Этап 4: Улучшение – детализация по шагам и инструментам (оценка времени: 1–2 часа)
Действия
- Добавить label
stepиtoolк метрикеcost_total.cost_total.labels(session=session_id, step=step_number, tool=tool_name)
- В дашборде создать таблицу “Cost breakdown per step” с запросом:
sum(agent_cost_total) by (session, step, tool) - Настроить переменную
$stepдля фильтрации. - Добавить панель “Cost per tool” (stacked bar chart).
- Проверить, что все сессии отображаются корректно, нет пропусков.
Ожидаемый результат этапа Дашборд показывает стоимость не только на сессию, но и по каждому шагу/инструменту. Можно видеть, какой инструмент дороже.
Этап 5: Тестирование и документирование (оценка времени: 1 час)
Действия
- Написать тестовый сценарий
- Запустить агента с разными типами запросов (короткие ответы, вызовы инструментов, длинные ответы).
- Убедиться, что стоимость корректно рассчитывается и отображается в дашборде.
- Проверить граничные случаи
- Ошибка API (retry) – не должна задваивать стоимость (использовать idempotent increment).
- Пустой ответ (0 токенов) – счётчик не должен увеличиваться.
- Задокументировать архитектуру
- Описание метрик и labels.
- Скриншот дашборда.
- Инструкция по добавлению нового инструмента/модели.
- Подготовить README к репозиторию
Ожидаемый результат этапа Всё работает стабильно. Документация готова.
5. Критерии приемки (Definition of Done)
- Агент запускается и совершает минимум 2 шага (вызовы LLM и инструментов).
- Собираются метрики
agent_cost_totalс лейбламиsession,step,tool. - Собирается гистограмма
agent_cost_per_sessionдля распределения стоимости сессии. - Prometheus получает метрики (можно проверить через
/metrics). - Grafana дашборд содержит панель “Cost per session” (Histogram или Gauge).
- В дашборде есть возможность drill‑down до конкретной сессии (через label
session). - Стоимость считается корректно (не превышает официальные тарифы модели).
- Обработаны ошибки (retry не дублирует стоимость).
- README с инструкцией по запуску и описание метрик.
- Тестовый прогон с тремя разными запросами – все отображаются в дашборде.
6. Ожидаемый результат
- Главный артефакт Репозиторий с кодом агента, интегрированного с Prometheus метриками, и конфигурацией Docker для Grafana + Prometheus. Внутри – дашборд
cost-tracking-agent.json(экспорт из Grafana). - Содержание дашборда
- Опциональные результаты Скрипт для нагрузочного тестирования, интеграция с Telegram‑уведомлением при превышении бюджета.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| API LLM не возвращает количество токенов | Использовать tiktoken для подсчёта на стороне клиента (приблизительно). Стоимость рассчитывать по числу токенов и тарифу. |
Множество шагов в одной сессии – метка session создаёт много уникальных label | Prometheus не предназначен для label с большим количеством уникальных значений. Использовать summary или histogram для агрегации на стороне клиента, а label session убрать (или оставить только для панели debug). Основную панель строить без разбивки по session. |
| Ошибки при вызове LLM – счётчик может инкрементироваться | Проверять статус ответа. Инкремент только при успешном получении usage данных. |
| Стоимость за один шаг очень мала (доли цента) – гистограмма может не различать | Выбрать подходящие bucket (0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0 USD). |
| Разные модели имеют разные цены | Создать отдельный label model в метрике. Рассчитывать стоимость по своей формуле для каждой модели. |
| Дашборд не обновляется в реальном времени | Убедиться, что scrape_interval в Prometheus ≤ 5s, и агент запущен до старта скрейпа. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| 1. Подготовка агента и инфраструктуры | 1–2 ч |
| 2. Инструментирование – захват токенов и стоимости | 2–3 ч |
| 3. Сбор метрик в Prometheus и настройка дашборда | 1–2 ч |
| 4. Улучшение – детализация по шагам и инструментам | 1–2 ч |
| 5. Тестирование и документирование | 1 ч |
| Итого | 6–10 ч |
Примечание: для первого раза закладывайте 8–10 часов, если вы ранее не работали с Prometheus и Grafana. Значительно ускоряет использование готового docker‑образа и импорт дашборда.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 45 | Как настроить Prometheus для сбора метрик Python-приложения? |
| 78 | Какие библиотеки использовать для подсчёта токенов в LLM? |
| 112 | Структура дашборда Grafana для мониторинга затрат |
| 156 | Как обрабатывать ошибки при вызове LLM без задваивания метрик? |
| 203 | Способы расчёта стоимости вызова различных LLM API (OpenAI, Anthropic, Cohere) |
| 247 | Использование pushgateway против pull-модели в агенте |
| 289 | Гистограммы vs Summary в Prometheus – что выбрать для cost per session? |
| 334 | Как добавить label session_id без перегрузки Prometheus? |
| 401 | Интеграция LangChain с Prometheus (callback handlers) |
| 456 | Автоматическое уведомление в Telegram при превышении бюджета на стоимость |
10. Чек-лист самопроверки
- Я настроил HTTP-сервер для отдачи метрик Prometheus (pull-модель) и он запускается при старте агента.
- Я проверил, что в каждом шаге агента фиксируются токены (prompt + completion) и стоимость (расчёт или из ответа).
- Я создал гистограмму
agent_cost_per_sessionи убедился, что после прогона сессии она обновилась. - Я импортировал дашборд в Grafana и вижу панели “Cost per session”, “Total cost over time” и “Cost breakdown by step”.
- Я протестировал сценарий с ошибкой API и убедился, что стоимость не задваивается (метрика не увеличивается).
- Я задокументировал все метрики и labels в README.