Суть
Агент без тормозов зацикливается (retry на ошибке инструмента, недостижимая цель, переполненный контекст, баг в tool) и жжёт токены. Причём CPU/RAM в норме — растут только токены, поэтому стандартный мониторинг (Prometheus) это не ловит.
Зачем это нужно
Runaway бывает не только от атаки, но и от обычного бага (изменился формат API → retry loop → 200× токенов за 40 минут). Token DoS (случайный или намеренный) защищается одинаково — бюджетными лимитами.
Как работает
- 4 независимых лимита (нужны все сразу):
max_iterations(шаги),max_tokens(на задачу),timeout(время),max_cost(деньги, circuit breaker). Уровни бюджета: задача ~$0.50 / сессия ~$2 / день ~$10. - 5-слойная защита (prod): Timeout → Anti-loop (max 3 retry + пауза) → Cost Circuit Breaker ($50 warning / $100 halt) → Model Pinning (дешёвые задачи не уходят на дорогую модель) → Session Audit Log. Каждый слой ловит то, что пропустил предыдущий.
- AI-специфичные метрики:
tokens_per_task,cost_per_completion,loop_iterations— алерт при 2× от baseline. - Early stopping > hard error: при остатке бюджета <20% вернуть частичный результат + статус, а не упасть с исключением (UX-решение). Связано с лимитом шагов в ReAct и квадратичным ростом Context Window.
- Контроль на уровне инструментов: лимиты прямо в контрактах (
find_customers(..., limit=5)) не дают агенту «выкачать всю базу» (см. Tool Calling). Для исполнителейmax_retries=2, причём «retry не должен скрывать реальную проблему» — после стоп и отчёт. К стоп-условиям петли добавляется No Progress (наряду с max_iterations/tokens/time). - Лимит на циклы валидации: при автоисправлении вывода (Validation Loops) ставят
retries=3; после исчерпания —UnexpectedModelBehavior, а не бесконечный цикл. Отдельная метрика стоимости —retry_overhead_tokens(токены, сожжённые на исправления). - Architect/Editor split (архитектурный приём экономии): дорогая «умная» модель проектирует короткий JSON-план, дешёвая быстрая печатает по нему сотни строк кода → экономия 50–80% бюджета (и качество выше — Редактор не отвлекается на архитектуру). Adaptive compute: Best-of-N тратит токены только там, где нужна надёжность (см. Agent Architecture, Generator Evaluator).
- Лимиты в LangGraph: на узел вешается
RetryPolicy(экспоненциальный backoff + jitter) для временных ошибок; цикличный граф ограничивается лимитом итераций + условным ребром на выход; дорогой replay при time-travel удешевляют кэшированием результатов LLM-узлов в state (см. LangGraph Reliability).
Пример
Architect/Editor split: дорогая «умная» модель проектирует короткий JSON-план, дешёвая быстрая печатает по нему основной объём кода → экономия 50–80% (Редактор не отвлекается на архитектуру).
def architect_editor_solve(task):
plan = client.chat.completions.create( # дорогая модель: короткий план
model=MODEL_STRONG, response_format={"type": "json_object"},
messages=[{"role": "system", "content": ARCHITECT_SYSTEM},
{"role": "user", "content": task}]).choices[0].message.content
code = client.chat.completions.create( # дешёвая модель: пишет код по плану
model=MODEL_FAST,
messages=[{"role": "system", "content": EDITOR_SYSTEM},
{"role": "user", "content": f"{task}\nПЛАН:\n{plan}"}]).choices[0].message.content
return {"plan": plan, "code": code}
Связано с
- ReAct — где ставится лимит итераций
- Reasoning Effort — усилие как источник затрат
- Agent Routing — budget-aware: при низком остатке форсим cheap-модель
- Context Window — квадратичный рост стоимости
- Validation Loops —
retries=3иretry_overhead_tokensкак часть бюджета - LangGraph Reliability —
RetryPolicy, лимиты циклов, кэш replay в LangGraph
Открытые вопросы
- стартовые значения лимитов для своего кейса
- как считать baseline для AI-метрик