Перевитрата токенів: коли AI-агент витрачає забагато токенів

Token overuse виникає, коли агент марнує токени на довгі reasoning-цикли або зайвий контекст. Як це контролювати у production.
На цій сторінці
  1. Проблема
  2. Чому це стається
  3. Які збої трапляються найчастіше
  4. Роздутий prompt (Prompt bloat)
  5. Token bombs у tool output
  6. Інфляція memory/history
  7. Тиха деградація через truncation
  8. Як виявляти ці проблеми
  9. Як відрізнити перевитрату від справді складної задачі
  10. Як зупиняти такі збої
  11. Де це реалізується в архітектурі
  12. Самоперевірка
  13. FAQ
  14. Пов'язані сторінки

Проблема

Запит виглядає простим: перевірити статус інциденту і дати короткий підсумок.

У трейсах видно інше: за 8 хвилин один run витратив понад 38k токенів, хоча подібні задачі раніше вкладались у ~4-6k. Половина бюджету пішла не у відповідь, а в контекст: історія, сирі логи і великі tool outputs.

Для задачі такого класу це може бути ~$2.80 замість звичних ~$0.20. І при цьому якість відповіді майже не зросла.

Система не падає.

Вона просто повільно роздуває prompt, latency і витрати.

Аналогія: уяви валізу, в яку перед кожною поїздкою додають "ще одну важливу річ", але ніколи нічого не виймають. Спочатку це майже непомітно. Потім ти витрачаєш більше часу, грошей і сил просто на те, щоб нести зайве. Token overuse в агентів працює так само.

Чому це стається

Token overuse зазвичай виникає не через саму модель, а через слабкий контроль контекстного бюджету в runtime.

У production зазвичай так:

  1. в контекст кожного нового кроку додають усе підряд: history, retrieval, tool output;
  2. raw payload (логи, HTML, JSON) потрапляє в prompt без стиснення;
  3. без пер-джерельних caps і summarization контекст росте кожен turn;
  4. токени йдуть у "перенесення зайвого", а не в корисний прогрес;
  5. довгі reasoning-цикли без no-progress перевірки ще сильніше роздувають історію.

У trace це зазвичай видно як стабільний ріст prompt_tokens, де кожен новий turn стає дорожчим за попередній, навіть якщо сама задача не ускладнюється.

Без контролю цей ріст починає шкодити latency, вартості і якості.

Які збої трапляються найчастіше

У production найчастіше видно чотири повторювані патерни token overuse.

Роздутий prompt (Prompt bloat)

У запит до моделі потрапляє занадто багато контексту "про всяк випадок".

Типова причина: немає max_prompt_tokens і пріоритезації chunk'ів.

Token bombs у tool output

Інструменти повертають великі payload (HTML, логи, stack traces), які йдуть у prompt майже без обробки.

Типова причина: немає caps, а payload не проходить extraction або summarization перед додаванням у prompt.

Інфляція memory/history

Агент накопичує історію turn за turn, але не стискає старі ділянки. У результаті нові кроки стають дедалі дорожчими. Якщо run ще й довго крутиться без прогресу, ця інфляція росте ще швидше.

Типова причина: memory використовується як "архів", а не як budgeted context.

Тиха деградація через truncation

Коли контекст перевищує реальне вікно, важливі частини prompt обрізаються. Часто першими зникають policy-обмеження або критичні інструкції.

Типова причина: немає явного контролю, що саме викидати і в якому порядку.

Як виявляти ці проблеми

Token overuse добре видно по поєднанню cost, latency і контекст-метрик.

МетрикаСигнал token overuseЩо робити
prompt_tokens_per_runстабільний ріст токенів на runввести max_prompt_tokens і budgeted context builder
tool_output_tokensвеликі сирі payload у promptcaps + extraction/summarization до моделі
tokens_per_successякість та сама, але ціна ростеперевірити unit economics і обмежити непотрібний контекст
context_truncation_rateчасті обрізання promptпріоритезувати policy і нові факти, стискати старе
latency_p95затримка росте разом із токенамизменшити контекст і обмежити fan-out retrieval або tool output

Як відрізнити перевитрату від справді складної задачі

Не кожен великий prompt — погано. Ключове питання: чи дають додаткові токени реальний приріст якості.

Нормально, якщо:

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

Небезпечно, якщо:

  • токени ростуть швидше, ніж success rate;
  • багато контексту дублює старі turn або сирі технічні дампи;
  • latency і вартість ростуть, а відповіді майже не змінюються.

Як зупиняти такі збої

Практично це виглядає так:

  1. вводиш жорсткі ліміти: max_prompt_tokens + caps на history/tool/retrieval;
  2. додаєш context builder з пріоритетами (policy і нові факти вище за старі логи);
  3. старі або великі фрагменти стискаєш у summarization-tier;
  4. при перевищенні бюджету повертаєш stop reason або partial, а не шлеш "переповнений" prompt.

Мінімальний guard для token budget:

PYTHON
from dataclasses import dataclass


@dataclass(frozen=True)
class TokenLimits:
    max_prompt_tokens: int = 7000
    max_history_tokens: int = 1800
    max_tool_tokens: int = 2500
    max_retrieval_tokens: int = 2200


