Idea en 30 segundos
Agents Without Guardrails es un anti-pattern donde el agente ejecuta acciones sin reglas runtime forzadas: policy-gate, allowlist, control de scope, límites de presupuesto y stop_reason claro.
Como resultado, un error del modelo o una ruta incorrecta se convierte en un problema operativo real: llamadas innecesarias, acciones no deseadas, sobreuso de presupuesto o acceso riesgoso en el contexto incorrecto.
Regla simple: las barreras de control deben vivir en código y en la capa de execution, no solo en el prompt.
Ejemplo del anti-pattern
El equipo lanza un agente de soporte que puede buscar datos, actualizar estados y enviar mensajes.
El agente recibe acceso amplio a herramientas sin reglas runtime centralizadas.
decision = agent.next_action(user_message)
result = run_tool(decision.tool, decision.args)
return result
En este esquema falta el control base:
# no hay allowlist por ruta
# no hay deny-by-default para acciones riesgosas
# no hay tenant/env scope enforcement
# no hay límites de budget/step/time
Con este enfoque, el run pasa a execution sin policy-gate, por eso los pasos riesgosos no se detienen en el punto de decisión.
En este esquema, la ausencia de guardrails provoca:
- cambios de estado impredecibles
- riesgo de llamadas incorrectas o innecesarias
- análisis de incidente difícil sin frontera clara de responsabilidad
Por qué aparece y qué sale mal
Este anti-pattern aparece cuando el equipo primero optimiza "para que el agente haga más" y deja los límites de control para después.
Causas típicas:
- demasiada confianza en instrucciones de prompt en lugar de checks runtime forzados
- ausencia de una capa gateway separada para decisiones policy
- roles mezclados: el agente planifica y ejecuta acciones riesgosas sin verificación
- nadie tiene responsabilidad explícita sobre reglas de acceso, límites y auditoría
Como resultado aparecen problemas:
- acciones riesgosas sin control - el agente puede ejecutar un paso peligroso en un escenario inválido
- sobreuso de recursos - sin límites de budget y steps, crecen el costo y la latencia del run
- errores de contexto - sin scope enforcement, la acción puede ir al tenant/env incorrecto
- fronteras de responsabilidad difusas - es difícil localizar incidentes entre agente y gateway
- incidentes repetidos - el equipo corrige consecuencias, pero no la causa raíz
A diferencia de Write Access by Default, aquí el problema es más amplio: no solo faltan límites de write, también faltan límites generales de execution para todo el run.
Señales típicas de producción de guardrails débiles o ausentes:
- tool-calls potencialmente peligrosos pasan aunque se espera
approval_requiredopolicy_denied - los blocked attempts casi no aparecen incluso en rutas riesgosas
- los runs llegan seguido a
max_stepso a exceso de presupuesto sin parada temprana - audit-logs no muestran qué regla exacta permitió o bloqueó una acción
- el equipo no puede explicar rápido por qué se ejecutó un tool-call concreto
Cada tool-call es una decisión operativa. Si los límites de execution no se fuerzan, el sistema de agentes se vuelve impredecible incluso en escenarios simples.
Enfoque correcto
Empieza con un conjunto mínimo pero estricto de guardrails en runtime. Cada paso o pasa controles policy o detiene el run con un stop_reason claro.
Si empiezas desde cero, no intentes implementar todo de una vez.
Primer mínimo: deny-by-default, allowlist por ruta, scope enforcement (tenant/env) y stop_reason explícito para rechazos policy.
Marco práctico:
- deny-by-default para acciones peligrosas o desconocidas
- allowlist de herramientas por rol y ruta
- scope obligatorio (
tenant_id,env) desde contexto autenticado - límites de step/time/budget para cada run
- paso separado de approval para write-operaciones riesgosas
- log de decisiones policy para cada 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)
En este esquema, el agente trabaja dentro de límites controlados: pasan las acciones permitidas y se detienen de forma transparente los pasos riesgosos o inválidos.
Prueba rápida
Si respondes "sí" a estas preguntas, tienes riesgo del anti-pattern Agents Without Guardrails:
- ¿El agente puede llamar una herramienta sin chequeo policy explícito?
- ¿En pasos riesgosos casi nunca aparecen
policy_deniedoapproval_required? - ¿El equipo no puede explicar rápido por qué se permitió una acción concreta?
Cómo se diferencia de otros anti-patterns
Write Access by Default vs Agents Without Guardrails
| Write Access by Default | Agents Without Guardrails |
|---|---|
| Problema principal: el acceso write está abierto por defecto. | Problema principal: no hay límites generales de execution para el run (policy, scope, budgets, approvals). |
| Cuándo aparece: cuando write no pasa por deny-by-default y approval-gate. | Cuándo aparece: cuando incluso rutas read/write/tool no tienen reglas runtime forzadas. |
En resumen: Write Access by Default trata de un modelo de acceso write inseguro, y Agents Without Guardrails trata de la ausencia de límites de execution en general.
Blind Tool Trust vs Agents Without Guardrails
| Blind Tool Trust | Agents Without Guardrails |
|---|---|
| Problema principal: tool output no validado entra a la decisión. | Problema principal: el sistema no limita qué acciones puede ejecutar el agente. |
| Cuándo aparece: cuando falta validación parse/schema/invariant. | Cuándo aparece: cuando decisiones policy quedan en el prompt y no en la capa de execution. |
En resumen: Blind Tool Trust trata de la confiabilidad de datos antes de actuar, y Agents Without Guardrails trata de los límites de acciones permitidas.
No Stop Conditions vs Agents Without Guardrails
| No Stop Conditions | Agents Without Guardrails |
|---|---|
| Problema principal: el ciclo no tiene condiciones de cierre claras. | Problema principal: faltan límites sistémicos de execution para acciones, permisos y acceso. |
Cuándo aparece: cuando faltan max_steps, timeout, no_progress. | Cuándo aparece: cuando el run no pasa por policy-gate, scope-check y control de acceso. |
En resumen: No Stop Conditions trata del control de fin del ciclo, y Agents Without Guardrails trata de límites más amplios de execution segura.
Autoevaluación: ¿tienes este anti-pattern?
Chequeo rápido del anti-pattern Agents Without Guardrails.
Marca los puntos para tu sistema y revisa el estado abajo.
Revisa tu sistema:
Progreso: 0/8
⚠ Hay señales de este anti-patrón
Intenta mover los pasos simples a un workflow y dejar el agente solo para decisiones complejas.
FAQ
Q: ¿Alcanza con definir restricciones en el system prompt?
A: No. El prompt sirve como intención, pero no como enforcement. Los límites críticos deben verificarse en la capa runtime.
Q: ¿Por dónde empezar si casi no hay guardrails?
A: Empieza con deny-by-default, allowlist por ruta, scope enforcement (tenant/env) y stop_reason explícito para rechazos policy.
Q: ¿Guardrails vuelve demasiado lento al sistema?
A: Guardrails agrega algo de overhead. En producción, ese costo casi siempre es menor que acciones erróneas, pérdida de presupuesto y limpieza manual de incidentes.
Qué sigue
Anti-patterns relacionados:
- Write Access by Default - cuando el acceso write queda abierto sin restricciones suficientes.
- Blind Tool Trust - cuando decisiones usan tool output no validado.
- No Stop Conditions - cuando el ciclo del agente no tiene cierre controlado.
Qué construir en su lugar:
- Allowed Actions - cómo limitar acciones del agente con reglas explícitas.
- Tool Execution Layer - dónde centralizar policy, scope y control de execution.
- Stop Conditions - cómo terminar un run de forma transparente cuando se violan límites.