Чому AI агенти ламаються: типові проблеми у production

Чому AI-агенти ламаються в production: infinite loops, tool spam, budget explosion, prompt injection і runtime-помилки. Які збої трапляються найчастіше і як їх зупиняти.
На цій сторінці
  1. Проблема
  2. Чому це стається
  3. Які збої трапляються найчастіше
  4. Зациклення (Loop failures)
  5. Збої інструментів (Tool failures)
  6. Збої бюджету (Budget failures)
  7. Дрейф контексту (Context drift)
  8. Як детектити ці проблеми
  9. Як відрізнити збій від справді складної задачі
  10. Як зупиняти такі збої
  11. Самоперевірка
  12. FAQ
  13. Пов'язані сторінки

Проблема

03:07 ночі.

Черговий інженер on-call бачить, що агент отримав звичайний запит, кілька разів викликав tool, отримував результати, але так і не зміг завершити задачу.

У логах повторюється:

plan → call_tool → analyze → plan → call_tool → analyze

Кроків багато, токенів теж багато, результату немає.

Агент намагається знайти email у CRM. Пошук повертає 404, але замість відповіді "не знайдено" агент починає змінювати запит:

  • john@example.com
  • John@example.com
  • JOHN@example.com
  • john@company.com

За 2 хвилини агент зробив 47 API-викликів, витратив близько $5 на токени і все одно не наблизився до відповіді.

Runaway loop може за 30–40 хвилин спалити бюджет, який планувався на тиждень роботи системи.

Аналогія: уяви касира, який безкінечно пробиває один і той самий товар у чек, ігноруючи ліміт картки покупця. Він може виглядати "зайнятим", але кожна нова дія лише збільшує збиток. Для AI-агентів цю роль контролю виконує runtime: stop conditions, бюджети та policy gates.

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

У production:

  1. LLM пропонує наступний крок;
  2. виклик іде в інструмент;
  3. результат знову потрапляє в reasoning loop;
  4. runtime не перевіряє, чи є прогрес, і не зупиняє цикл вчасно.

Проблема не в моделі — проблема в тому, що runtime не знає, коли треба зупинитись.

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

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

Зациклення (Loop failures)

Агент повторює ті самі кроки без нових спостережень. Зовні це може виглядати так, ніби він ще працює, але насправді система просто крутиться по колу і спалює час та гроші.

Типова причина: відсутні max_steps, progress check або чіткий stop reason.

У production це зазвичай виглядає як нескінченний цикл.

Збої інструментів (Tool failures)

Агент занадто часто або неправильно викликає інструменти. Зростають latency і API-навантаження, а збої починають розповзатися по ланцюгу сервісів.

Типова причина: занадто вільний Tool Execution Layer і слабка валідація аргументів.

У результаті легко отримати збій інструмента.

Збої бюджету (Budget failures)

Бюджет токенів і часу зростає без помітного прогресу. У результаті система дорожчає, а суміжні сервіси частіше впираються в timeout.

Типова причина: немає execution budgets на кроки, токени, час і кількість tool викликів.

Без лімітів це часто переростає у вибух бюджету.

Дрейф контексту (Context drift)

Коли агент працює занадто довго, історія повідомлень росте. Нові токени можуть витіснити системний prompt, і агент починає "забувати" свою роль або первинну задачу — це context drift. Зазвичай його виправляють через summarization і обмеження context window; близький за симптомами сценарій — отруєння контексту.

Окремо варто тримати в полі зору ще два класи:

  • Security failures: prompt injection і несанкціонований доступ до write-інструментів.
  • Data failures: хибні або невалідовані проміжні дані, що ламають фінальну відповідь.

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

Щоб спіймати такі збої до того, як вони стануть інцидентом, production-системи зазвичай відстежують кілька ключових метрик.

МетрикаСигналЩо робити
steps_per_taskрізкий ріст ітераційперевірити stop conditions, додати progress check
tool_calls_per_taskпідозріло багато повторівввести dedupe tool+args, обмеження на виклики
tokens_per_taskвитрата росте без прогресуобмежити розмір context window, додати summarization і caps для tool output
runtime_durationзатримки ростуть, task зависаєtimeout і примусове завершення run'а

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

Не кожен довгий run означає збій. Ключовий сигнал проблеми — не кількість кроків, а відсутність реального прогресу.

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

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

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

  • повтори без нових спостережень;
  • той самий tool_call без змін в аргументах;
  • вартість росте, а результат не поліпшується.

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

Найпростіший спосіб контролювати execution loop — runtime limits. Зазвичай це ліміти max_steps, max_tool_calls, max_tokens і timeout.

max_steps — перший стоп-кран проти runaway loops. Більш просунутий варіант — semantic progress check: окрема невелика модель (наприклад, Gemini Flash або Claude Haiku) аналізує останні 3 кроки агента і перевіряє, чи з'явився новий сигнал, чи система просто крутиться по колу. Результат може виглядати так:

JSON
{
  "is_progressing": true,
  "is_looping": false
}

Базовий runtime-каркас, який закриває більшість runaway loops:

PYTHON
class RunLimits:
    def __init__(self):
        self.max_steps = 8
        self.max_tool_calls = 12
        self.max_tokens = 4000
        self.max_seconds = 30
        self.steps = 0
        self.tool_calls = 0

    def check(self, step_tokens: int, elapsed_ms: int) -> str | None:
        self.steps += 1
        self.max_tokens -= step_tokens

        if self.steps > self.max_steps:
            return "max_steps_reached"
        if self.tool_calls > self.max_tool_calls:
            return "max_tool_calls_reached"
        if self.max_tokens <= 0:
            return "max_tokens_reached"
        if elapsed_ms > self.max_seconds * 1000:
            return "timeout"
        return None

    def register_tool(self):
        self.tool_calls += 1

У production такі ліміти часто зберігають у Redis, щоб контролювати їх між stateless workers.

Але самі ліміти не гарантують правильну поведінку — вони лише зупиняють runaway loop. Щоб агент працював стабільно, потрібні ще валідація tool output, policy boundaries і контроль write-дій.

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

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

Прогрес: 0/8

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

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

FAQ

Q: Чому AI-агенти ламаються частіше за звичайні workflow?
A: У workflow кроки зафіксовані наперед. В агенті LLM пропонує наступний крок динамічно, і без runtime меж цикл швидко виходить з-під контролю.

Q: Чи врятує перехід на сильнішу модель?
A: Частково допоможе, але проблему не вирішить. Без runtime-контролю навіть сильна модель може зациклитися, перевищити бюджет або спамити інструментами.


Якби агент із початку статті мав max_steps = 8 і dedupe для tool+args, інцидент о 03:07 завершився б за кілька секунд.

У production стабільність агента визначається не моделлю, а межами, які runtime ставить навколо execution loop.

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

Щоб краще зрозуміти, як запобігати таким збоям, подивись на шари системи, які контролюють поведінку агента:

  • Agent Runtime — керує циклом агента, лімітами і причинами зупинки.
  • Tool Execution Layer — безпечно виконує tool_call через валідацію, policy і timeout.
  • Policy Boundaries — визначає, які дії дозволені, а які блокуються за замовчуванням.
  • Memory Layer — допомагає тримати стан чистим, щоб агент не повторював кроки без прогресу.

Також корисно перейти до окремих failure-сценаріїв:

  • Infinite loop — як виявляти і зупиняти повтори без прогресу.
  • Tool spam — як обмежувати дубльовані виклики інструментів.
  • Budget explosion — як контролювати витрати токенів і API-бюджет.
⏱️ 6 хв читанняОновлено 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-агентних системах.