Audit logs para agentes de IA: cómo reconstruir la cadena de decisiones en producción

Audit trail práctico en producción: policy decisions, stop reasons, actor/scope, redaction, immutable storage e investigación rápida de incidentes.
En esta página
  1. Idea en 30 segundos
  2. Problema
  3. Solución
  4. Audit logs ≠ debug logs
  5. Componentes del control de audit
  6. Cómo se ve en la arquitectura
  7. Ejemplo
  8. En código se ve así
  9. Cómo se ve durante la ejecución
  10. Escenario 1: policy stop
  11. Escenario 2: approval_required
  12. Escenario 3: allow + ejecución
  13. Errores típicos
  14. Autoevaluación
  15. FAQ
  16. Dónde encaja Audit Logs en el sistema
  17. Páginas relacionadas

Idea en 30 segundos

Audit logs es el diario centralizado de runtime sobre decisiones del agente: qué pasó, por qué pasó y quién lo inició.

Cuándo se necesita:
cuando un agente trabaja con tools, approval, límites, y cualquier incidente debe analizarse con hechos, no con suposiciones.

Problema

Sin audit logs, el equipo ve síntomas, pero no ve la cadena de decisiones. En demo casi no se nota. En producción, cada incidente se vuelve una "adivinación" manual.

Consecuencias típicas:

  • no queda claro por qué hubo deny o stop
  • es imposible reconstruir qué step exacto produjo side effects (cambios de estado)
  • cuesta explicar al cliente quién cambió policy o activó una restricción y cuándo

Analogía: es como investigar un choque sin grabación de cámara. Está el resultado, pero no hay una secuencia verificable de eventos.

Y cada minuto sin un audit trail de calidad alarga el incidente y aumenta el tiempo de recuperación.

Solución

La solución es agregar una capa audit centralizada en runtime que registre tanto policy decisions como el hecho de ejecución de la acción. Cada step del agente registra un evento estandarizado: decision, reason, action, scope, actor, timestamp.

Para runtime es clave un modelo único de decisiones:

  • allow
  • stop
  • approval_required

También es importante loguear no solo bloqueos, sino ejecución exitosa. Si no, en incidente ves "por qué se bloqueó", pero no "qué se ejecutó realmente".

Audit logs ≠ debug logs

Resuelven tareas distintas:

  • Audit logs: diario estructurado y reproducible de decisiones y acciones.
  • Debug logs: detalles técnicos para diagnóstico local.

Uno sin el otro no alcanza:

  • sin audit logs no hay historial de decisiones confiable legal y operativamente
  • sin debug logs cuesta depurar detalles de implementación en local

Ejemplo:

  • audit: decision=stop, reason=rate_limited_tenant, tenant_id=t_42, action=crm.search
  • debug: stack trace, retries internos, latencia de dependencias individuales

Componentes del control de audit

Estos componentes trabajan juntos en cada step del agente.

ComponenteQué controlaMecánicas clavePara qué
Event identityUnicidad del eventorun_id + step_id
event timestamp
Permite reconstruir la secuencia completa sin huecos
Decision contextRazón de la decisión policydecision / reason
policy layer name
Explica por qué la acción se ejecutó o se detuvo
Action contextQué hizo exactamente el agenteaction + action_key
scope (user/tenant/global)
Conecta policy con la acción real ejecutada
Data safetyRiesgo de fuga de datos sensiblesargs hash
redaction policy
Conserva valor de auditoría sin secretos crudos ni PII
Immutable storageIntegridad del auditappend-only sink
retention + access control
Protege el log contra edición silenciosa tras incidentes

Ejemplo de alerta:

Slack: 🛑 Support-Agent decision=stop, reason=approval_required, tenant=t_42, run_id=run_981.

Cómo se ve en la arquitectura

La capa audit está en el runtime loop y registra decisiones antes y después de ejecutar la siguiente acción del agente. Cada outcome (allow, stop, approval_required) se escribe en un audit trail centralizado. Aquí, policy layer es una capa lógica dentro de runtime, no un servicio separado.

Cada step pasa por este flow antes de ejecutarse: runtime no ejecuta acción directo hasta que policy devuelve decisión y el evento queda registrado en audit.

Resumen del flow:

  • Runtime forma la siguiente acción del agente
  • Policy devuelve allow, stop o approval_required
  • Runtime registra pre-event con decision y reason
  • si la acción se ejecutó, registra post-event con result
  • ambos tipos de eventos quedan disponibles para búsqueda, alerting e investigación

Ejemplo

El agente de soporte recibe solicitud refund.create. Policy devuelve approval_required.

Resultado:

  • la ejecución no inicia sin aprobación
  • en audit se ve decision=approval_required, actor, scope, action_key
  • tras aprobar, se ve un evento separado decision=allow y el resultado de ejecución

Audit logs reduce el tiempo de investigación de incidente al nivel de steps de runtime, no después de recolectar artefactos manualmente.

En código se ve así

El esquema simplificado de arriba muestra el flujo principal. Punto crítico: los eventos de audit deben ser estructurados y consistentes con el esquema; si no, la búsqueda de incidentes se rompe.

