Проблема
Зовні все виглядає стабільно. Моніторинг не кричить, явних аварій немає, показник успіху (success rate) майже такий самий.
Але в run-метриках видно зсув: тиждень тому цей агент стабільно закривав задачу за 2-3 кроки, а після невеликого оновлення prompt і версії моделі — вже за 7-9.
Система не впала.
Вона просто повільно з'їхала вбік.
Аналогія: уяви ваги в магазині, які щодня помиляються лише на 1-2 грами. У перший день це майже непомітно. За місяць помилка вже б'є по всій касі. З агентом так само: малий drift у кожному run дає великий збиток на масштабі.
Чому це стається
LLM-агенти — це стохастичні системи. Невелика зміна моделі, prompt або вхідних даних може змінити порядок кроків. Навіть маленька різниця в reasoning loop з часом накопичується у drift.
У production drift зазвичай проходить тихо:
- змінюється модель, prompt, tool output або retrieval-дані;
- агент формально продовжує завершувати задачі;
- але робить інші кроки й витрачає більше ресурсів;
- без порівняння з базовою версією (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 змістилися в бік лімітів;
- агент частіше використовує інструменти без приросту точності.
Як зупиняти такі збої
Практично це виглядає так:
- робиш зміну (candidate);
- у Drift gate в CI проганяєш тести і порівнюєш candidate з baseline за quality/tokens/tool calls/latency/stop reasons;
- якщо пороги порушені, реліз блокується або відбувається rollback;
- якщо пороги в нормі, зміна йде в canary, а потім у повний rollout.
baseline
↓
candidate evaluation
↓
threshold gate
↓
canary
↓
production
Мінімальний бар'єр проти drift у runtime CI:
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 і контроль викликів.