Дрейф AI-агента: коли агент поступово втрачає фокус

Agent drift виникає, коли AI-агент поступово відходить від початкової задачі. Чому це трапляється у production і як runtime-обмеження допомагають це зупинити.
На цій сторінці
  1. Проблема
  2. Чому це стається
  3. Які збої трапляються найчастіше
  4. Модельний drift
  5. Drift у prompt
  6. Drift контрактів інструментів
  7. Drift у retrieval і контексті
  8. Як виявляти ці проблеми
  9. Як відрізнити drift від справді корисної зміни
  10. Як зупиняти такі збої
  11. Де це реалізується в архітектурі
  12. Самоперевірка
  13. FAQ
  14. Пов'язані сторінки

Проблема

Зовні все виглядає стабільно. Моніторинг не кричить, явних аварій немає, показник успіху (success rate) майже такий самий.

Але в run-метриках видно зсув: тиждень тому цей агент стабільно закривав задачу за 2-3 кроки, а після невеликого оновлення prompt і версії моделі — вже за 7-9.

Система не впала.

Вона просто повільно з'їхала вбік.

Аналогія: уяви ваги в магазині, які щодня помиляються лише на 1-2 грами. У перший день це майже непомітно. За місяць помилка вже б'є по всій касі. З агентом так само: малий drift у кожному run дає великий збиток на масштабі.

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

LLM-агенти — це стохастичні системи. Невелика зміна моделі, prompt або вхідних даних може змінити порядок кроків. Навіть маленька різниця в reasoning loop з часом накопичується у drift.

У production drift зазвичай проходить тихо:

  1. змінюється модель, prompt, tool output або retrieval-дані;
  2. агент формально продовжує завершувати задачі;
  3. але робить інші кроки й витрачає більше ресурсів;
  4. без порівняння з базовою версією (baseline) це виглядає як "усе нормально".

Проблема не в одній конкретній зміні. Проблема в тому, що немає контролю релізів, який рано ловить відхилення від baseline.

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

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

Модельний drift

Після зміни версії LLM агент починає інакше ранжувати кроки: частіше "перевіряє ще раз", пізніше завершує run або обирає інший tool.

Типова причина: версію моделі оновили без порівняння з baseline на golden-наборі задач.

Drift у prompt

Невелика правка в системному prompt змінює пріоритети агента: він стає "надто обережним" або "надто активним".

Типова причина: prompt змінили як текст, а не як production-код із тестом і canary.

Drift контрактів інструментів

tool повертає нове поле, інший формат помилки або порожній масив замість null. Агент інтерпретує це інакше й змінює цикл прийняття рішень.

У production це легко переходить у збій інструмента або в спам інструментами.

Drift у retrieval і контексті

Оновився індекс знань: додались нові документи, змінився ranking, зросла кількість нерелевантних chunks у context window. Агент формально працює, але частіше бере не ті факти.

За симптомами це часто схоже на отруєння контексту.

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

Найкраще drift видно не по одній метриці, а по відхиленнях від baseline.

МетрикаСигнал driftЩо робити
tool_calls_per_taskповільний, але стабільний рістпорівняти candidate з baseline, додати пороги на відхилення
tokens_per_taskбільша витрата без приросту якостіперевірити prompt та caps на tool output
latency_p95погіршення після релізуcanary + автоматичний rollback за порогом
stop_reason_distributionбільше timeout або max_steps_reachedперевірити нові цикли та зміну policy у prompt
task_success_rateмайже без змін, але інші метрики погіршилисьне довіряти лише success rate, дивитися повний профіль run'а

Як відрізнити drift від справді корисної зміни

Не кожна зміна поведінки погана. Іноді нова версія справді краща. Ключове питання: чи покращилась якість без непропорційної ціни.

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

  • якість зросла, а tokens_per_task і latency_p95 майже не змінились;
  • нова поведінка стабільна на golden-задачах;
  • canary не показує зростання timeout і max_steps_reached.

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

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

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

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

  1. робиш зміну (candidate);
  2. у Drift gate в CI проганяєш тести і порівнюєш candidate з baseline за quality/tokens/tool calls/latency/stop reasons;
  3. якщо пороги порушені, реліз блокується або відбувається rollback;
  4. якщо пороги в нормі, зміна йде в canary, а потім у повний rollout.
TEXT
baseline
   ↓
candidate evaluation
   ↓
threshold gate
   ↓
canary
   ↓
production

Мінімальний бар'єр проти drift у runtime CI:

PYTHON
from dataclasses import dataclass


@dataclass(frozen=True)
class Thresholds:
    max_tool_calls_delta: int = 2
    max_tokens_delta_pct: float = 0.30
    max_latency_delta_pct: float = 0.30
    allow_stop_reason_change: bool = False


def violates_thresholds(baseline: dict, candidate: dict, t: Thresholds) -> list[str]:
    errors: list[str] = []

    if candidate["tool_calls"] > baseline["tool_calls"] + t.max_tool_calls_delta:
        errors.append("tool_calls_delta_exceeded")

    if candidate["tokens"] > baseline["tokens"] * (1 + t.max_tokens_delta_pct):
        errors.append("tokens_delta_exceeded")

    if candidate["latency_ms"] > baseline["latency_ms"] * (1 + t.max_latency_delta_pct):
        errors.append("latency_delta_exceeded")

    if (not t.allow_stop_reason_change) and candidate["stop_reason"] != baseline["stop_reason"]:
        errors.append("stop_reason_changed")

    return errors

Цей бар'єр не робить магії. Він просто не дає зашипити повільну і дорожчу регресію під виглядом "успішного" релізу.

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

Drift-контроль зазвичай розподілений між двома шарами.

Agent Runtime фіксує сигнали drift під час виконання: stop_reason_distribution, steps_per_task, tokens_per_task. Без цих метрик threshold gate не матиме з чим порівнювати.

Tool Execution Layer — джерело частини drift: зміна формату tool output, нова retry policy або інший контракт помилок непомітно змінюють поведінку агента. Саме тут варто версіонувати контракти інструментів.

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

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

Прогрес: 0/7

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

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

FAQ

Q: Drift завжди означає, що модель стала гіршою?
A: Ні. Drift означає, що поведінка змінилась. Погано, коли зміна не виміряна і неконтрольована.

Q: Можна виявляти drift лише по success rate?
A: Ні. Success rate часто запізнюється. Раніше рухаються tool_calls, токени, latency і stop reasons.

Q: Canary потрібен для маленьких правок prompt?
A: Для high-traffic систем так. Навіть одне речення в prompt може змінити вибір дій агента.

Q: Що робити, якщо drift є, але якість трохи краща?
A: Порахуй unit economics: вартість одного успішного run у baseline і candidate. Якщо quality зросла, а нова ціна run'а в межах допустимого бюджету, шипи зміни і зафіксуй новий baseline.


Agent drift майже ніколи не виглядає як аварія. Це повільна регресія, яку видно тільки у порівнянні з baseline. Тому production-агенти потребують не лише кращих моделей, а й жорсткого release-контролю.

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

Щоб краще закрити drift у production, подивись:

  • Чому AI агенти ламаються — загальна карта типових збоїв у production.
  • Budget explosion — як дрейф поведінки тихо роздуває витрати.
  • Tool spam — як контролювати ріст зайвих викликів інструментів.
  • Context poisoning — як проблеми контексту маскуються під "дивні" рішення агента.
  • Agent Runtime — де ставити release-gates, ліміти і stop reasons.
  • Tool Execution Layer — де тримати валідацію, retries і контроль викликів.
⏱️ 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-агентних системах.