Ejemplo de configuración de audit:

YAML
audit:
  sink: append_only
  retention_days: 180
  redact_fields: ["email", "phone", "card_number"]
  hash_args: true
  sign_events: true
PYTHON
action = planner.next(state)
action_key = make_action_key(action.name, action.args)
decision = policy.evaluate(action, state.user_context)

base_event = {
    "run_id": run_id,
    "step_id": state.step,
    "tenant_id": state.tenant_id,
    "action": action.name,
    "action_key": action_key,
    "timestamp": clock.iso(),
}

audit.log(
    **base_event,
    phase="pre_exec",
    decision=decision.outcome,
    reason=decision.reason,
    args_hash=hash_args(action.args),
)

if decision.outcome == "approval_required":
    # approval resume flow se registra como step runtime separado:
    # approval_required -> approval_granted -> allow -> result
    return stop("approval_required")

if decision.outcome == "stop":
    return stop(decision.reason)

result = executor.execute(action)

audit.log(
    **base_event,
    phase="post_exec",
    decision=decision.outcome,
    reason=decision.reason,
    result=result.status,
)

return result

Cómo se ve durante la ejecución

Escenario 1: policy stop

  1. Runtime forma acción crm.search.
  2. Policy devuelve stop (reason=rate_limited_tenant).
  3. Runtime escribe pre-event en audit.
  4. La acción no se ejecuta.
  5. El equipo ve stop reason de inmediato en logs.

Escenario 2: approval_required

  1. Runtime forma refund.create.
  2. Policy devuelve approval_required.
  3. Runtime escribe pre-event y detiene ejecución.
  4. Tras decisión humana, inicia un step separado.
  5. En audit se ve el camino completo: approval_required -> allow -> result.

Escenario 3: allow + ejecución

  1. Runtime forma la siguiente acción.
  2. Policy devuelve allow.
  3. Runtime ejecuta acción.
  4. Escribe post-event con result.
  5. El diario contiene decisión y resultado de ejecución.

Errores típicos

  • loguear solo stop, pero no loguear allow
  • guardar args crudos sin redaction/hash
  • no tener action_key estable para deduplicación
  • mezclar audit y debug en un único texto no estructurado
  • no registrar actor para cambios de policy y acciones de operador
  • permitir editar o borrar eventos de audit retroactivamente

Resultado: el log existe, pero en incidente no da una imagen verificable.

Autoevaluación

Chequeo rápido de audit logging antes de lanzar a producción:

Progreso: 0/8

⚠ Faltan controles base de governance

Antes de production necesitas como mínimo control de acceso, límites, audit logs y parada de emergencia.

FAQ

P: ¿En qué se diferencian audit logs y traces?
R: Trace muestra la ruta técnica de ejecución; audit log muestra policy decisions y acciones en términos de quién/qué/por qué. En incidentes, normalmente se necesitan ambos.

P: ¿Se pueden loguear args completos por comodidad?
R: Mejor no. En producción, es más seguro guardar hash o versión redacted para evitar fugas de secretos y PII.

P: ¿Cuál es el set mínimo obligatorio de campos?
R: Mínimo: run_id, step_id, decision, reason, action, action_key, scope, timestamp.

P: ¿Cuándo escribir evento: antes o después de ejecutar?
R: Ambos momentos importan: pre-event fija la decisión; post-event fija el hecho y resultado de ejecución.

P: ¿Dónde almacenar audit logs?
R: En almacenamiento centralizado append-only con acceso controlado, retention y búsqueda rápida por run_id/tenant_id/reason.

Dónde encaja Audit Logs en el sistema

Audit logs es la capa base de transparencia en Agent Governance. Junto con RBAC, límites, budget controls, approval y kill switch, da un comportamiento del agente controlable y explicable en producción.

Páginas relacionadas

Siguiente sobre este tema:

⏱️ 7 min de lecturaActualizado 27 de marzo de 2026Dificultad: ★★★
Implementar en OnceOnly
Budgets + permissions you can enforce at the boundary.
Usar en 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
writes:
  require_approval: true
  idempotency: true
controls:
  kill_switch: { enabled: true }
Integrado: control en producciónOnceOnly
Guardrails para agentes con tool-calling
Lleva este patrón a producción con gobernanza:
  • Presupuestos (pasos / topes de gasto)
  • Permisos de herramientas (allowlist / blocklist)
  • Kill switch y parada por incidente
  • Idempotencia y dedupe
  • Audit logs y trazabilidad
Mención integrada: OnceOnly es una capa de control para sistemas de agentes en producción.

Autor

Nick — ingeniero que construye infraestructura para agentes de IA en producción.

Enfoque: patrones de agentes, modos de fallo, control del runtime y fiabilidad del sistema.

🔗 GitHub: https://github.com/mykolademyanov


Nota editorial

Esta documentación está asistida por IA, con responsabilidad editorial humana sobre la exactitud, la claridad y la relevancia en producción.

El contenido se basa en fallos reales, post-mortems e incidentes operativos en sistemas de agentes de IA desplegados.