Моніторинг витрат агентів

Моніторинг витрат показує використання токенів і витрати на API.
На цій сторінці
  1. Ідея за 30 секунд
  2. Основна проблема
  3. Як це працює
  4. Типові production-метрики витрат
  5. Як читати cost-layer
  6. Коли використовувати
  7. Приклад реалізації
  8. Investigation
  9. Типові помилки
  10. Є тільки загальна сума витрат за день
  11. Рахуються тільки токени, але ігнорується вартість tools
  12. Немає розбиття за release і model
  13. Висококардинальні labels
  14. Немає алертів на burn rate і cost_p95
  15. Самоперевірка
  16. FAQ
  17. Пов'язані сторінки

Ідея за 30 секунд

Моніторинг витрат для AI-агентів показує не тільки загальну суму витрат, а й те, де саме вони зростають: у токенах LLM, зовнішніх API і повторних кроках агента.

Без цього легко пропустити момент, коли система ще "працює", але вже стає занадто дорогою для production.

Основна проблема

Один run може завершитися успішно, але коштувати в 2-3 рази дорожче, ніж зазвичай.

Два запити з однаковою фінальною відповіддю можуть мати різну собівартість: через додаткові reasoning-кроки, retries або зайві виклики tools. Без cost monitoring це зазвичай видно тільки після перевищення бюджету.

Далі розберемо, як читати ці сигнали і знаходити, що саме робить run дорогим.

У production це часто виглядає так:

  • токени ростуть хвилями після релізу;
  • один tool непомітно починає споживати більшу частину бюджету;
  • retries збільшують витрати навіть без зростання трафіку;
  • команда бачить проблему вже після вибуху бюджету.

Саме тому cost-layer варто моніторити окремо, а не лише через загальні run-метрики.

Як це працює

Моніторинг витрат будується навколо двох типів сигналів:

  • usage signals (prompt_tokens, completion_tokens, tool_calls, retries);
  • cost signals (llm_cost_usd, tool_cost_usd, total_cost_per_run).

Ці метрики відповідають на питання «де і чому дорожчає система в часі». Логи й трейсинг потрібні, щоб пояснити конкретний дорогий run.

Витрати ростуть не тільки через обсяг трафіку, а й через поведінку агента. Usage ≠ cost. Агент може виконати ту саму задачу з тим самим результатом, але коштувати в рази дорожче через retries, довші reasoning-ланцюги або дорогі tools.

Типові production-метрики витрат

МетрикаЩо показуєНавіщо потрібна
token_usage_per_runскільки токенів витрачає один runбазовий контроль LLM-споживання
llm_cost_per_runвартість LLM на один runпорівняння моделей і prompt-стратегій
tool_cost_per_runвартість зовнішніх API/tools на runпошук дорогих інструментів
total_cost_per_runзагальна вартість runконтроль собівартості відповіді
cost_p95«довгий хвіст» дорогих runраннє виявлення дорогих аномалій
budget_burn_rateшвидкість витрачання бюджетупрогноз перевищення бюджету
cost_per_1k_runsскільки коштують 1000 runпорівняння стабільності між релізами

budget_burn_rate зазвичай рахується на рівні дашборду (витрати за одиницю часу), а не як окремий counter у runtime-коді.

Щоб метрики були практичними, їх зазвичай сегментують за release, model, tool і типом запиту.

Важливо: не додавай у labels висококардинальні поля (run_id, request_id, user_id), інакше сховище метрик швидко перевантажиться.

Як читати cost-layer

Що споживається → як агент поводиться → скільки це реально коштує. Це три рівні, які завжди потрібно дивитися разом.

Важливо дивитися на тренди у часі і різницю між релізами, а не на одиничні значення.

Далі дивимось на комбінації сигналів:

  • token_usage_per_run ↑ + llm_cost_per_run ↑ → агент витрачає більше токенів на один run;
  • tool_cost_per_run ↑ + total_cost_per_run ↑ → over-tooling або дорогий tool-path;
  • llm_cost_per_run ↑ + tool_cost_per_run ≈ стабільний → проблема в prompt або reasoning, не в tools;
  • budget_burn_rate ↑ + run_count ≈ стабільний → регресія собівартості;
  • cost_p95 ↑ + budget_burn_rate ↑ → дорогі аномальні run починають прискорювати витрати.

