English translation is not available yet. Showing Russian content.

Настроить 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)Запуск агента с логированием

Если нет реального инструмента — симулируем:

  1. Создать минимального агента на основе LangChain (или аналогичного фреймворка), который обращается к OpenAI GPT‑4o и вызывает один‑два инструмента (например, Wikipedia API, калькулятор).
  2. Вставить в код вызовы к Prometheus‑клиенту для регистрации потреблённых токенов и стоимости на каждом шаге.
  3. Запустить агента 10–20 раз с разными запросами, собрать метрики.
  4. Развернуть Grafana локально (docker compose) и импортировать готовый дашборд.

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.9+Разработка интеграции отслеживания
LLM APIOpenAI / 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 часа)

Действия

  1. Создать (или взять готового) агента с вызовами LLM.
    • Пример на LangChain: AgentExecutor с tool (например, WikipediaQueryRun, Calculator), моделью ChatOpenAI(model="gpt-4o", temperature=0).
    • Убедиться, что агент делает минимум 2–3 шага (вызовы инструментов + повторные запросы к LLM).
  2. Подготовить docker‑стек для мониторинга
  3. Установить prometheus_client в Python (pip install prometheus-client).
  4. Написать простой HTTP‑сервер (Flask / FastAPI) в агенте для отдачи метрик, либо использовать push‑gateway для разовых сессий. Рекомендую pull‑модель – встроить в агент start_http_server(8000).

Ожидаемый результат этапа Агент запускается, на порту 8000 отдаёт метрики (пока пустые). Grafana и Prometheus работают, дашборд пуст.

Этап 2: Инструментирование – захват токенов и стоимости на каждом шаге (оценка времени: 2–3 часа)

Действия

  1. Определить, как получить количество токенов и стоимость.
    • Вариант А: Использовать ответ LLM – response.usage.prompt_tokens, response.usage.completion_tokens, а также response.usage.total_tokens.
    • Вариант Б: Если API не возвращает стоимость, рассчитать её по официальной цене за 1k токенов (например, OpenAI GPT‑4o: $5.00 / 1M input, $15.00 / 1M output).
  2. Создать декоратор / 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.
    • Для инструментов (например, Wikipedia API) также считать стоимость, если инструмент платный. Иначе фиксировать только факт вызова.
  3. Обернуть выполнение агента в блок счётчика сессии:
    • Перед запуском сессии: создать уникальный session_id (UUID).
    • После окончания: записать cost_per_session = sum(cost за все шаги) в гистограмму или summary.
  4. Проверить корректность
    • Запустить агента с одним запросом – в логах должны появиться метрики с labels.
    • Выполнить curl http://localhost:8000/metrics | grep cost – увидеть значения.

Пример кода (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 часа)

Действия

  1. Убедиться, что Prometheus забирает метрики с агента.
    • В prometheus.yml добавить - job_name: 'agent' с targets: ['host.docker.internal:8000'] (если агент на хосте, Grafana в докере) или targets: ['agent:8000'] (в одной сети).
  2. Запустить несколько сессий агента (5–10 запросов).
  3. Проверить в Prometheus: agent_cost_per_session_count должна быть >0.
  4. Настроить дашборд в 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).
  5. Добавить переменную $session для drill‑down до конкретной сессии.

Ожидаемый результат этапа В Grafana отображается дашборд с как минимум одной панелью “Cost per session”. При клике на сессию видны детали по шагам (если настроены лейблы step).

Этап 4: Улучшение – детализация по шагам и инструментам (оценка времени: 1–2 часа)

Действия

  1. Добавить label step и tool к метрике cost_total.
    • cost_total.labels(session=session_id, step=step_number, tool=tool_name)
  2. В дашборде создать таблицу “Cost breakdown per step” с запросом:
    sum(agent_cost_total) by (session, step, tool)
    
  3. Настроить переменную $step для фильтрации.
  4. Добавить панель “Cost per tool” (stacked bar chart).
  5. Проверить, что все сессии отображаются корректно, нет пропусков.

Ожидаемый результат этапа Дашборд показывает стоимость не только на сессию, но и по каждому шагу/инструменту. Можно видеть, какой инструмент дороже.

Этап 5: Тестирование и документирование (оценка времени: 1 час)

Действия

  1. Написать тестовый сценарий
    • Запустить агента с разными типами запросов (короткие ответы, вызовы инструментов, длинные ответы).
    • Убедиться, что стоимость корректно рассчитывается и отображается в дашборде.
  2. Проверить граничные случаи
    • Ошибка API (retry) – не должна задваивать стоимость (использовать idempotent increment).
    • Пустой ответ (0 токенов) – счётчик не должен увеличиваться.
  3. Задокументировать архитектуру
    • Описание метрик и labels.
    • Скриншот дашборда.
    • Инструкция по добавлению нового инструмента/модели.
  4. Подготовить 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).
  • Содержание дашборда
    • Панель «Cost per session» (гистограмма, средняя, p95).
    • Панель «Total cost over time» (counter).
    • Панель «Top sessions by cost» (table).
    • Панель «Cost breakdown by step» (table с группировкой).
    • Переменные $session, $tool для фильтрации.
  • Опциональные результаты Скрипт для нагрузочного тестирования, интеграция с Telegram‑уведомлением при превышении бюджета.

7. Возможные сложности и их решение

СложностьРешение
API LLM не возвращает количество токеновИспользовать tiktoken для подсчёта на стороне клиента (приблизительно). Стоимость рассчитывать по числу токенов и тарифу.
Множество шагов в одной сессии – метка session создаёт много уникальных labelPrometheus не предназначен для 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.