Ідея за 30 секунд
Agents Without Guardrails — це анти-патерн, коли агент виконує дії без примусових runtime-правил: policy-gate, allowlist, scope-контролю, бюджетних лімітів і зрозумілих stop_reason.
У результаті помилка моделі або хибний маршрут стає реальною операційною проблемою: зайві виклики, небажані дії, перевитрата бюджету або ризикований доступ не в той контекст.
Просте правило: guardrails мають жити в коді й шарі виконання, а не тільки в prompt.
Приклад анти-патерну
Команда запускає support-агента, який може шукати дані, оновлювати статуси і надсилати повідомлення.
Агент отримує широкий доступ до інструментів без централізованих runtime-правил.
decision = agent.next_action(user_message)
result = run_tool(decision.tool, decision.args)
return result
У такій схемі немає базового контролю:
# немає allowlist за маршрутом
# немає deny-by-default для ризикових дій
# немає tenant/env scope enforcement
# немає budget/step/time лімітів
У такому підході run переходить до виконання без policy-gate, тому ризикові кроки не зупиняються в точці рішення.
У такій схемі відсутність guardrails призводить до:
- непередбачуваних змін стану
- ризик помилкових або зайвих викликів
- складний інцидент-аналіз без чіткої межі відповідальності
Чому виникає і що йде не так
Цей анти-патерн часто з’являється, коли команда спочатку оптимізує "щоб агент умів більше", а контрольні межі відкладає на пізніше.
Типові причини:
- надмірна довіра до prompt-інструкцій замість примусових runtime-перевірок
- відсутність окремого gateway-шару для policy-рішень
- змішані ролі: агент сам і планує, і виконує ризикові дії без перевірок
- ніхто явно не відповідає за правила доступу, ліміти й audit
У результаті виникають проблеми:
- ризикові дії без контролю — агент може виконати небезпечний крок у невідповідному сценарії
- перевитрата ресурсів — без бюджетних і step-лімітів run зростає в cost і latency
- помилки контексту — без scope enforcement дія може піти не в той tenant/env
- розмиті межі відповідальності — інцидент важко локалізувати між агентом і gateway
- повторні інциденти — команда виправляє наслідки, але не корінь проблеми
На відміну від Write Access by Default, тут проблема ширша: відсутні не лише write-обмеження, а й загальні execution-межі для всього run.
Типові production-сигнали, що guardrails не працюють або відсутні:
- потенційно небезпечні tool-calls проходять, хоча для них очікується
approval_requiredабоpolicy_denied - blocked attempts майже не трапляються навіть у ризикових маршрутах
- run часто доходить до
max_stepsабо budget-перевищення без ранньої зупинки - audit-логи не показують, яке саме правило дозволило або заблокувало дію
- команда не може швидко пояснити, чому конкретний tool-call був виконаний
Кожен tool-call — це операційне рішення. Якщо межі виконання не примусові, агентна система поводиться непередбачувано навіть у простих сценаріях.
Правильний підхід
Починайте з мінімального, але жорсткого набору guardrails у runtime. Кожен крок або проходить policy-перевірку, або зупиняє run зі зрозумілим stop_reason.
Якщо починаєте з нуля, не намагайтесь впровадити все одразу.
Перший мінімум: deny-by-default, route-based allowlist, scope enforcement (tenant/env) і явні stop_reason для policy-відмов.
Практична рамка:
- deny-by-default для небезпечних або невідомих дій
- allowlist інструментів за роллю і маршрутом
- обов’язковий scope (
tenant_id,env) з authenticated context - step/time/budget ліміти для кожного run
- окремий approval-крок для ризикових write-операцій
- журнал policy-рішень для кожного tool-call
ALLOWED_TOOLS_BY_ROUTE = {
"faq": {"kb.search"},
"refund": {"order.get", "refund.create"},
}
WRITE_TOOLS = {"refund.create", "ticket.close", "email.send"}
def execute_step(decision, ctx):
allowed = ALLOWED_TOOLS_BY_ROUTE.get(ctx["route"], set())
if decision.tool not in allowed:
return stop("policy_denied:tool_not_allowed")
if decision.tool in WRITE_TOOLS and not has_approval(ctx, decision):
return stop("approval_required")
if exceeds_budget(ctx):
return stop("budget_exceeded")
scoped_args = enforce_scope(
decision.args,
tenant_id=ctx["tenant_id"],
env=ctx["env"],
)
return run_tool(decision.tool, scoped_args)
У такій схемі агент працює в контрольованих межах: дозволені дії проходять, а ризикові або невалідні кроки зупиняються прозоро.
Швидкий тест
Якщо на ці питання відповідь "так", у вас є ризик анти-патерну Agents Without Guardrails:
- Чи агент може викликати інструмент без явної policy-перевірки?
- Чи для ризикових кроків майже ніколи не з’являється
policy_deniedабоapproval_required? - Чи команда не може швидко пояснити, чому конкретна дія була дозволена?
Чим відрізняється від інших анти-патернів
Write Access by Default vs Agents Without Guardrails
| Write Access by Default | Agents Without Guardrails |
|---|---|
| Основна проблема: write-доступ відкритий за замовчуванням. | Основна проблема: немає загальних execution-меж для run (policy, scope, budgets, approvals). |
| Коли виникає: коли write не проходить через deny-by-default і approval-gate. | Коли виникає: коли навіть read/write/tool маршрути не мають примусових runtime-правил. |
Якщо коротко: Write Access by Default — про небезпечну модель write-доступу, а Agents Without Guardrails — про відсутність контрольних меж виконання загалом.
Blind Tool Trust vs Agents Without Guardrails
| Blind Tool Trust | Agents Without Guardrails |
|---|---|
| Основна проблема: неперевірений tool output потрапляє в рішення. | Основна проблема: система не обмежує, які дії агент взагалі може виконати. |
| Коли виникає: коли немає parse/schema/invariant validation-gate. | Коли виникає: коли policy-рішення залишають у prompt, а не в шарі виконання. |
Якщо коротко: Blind Tool Trust — про надійність даних перед дією, а Agents Without Guardrails — про межі дозволених дій.
No Stop Conditions vs Agents Without Guardrails
| No Stop Conditions | Agents Without Guardrails |
|---|---|
| Основна проблема: у циклі немає чітких умов завершення. | Основна проблема: відсутні системні межі виконання для дій, прав і доступу. |
Коли виникає: коли немає max_steps, timeout, no_progress. | Коли виникає: коли run не проходить через policy-gate, scope-check і контроль доступу. |
Якщо коротко: No Stop Conditions — про контроль завершення циклу, а Agents Without Guardrails — про ширші межі безпечного виконання.
Самоперевірка: чи немає у вас цього анти-патерну
Швидка перевірка на anti-pattern Agents Without Guardrails.
Відмічайте пункти під вашу систему і дивіться статус нижче.
Перевірте свою систему:
Прогрес: 0/8
⚠ Є ознаки цього anti-pattern
Спробуйте винести прості кроки у workflow і залишити агента лише для складних рішень.
FAQ
Q: Чи достатньо прописати обмеження в system prompt?
A: Ні. Prompt корисний як намір, але не як примусове правило. Критичні межі мають перевірятись у runtime-шарі.
Q: З чого почати, якщо guardrails майже немає?
A: Почніть із deny-by-default, route-based allowlist, scope enforcement (tenant/env) і явних stop_reason для policy-відмов.
Q: Чи не зробить guardrails систему занадто повільною?
A: Так, guardrails додають невеликий overhead. Але він майже завжди дешевший за помилкові дії, перевитрату бюджету й ручне виправлення наслідків.
Що далі
Схожі anti-patterns:
- Write Access by Default — коли write-доступ відкритий без достатніх обмежень.
- Blind Tool Trust — коли рішення приймаються на неперевіреному tool output.
- No Stop Conditions — коли цикл агента не має контрольованого завершення.
Що будувати замість цього:
- Allowed Actions — як обмежити дії агента через явні правила.
- Tool Execution Layer — де централізувати policy, scope і контроль виконання.
- Stop Conditions — як завершувати run прозоро при порушенні меж.