class TokenBudgetGuard:
    def __init__(self, limits: TokenLimits = TokenLimits()):
        self.limits = limits
        self.total_prompt_tokens = 0
        self.by_source = {
            "history": 0,
            "tool": 0,
            "retrieval": 0,
        }

    def _cap_for(self, source: str) -> int:
        if source == "history":
            return self.limits.max_history_tokens
        if source == "tool":
            return self.limits.max_tool_tokens
        if source == "retrieval":
            return self.limits.max_retrieval_tokens
        return self.limits.max_prompt_tokens

    def add_chunk(self, source: str, tokens: int) -> str | None:
        if self.by_source.get(source, 0) + tokens > self._cap_for(source):
            return f"token_overuse:{source}_cap"

        if self.total_prompt_tokens + tokens > self.limits.max_prompt_tokens:
            return "token_overuse:prompt_budget_exceeded"

        self.by_source[source] = self.by_source.get(source, 0) + tokens
        self.total_prompt_tokens += tokens
        return None

Це базовий guard. У production його зазвичай доповнюють точним token counting від провайдера, summarization-tier для старих chunk'ів і окремими stop reasons для truncation. add_chunk(...) викликають до додавання фрагмента в prompt, щоб budget працював як gate, а не як постфактум перевірка.

Де це реалізується в архітектурі

У production контроль token overuse майже завжди розкладений між трьома шарами системи.

Memory Layer керує тим, що зберігати надовго, а що подавати в поточний prompt. Якщо memory = "показати все", витрати неминуче ростуть.

Tool Execution Layer відповідає за нормалізацію і стиснення великих payload до того, як вони потрапляють у контекст моделі. Тут ставлять caps на output, витягують потрібні факти з великих payload і стискають їх до того, як вони потрапляють у prompt.

Agent Runtime тримає execution budgets: max_prompt_tokens, stop reasons, кероване завершення і fallback при перевищенні лімітів. Саме тут токен-бюджет стає production-правилом, а не побажанням.

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

Швидка перевірка перед релізом. Відмічайте пункти і дивіться статус нижче.
Це короткий sanity-check, а не формальний аудит.

Прогрес: 0/8

⚠ Є сигнали ризику

Бракує базових контролів. Закрийте ключові пункти цього чекліста перед релізом.

FAQ

Q: Чи можна просто перейти на модель із більшим context window?
A: Можна, але це зазвичай дорожче і повільніше. Без budget-контролю проблема не зникає, а лише переноситься на більший ліміт.

Q: Що краще на старті: рахувати токени чи символи?
A: Найкраще — токени провайдерським лічильником. Якщо це недоступно, починай із консервативних char caps і переходь на токени.

Q: Що стискати першим при перевищенні бюджету?
A: Зазвичай старі turn і великі сирі tool outputs. Policy та найновіші факти мають залишатися.

Q: Що показувати користувачу, коли prompt budget вичерпано?
A: Причину зупинки, що вже обробили, і безпечний наступний крок: partial result, звуження запиту або повторний запуск із меншим контекстом.


Token overuse майже ніколи не виглядає як гучна аварія. Це повільна деградація, яка роздуває latency і вартість без явного падіння сервісу. Тому production-агентам потрібні не лише кращі моделі, а й жорсткий контроль контекстного бюджету.

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

Якщо ця проблема виникла у production, корисно також подивитися:

  • Чому AI агенти ламаються — загальна карта збоїв у production.
  • Budget explosion — як перевитрата токенів переростає у фінансовий інцидент.
  • Tool spam — як зайві виклики інструментів роздувають контекст і витрати.
  • Context poisoning — як неякісний контекст псує рішення агента.
  • Memory Layer — де відділяти довготривалу пам'ять від prompt-контексту.
  • Agent Runtime — де ставити токен-ліміти, stop reasons і fallback.
⏱️ 7 хв читанняОновлено 12 березня 2026 р.Складність: ★★☆
Реалізувати в OnceOnly
Guardrails for loops, retries, and spend escalation.
Використати в OnceOnly
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
controls:
  loop_detection:
    enabled: true
    dedupe_by: [tool, args_hash]
  retries:
    max: 2
    backoff_ms: [200, 800]
stop_reasons:
  enabled: true
logging:
  tool_calls: { enabled: true, store_args: false, store_args_hash: true }
Інтегровано: продакшен-контрольOnceOnly
Додай guardrails до агентів з tool-calling
Зашип цей патерн з governance:
  • Бюджетами (кроки / ліміти витрат)
  • Kill switch та аварійна зупинка
  • Audit logs та трасування
  • Ідемпотентність і dedupe
  • Дозволами на інструменти (allowlist / blocklist)
Інтегрована згадка: OnceOnly — контрольний шар для продакшен агент-систем.
Приклад policy (концепт)
# Example (Python — conceptual)
policy = {
  "budgets": {"steps": 20, "seconds": 60, "usd": 1.0},
  "controls": {"kill_switch": True, "audit": True},
}

Автор

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

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

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


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

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

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