Коли використовувати

Повний cost monitoring не завжди потрібен.

Для простого прототипу інколи достатньо базового token_usage і ліміту на денні витрати.

Але детальний моніторинг витрат стає критичним, коли:

  • система вже в production і має бюджетні обмеження;
  • агент використовує кілька tools із платними API;
  • релізи виходять часто й важливо бачити регресії витрат;
  • потрібно масштабувати трафік без втрати керованості бюджету.

Приклад реалізації

Нижче — спрощений приклад інструментації cost metrics у стилі Prometheus. Приклад показує базовий контроль вартості LLM, tools і загальної ціни run.

PYTHON
import time
from prometheus_client import Counter, Histogram

RUN_TOTAL = Counter(
    "agent_run_total",
    "Total number of agent runs",
    ["status", "stop_reason", "release"],
)

LLM_COST_USD_TOTAL = Counter(
    "agent_llm_cost_usd_total",
    "Total LLM cost in USD",
    ["model", "release"],
)

TOOL_COST_USD_TOTAL = Counter(
    "agent_tool_cost_usd_total",
    "Total tool/API cost in USD",
    ["tool", "release"],
)

TOKEN_USAGE_TOTAL = Counter(
    "agent_token_usage_total",
    "Total LLM tokens",
    ["model", "token_type", "release"],
)

RUN_COST_USD = Histogram(
    "agent_run_cost_usd",
    "Cost per run in USD",
    ["release"],
    buckets=(0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3),
)

BUDGET_BREACH_TOTAL = Counter(
    "agent_budget_breach_total",
    "Total runs that crossed cost budget",
    ["release"],
)

LLM_PRICING = {
    # WARNING: приклад тарифу (може бути неактуальним).
    # У production ці значення потрібно брати з конфігурації або API провайдера.
    "gpt-4.1": {
        "prompt": 0.0000015,
        "completion": 0.0000020,
    }
}


def estimate_llm_cost_usd(model, prompt_tokens, completion_tokens):
    # WARNING: replace with actual provider pricing
    pricing = LLM_PRICING.get(model)
    if not pricing:
        # WARNING: unknown model — cost will be reported as 0 (underestimated)
        return 0.0
    prompt_cost = prompt_tokens * pricing.get("prompt", 0)
    completion_cost = completion_tokens * pricing.get("completion", 0)
    return prompt_cost + completion_cost


def run_agent(agent, task, budget_limit_usd=0.25, release="2026-03-21"):
    run_status = "ok"
    stop_reason = "max_steps"
    run_cost_usd = 0.0

    try:
        for step in agent.iter(task):
            step_type = step.type
            try:
                result = step.execute()
            except Exception as error:
                run_status = "error"

                if step_type == "tool_call":
                    stop_reason = "tool_error"
                elif step_type == "llm_generate":
                    stop_reason = "llm_error"
                else:
                    stop_reason = "step_error"

                raise

            if step_type == "llm_generate":
                model = getattr(step, "model", "unknown")
                usage = getattr(result, "token_usage", {}) or {}
                prompt_tokens = usage.get("prompt_tokens", 0)
                completion_tokens = usage.get("completion_tokens", 0)

                TOKEN_USAGE_TOTAL.labels(model=model, token_type="prompt", release=release).inc(
                    prompt_tokens
                )
                TOKEN_USAGE_TOTAL.labels(
                    model=model, token_type="completion", release=release
                ).inc(completion_tokens)

                llm_cost = estimate_llm_cost_usd(model, prompt_tokens, completion_tokens)
                run_cost_usd += llm_cost
                LLM_COST_USD_TOTAL.labels(model=model, release=release).inc(llm_cost)

            if step_type == "tool_call":
                tool_name = getattr(step, "tool_name", "unknown")
                tool_cost = float(getattr(result, "cost_usd", 0.0) or 0.0)
                run_cost_usd += tool_cost
                TOOL_COST_USD_TOTAL.labels(tool=tool_name, release=release).inc(tool_cost)

            if result and result.is_final:
                stop_reason = "completed"
                break
    finally:
        RUN_COST_USD.labels(release=release).observe(run_cost_usd)
        if run_cost_usd > budget_limit_usd:
            BUDGET_BREACH_TOTAL.labels(release=release).inc()
        RUN_TOTAL.labels(status=run_status, stop_reason=stop_reason, release=release).inc()

# cost_per_1k_runs зазвичай рахується на рівні дашборду:
# (sum(agent_run_cost_usd) / run_count) * 1000
# budget_burn_rate зазвичай рахується на рівні дашборду:
# витрати за одиницю часу (наприклад USD/hour), а не окремим counter у коді.

Ось як ці метрики виглядають разом у реальному дашборді:

Segmentcost_per_runcost_p95burn_rate (hour)Статус
gpt-4.1 + tools$0.084$0.29$42/hcritical: budget risk
mini-model + cache$0.021$0.07$11/hok
research workflow$0.136$0.41$58/hwarning: p95 росте

Investigation

Коли спрацьовує алерт по витратах:

  1. знайти сегмент із аномалією (model, tool, release);
  2. подивитись дорогі runs у трейсингу;
  3. перевірити в логах retries, stop_reason і tool-path;
  4. знайти root cause (prompt, логіка агента, дорогий API, помилковий routing).

Типові помилки

Навіть коли cost metrics уже додані, вони часто не дають користі через типові помилки нижче.

Є тільки загальна сума витрат за день

Денна сума не показує, який саме run або сегмент став дорожчим. Без cost_per_run і cost_p95 проблему зазвичай помічають запізно.

Рахуються тільки токени, але ігнорується вартість tools

У багатьох агентних системах дорогими є саме зовнішні API-виклики. Без tool_cost_per_run легко пропустити ранню фазу вибуху бюджету.

Немає розбиття за release і model

Без сегментації складно довести, що саме новий реліз або нова модель погіршили собівартість.

Висококардинальні labels

Додавання run_id, request_id або session_id у labels швидко перевантажує бекенд метрик. Краще тримати ці дані в логах і трейсингу.

Немає алертів на burn rate і cost_p95

Без алертів проблеми накопичуються непомітно, поки не вдарять по бюджету. Це часто йде разом із надмірним використанням токенів.

Самоперевірка

Нижче — короткий checklist базового cost monitoring перед релізом.

Прогрес: 0/9

⚠ Бракує базової observability

Систему буде складно дебажити в production. Почніть з run_id, structured logs і tracing tool calls.

FAQ

Q: Чим моніторинг витрат відрізняється від моніторингу токенів?
A: Токени — це лише частина витрат. Cost monitoring включає і токени LLM, і платні tool/API-виклики, і загальну собівартість run.

Q: Який мінімум метрик витрат потрібен на старті?
A: Почни з token_usage_per_run, total_cost_per_run, cost_p95 і budget_burn_rate.

Q: Як рахувати cost_per_run, якщо в системі кілька провайдерів?
A: Нормалізуй усі кроки в єдину валюту (зазвичай USD) і сумуй витрати LLM + tools у межах одного run.

Q: Як відрізнити ріст трафіку від регресії собівартості?
A: Дивись одночасно на run_count і cost_per_run. Якщо трафік стабільний, а cost_per_run росте — це регресія собівартості.

Пов'язані сторінки

Далі за темою:

⏱️ 7 хв читанняОновлено 22 березня 2026 р.Складність: ★★★
Інтегровано: продакшен-контрольOnceOnly
Додай guardrails до агентів з tool-calling
Зашип цей патерн з governance:
  • Бюджетами (кроки / ліміти витрат)
  • Дозволами на інструменти (allowlist / blocklist)
  • Kill switch та аварійна зупинка
  • Ідемпотентність і dedupe
  • Audit logs та трасування
Інтегрована згадка: OnceOnly — контрольний шар для продакшен агент-систем.

Автор

Микола — інженер, який будує інфраструктуру для продакшн AI-агентів.

Фокус: патерни агентів, режими відмов, контроль рантайму та надійність систем.

🔗 GitHub: https://github.com/mykolademyanov


Редакційна примітка

Ця документація підготовлена з допомогою AI, із людською редакторською відповідальністю за точність, ясність і продакшн-релевантність.

Контент базується на реальних відмовах, постмортемах та операційних інцидентах у розгорнутих AI-агентних системах.