Guía técnica

Decisiones de IA que puedes defender: Auditabilidad, Trazabilidad y Pruebas en Producción

Cómo construir sistemas de IA con trazabilidad total de decisiones. Eventos de auditoría estructurados, recibos HMAC, cadenas de decisiones por sesión, registros de aprobación humana y arquitectura de retención.

5 de marzo de 202618 min de lecturaEquipo de Ingeniería Oronts

"¿Qué hizo la IA y puedes demostrarlo?"

Esta pregunta surge en cada despliegue de IA empresarial. No viene de los ingenieros. Viene de legal, cumplimiento, compras y la junta directiva. La respuesta que necesitan no es "usamos GPT-4" ni "el modelo se entrenó con nuestros datos." Necesitan datos específicos: qué datos entraron, qué modelo los procesó, qué herramientas se invocaron, qué humano aprobó la acción y si el registro se puede verificar después de los hechos.

La mayoría de los sistemas de IA no pueden responder esta pregunta. Registran prompts y respuestas (si acaso), pero esos logs no te dicen la cadena de decisiones. No te dicen por qué el sistema eligió la opción A sobre la B. No te dicen quién aprobó una acción de alto valor. Y definitivamente no proporcionan pruebas a prueba de manipulación de que el registro no se ha modificado desde que se tomó la decisión.

Nosotros construimos trazabilidad de decisiones en múltiples sistemas de IA en producción. Este artículo cubre los patrones de arquitectura que hacen que las decisiones de IA sean defendibles. No teóricamente defendibles. Demostrablemente defendibles, con recibos criptográficos y registros inmutables.

Para contexto sobre cómo abordamos la gobernanza de IA de forma general y los sistemas con humano en el bucle en particular, esas guías cubren patrones relacionados. Este artículo se centra en la capa de pruebas: qué registrar, cómo estructurarlo y cómo hacerlo verificable.

Qué significa realmente la trazabilidad de decisiones

La trazabilidad de decisiones no es logging. El logging te dice qué pasó. La trazabilidad te dice por qué pasó, quién lo autorizó y si el registro es confiable.

CapacidadLogging estándarTrazabilidad de decisiones
Qué pasóTexto de prompt y respuestaEvento de decisión estructurado con campos tipados
Qué modeloQuizás en los headersExplícito: ID del modelo, versión, proveedor, temperature
Qué datos se usaronPrompt sin procesar (contiene PII)IDs de tokens referenciando mapeo de sesión (sin PII)
Qué herramientas se llamaronQuizás en logs de debugCadena de llamadas a herramientas estructurada con entradas y salidas
Quién lo aprobóNo se rastreaRegistro de aprobación: quién, cuándo, qué vio, qué decidió
¿Se puede verificar?No (los logs se pueden editar)Recibo HMAC: a prueba de manipulación, firmado criptográficamente
RetenciónLo que tu agregador de logs conserveBasado en políticas: 90 días operativo, 7 años archivo

La diferencia importa cuando un cliente disputa una recomendación generada por IA, cuando un regulador pregunta cómo se tomó una decisión, o cuando una auditoría interna necesita verificar que el sistema de IA siguió la política.

El esquema del evento de decisión

Cada decisión de IA genera un evento estructurado. No una línea de log. Un registro tipado con campos explícitos para cada dimensión de la decisión.

interface AiDecisionEvent {
    // Identidad
    event_id: string;              // UUID, único por evento
    event_type: string;            // "transform", "rehydrate", "tool_call", "agent_action", "approval"
    timestamp: string;             // ISO 8601 UTC

    // Actor
    actor_type: string;            // "agent" | "human" | "system" | "scheduler"
    actor_id: string;              // ID del hilo del agente, ID de usuario o nombre del componente del sistema

    // Contexto
    tenant_id: string;             // alcance multi-tenant
    session_id: string;            // agrupa eventos dentro de una sesión
    correlation_id: string;        // enlaza eventos relacionados entre servicios
    channel_id?: string;           // qué canal (web, api, widget)

    // Modelo
    model_provider?: string;       // "openai" | "anthropic" | "local"
    model_id?: string;             // "gpt-4o" | "claude-sonnet-4-20250514"
    model_version?: string;        // versión de despliegue o checkpoint

    // Decisión
    action: string;                // qué se hizo: "generate_response", "call_tool", "approve_order"
    input_summary: object;         // resumen estructurado (SIN PII sin procesar, solo IDs de tokens y tipos)
    output_summary: object;        // resumen estructurado del resultado
    decision_rationale?: string;   // por qué se tomó esta acción (del razonamiento del agente)

    // Política
    policy_id?: string;            // qué política se evaluó
    policy_result?: string;        // "allowed" | "denied" | "escalated"
    policy_conditions?: object;    // qué condiciones se verificaron

    // Aprobación (si HITL)
    approval_required: boolean;
    approval_status?: string;      // "pending" | "approved" | "rejected"
    approved_by?: string;          // ID de usuario del aprobador
    approved_at?: string;          // cuándo se dio la aprobación
    approval_context?: object;     // qué vio el aprobador al decidir

    // Integridad
    receipt_hmac?: string;         // HMAC-SHA256 del payload del evento
    previous_event_id?: string;    // enlace de cadena al evento anterior en la sesión
}

Las decisiones de diseño clave:

Sin PII en los eventos. El campo input_summary contiene IDs de tokens (p_001, e_001) y tipos de entidad, nunca valores sin procesar. Esto significa que tu almacenamiento de auditoría no se convierte en un sistema regulado por GDPR. Consulta nuestra guía de cumplimiento GDPR para la arquitectura completa.

Identificación explícita del modelo. No solo "usamos un LLM." Se registra el proveedor específico, el ID del modelo y la versión. Cuando un modelo se actualiza o reemplaza, puedes rastrear qué decisiones usaron qué versión.

Enlace en cadena. El campo previous_event_id crea una cadena enlazada de eventos dentro de una sesión. El evento 3 apunta al evento 2, que apunta al evento 1. La cadena prueba la secuencia de decisiones y que no se insertaron ni eliminaron eventos después de los hechos.

Cadenas de decisiones por sesión

Una sola interacción con IA frecuentemente involucra múltiples decisiones. Un agente de soporte al cliente podría: leer el ticket (evento 1), buscar información del cliente (evento 2), verificar la facturación (evento 3), redactar una respuesta (evento 4) y enviar el correo (evento 5). Cada paso es un evento de decisión. Juntos, forman una cadena de decisiones.

┌──────────────────────────────────────────────────────┐
│                  SESSION: sess_abc123                  │
│                                                       │
│  Evento 1        Evento 2        Evento 3             │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐         │
│  │ LEER     │──▶│ BUSCAR   │──▶│ VERIFICAR│         │
│  │ TICKET   │   │ CLIENTE  │   │ FACTURA  │         │
│  │          │   │          │   │          │         │
│  │ model:   │   │ tool:    │   │ tool:    │         │
│  │ claude   │   │ crm_api  │   │ billing  │         │
│  │          │   │          │   │ _api     │         │
│  │ tokens:  │   │ tokens:  │   │ tokens:  │         │
│  │ p_001    │   │ cid_001  │   │ o_001    │         │
│  └──────────┘   └──────────┘   └──────────┘         │
│       │              │              │                 │
│       ▼              ▼              ▼                 │
│  Evento 4        Evento 5                             │
│  ┌──────────┐   ┌──────────┐                         │
│  │ REDACTAR │──▶│ ENVIAR   │                         │
│  │ RESPUESTA│   │ EMAIL    │                         │
│  │          │   │          │                         │
│  │ model:   │   │ channel: │                         │
│  │ claude   │   │ email    │                         │
│  │          │   │          │                         │
│  │ policy:  │   │ restore: │                         │
│  │ support  │   │ formatted│                         │
│  └──────────┘   └──────────┘                         │
│                                                       │
└──────────────────────────────────────────────────────┘

Cada evento referencia al anterior. La cadena es verificable: si alguien elimina el evento 3, la cadena del evento 4 al evento 2 tiene un hueco. Si alguien inserta un evento falso entre el 2 y el 3, los enlaces de la cadena no coinciden.

Consultar la cadena

Cuando un auditor pregunta "¿qué pasó con la sesión X?", consultas por session_id y reconstruyes la cadena:

async function getDecisionChain(sessionId: string): Promise<AiDecisionEvent[]> {
    const events = await this.eventStore.findBySessionId(sessionId, {
        orderBy: 'timestamp',
        direction: 'ASC',
    });

    // Verificar integridad de la cadena
    for (let i = 1; i < events.length; i++) {
        if (events[i].previous_event_id !== events[i - 1].event_id) {
            throw new ChainIntegrityError(
                `Chain broken at event ${events[i].event_id}: ` +
                `expected previous ${events[i - 1].event_id}, ` +
                `got ${events[i].previous_event_id}`
            );
        }
    }

    return events;
}

Para ver cómo manejamos verificación de cadena similar en transacciones de comercio, consulta nuestra guía de comercio agéntico que usa recibos HMAC con el mismo propósito.

Recibos HMAC: prueba a prueba de manipulación

Los eventos de decisión almacenados en una base de datos se pueden modificar. Un recibo HMAC demuestra que los datos del evento no han cambiado desde que se crearon.

function signDecisionEvent(event: AiDecisionEvent, tenantSecret: string): string {
    // Forma canónica: claves ordenadas, JSON determinista
    const canonical = JSON.stringify(event, Object.keys(event).sort());
    return crypto.createHmac('sha256', tenantSecret).update(canonical).digest('hex');
}

function verifyDecisionEvent(event: AiDecisionEvent, storedHmac: string, tenantSecret: string): boolean {
    const recomputed = signDecisionEvent(event, tenantSecret);
    return crypto.timingSafeEqual(
        Buffer.from(recomputed, 'hex'),
        Buffer.from(storedHmac, 'hex')
    );
}

Cada evento de decisión se firma en el momento de creación. El HMAC se almacena junto al evento. Para verificar, se recalcula el HMAC a partir de los datos actuales del evento y se compara. Si se modificó un solo campo después de la firma, el HMAC no coincidirá.

PropiedadValor
AlgoritmoHMAC-SHA256
ClaveSecreto por tenant (rotado anualmente)
CanonicalizaciónJSON.stringify(payload, Object.keys(payload).sort())
SalidaString codificado en hex (64 caracteres)
ComparaciónTiming-safe (crypto.timingSafeEqual)

El secreto por tenant significa que los recibos de un tenant no se pueden verificar usando la clave de otro tenant. La rotación de claves incluye un período de superposición de 24 horas donde tanto la clave antigua como la nueva se aceptan para verificación.

Registros de aprobación humana

Cuando una decisión requiere aprobación humana (transacciones de alto valor, acceso a datos sensibles, excepciones de política), la aprobación en sí misma es un evento de decisión con campos específicos:

interface ApprovalEvent extends AiDecisionEvent {
    event_type: 'approval';
    approval_required: true;

    // Lo que el humano vio al decidir
    approval_context: {
        original_request: string;      // resumen de lo que se solicitó
        estimated_impact: string;      // "Order for 2,500 EUR from supplier Alpha"
        policy_triggered: string;      // "require_human_approval_above: 500"
        agent_recommendation: string;  // lo que el agente sugirió
        risk_flags: string[];          // alertas mostradas al aprobador
    };

    // Lo que el humano decidió
    approved_by: string;               // ID de usuario
    approved_at: string;               // ISO 8601
    approval_status: 'approved' | 'rejected';
    rejection_reason?: string;         // si se rechazó, por qué
    approval_duration_ms: number;      // cuánto tardó el humano en decidir
}

El campo approval_context es crítico. Registra qué información se le presentó al humano cuando tomó su decisión. Esto previene el argumento "lo aprobé pero no sabía X." El registro muestra exactamente lo que el aprobador vio.

approval_duration_ms también es útil para auditoría. Si un aprobador aprueba consistentemente en menos de 2 segundos, eso sugiere aprobación mecánica en lugar de revisión genuina. Los equipos de cumplimiento usan esta métrica para evaluar si la supervisión humana es significativa.

Qué NO registrar

La trazabilidad de decisiones requiere disciplina sobre lo que entra en la pista de auditoría.

Sí registrar:

  • IDs de tokens y tipos de entidad (por ejemplo, "entidad p_001 de tipo persona fue detectada")
  • Identificadores y versiones de modelos
  • Nombres de llamadas a herramientas y parámetros estructurados
  • Resultados de evaluación de políticas
  • Registros de aprobación con contexto
  • Información de tiempo (latencias, duraciones)
  • Códigos de error y razones de fallo

NO registrar:

  • PII sin procesar (nombres, correos, números de teléfono, direcciones)
  • Texto completo del prompt (contiene PII y es enorme)
  • Respuestas completas del modelo (mismos problemas)
  • Credenciales de autenticación o API keys
  • Contraseñas internas del sistema o cadenas de conexión
// Bueno: estructurado, libre de PII
{
    event_type: "transform",
    action: "detect_and_tokenize",
    input_summary: {
        entities_detected: 3,
        entity_types: ["person", "email", "customer_id"],
        token_ids: ["p_001", "e_001", "cid_001"],
        detection_confidence: [0.95, 1.0, 0.99],
    },
    policy_id: "german-support",
    model_id: "ner-spacy-de",
    duration_ms: 12,
}

// Malo: contiene PII, inútil para consultas estructuradas
{
    event_type: "transform",
    action: "process_input",
    input: "Hallo, ich bin Sara Mustermann, meine Kundennummer ist 948221...",
    output: "Hallo, ich bin {{person:p_001}}...",
}

El ejemplo bueno es consultable ("muéstrame todos los eventos donde la confianza de detección fue menor a 0.8"), filtrable ("muéstrame todos los eventos para la política german-support") y libre de PII. El ejemplo malo es un bloque de texto que se convierte en una responsabilidad GDPR.

Para la arquitectura completa de logging seguro para PII en sistemas de IA, consulta nuestra guía de observabilidad de IA.

Arquitectura de retención

Los eventos de decisión tienen diferentes requisitos de retención dependiendo de su contexto regulatorio:

NivelAlmacenamientoRetenciónConsultableCaso de uso
CalienteBase de datos (PostgreSQL / DynamoDB)90 díasSQL/consulta completaDepuración, dashboards operativos, monitoreo en tiempo real
TempladoObject storage (S3)2 añosPor session_id, rango de fechasAuditorías internas, disputas de clientes, revisiones de cumplimiento
FríoObject storage con bloqueos write-once7 añosSolo por session_idAuditorías regulatorias, retenciones legales, cumplimiento financiero

El nivel frío usa object storage con bloqueos en modo de cumplimiento. Una vez escritos, los registros no se pueden modificar ni eliminar hasta que expire el período de retención. Esto no es solo control de acceso. El sistema de almacenamiento impide físicamente la eliminación, incluso por administradores.

Evento de Decisión Creado
  │
  ├──▶ Nivel Caliente (base de datos): escritura inmediata, consultable
  │
  ├──▶ Nivel Templado (object storage): exportación diaria por lotes
  │
  └──▶ Nivel Frío (object storage con bloqueo): streaming desde la base
       de datos vía change data capture, write-once, bloqueo de 7 años

El streaming de la base de datos al almacenamiento frío ocurre a través de change data capture (streams de base de datos o envío WAL). Los eventos se escriben en el archivo inmutable en minutos desde su creación. No hay un batch job que se ejecute diariamente y pueda perder eventos. El stream es continuo.

Correlación entre servicios

En un sistema de IA distribuido, una sola solicitud de usuario puede tocar múltiples servicios: un API gateway, un runtime de protección de datos, un proveedor de LLM, un servidor de herramientas y un servicio de auditoría. El correlation_id une todos los eventos de decisión de todos los servicios.

// El API gateway genera el correlation_id
const correlationId = generateUUID();

// Cada servicio downstream lo recibe
const response = await dataProtection.transform(input, {
    headers: { 'X-Correlation-Id': correlationId },
});

// Cada evento de decisión lo incluye
const event: AiDecisionEvent = {
    correlation_id: correlationId,
    // ...
};

Al depurar o auditar, consulta por correlation_id para obtener el panorama completo de todos los servicios. Este es el mismo patrón usado en trazado distribuido, pero aplicado específicamente a eventos de decisión en lugar de trazas de rendimiento.

Implementación práctica

Elección de almacenamiento

RequisitoPostgreSQLDynamoDBEvent Store (ej. EventStoreDB)
Consultas estructuradasExcelenteLimitado (clave-valor)Limitado (basado en streams)
Throughput de escrituraBueno (con connection pooling)Excelente (auto-scaling)Excelente
Integridad de cadenaA nivel de aplicaciónA nivel de aplicaciónIntegrado (streams append-only)
Políticas de retenciónA nivel de aplicaciónTTL en itemsIntegrado
Costo a escalaFijo (basado en servidor)Pago por solicitudFijo

Para la mayoría de las implementaciones, PostgreSQL es la elección correcta para el nivel caliente. Es consultable, transaccional, y tu equipo ya lo conoce. DynamoDB funciona bien si estás en AWS y necesitas throughput de escritura con auto-scaling. Un event store dedicado es excesivo a menos que tengas miles de eventos de decisión por segundo.

Patrones de consulta

Las consultas más comunes contra el almacén de eventos de decisión:

-- Todas las decisiones en una sesión (reconstruir la cadena)
SELECT * FROM ai_decision_events
WHERE session_id = $1
ORDER BY timestamp ASC;

-- Todas las decisiones de un agente específico en las últimas 24 horas
SELECT * FROM ai_decision_events
WHERE actor_type = 'agent' AND actor_id = $1
AND timestamp > NOW() - INTERVAL '24 hours'
ORDER BY timestamp DESC;

-- Todas las evaluaciones de política denegadas (encontrar políticas mal configuradas)
SELECT * FROM ai_decision_events
WHERE policy_result = 'denied'
AND timestamp > NOW() - INTERVAL '7 days'
ORDER BY timestamp DESC;

-- Todas las aprobaciones humanas con tiempo de revisión corto (detección de aprobación mecánica)
SELECT * FROM ai_decision_events
WHERE event_type = 'approval'
AND approval_status = 'approved'
AND approval_duration_ms < 3000
AND timestamp > NOW() - INTERVAL '30 days';

-- Verificar integridad de la cadena para una sesión
SELECT e1.event_id, e1.previous_event_id,
       CASE WHEN e2.event_id IS NULL AND e1.previous_event_id IS NOT NULL
            THEN 'BROKEN' ELSE 'OK' END as chain_status
FROM ai_decision_events e1
LEFT JOIN ai_decision_events e2 ON e1.previous_event_id = e2.event_id
WHERE e1.session_id = $1;

Indexación

CREATE INDEX idx_session ON ai_decision_events (session_id, timestamp);
CREATE INDEX idx_actor ON ai_decision_events (actor_type, actor_id, timestamp);
CREATE INDEX idx_correlation ON ai_decision_events (correlation_id);
CREATE INDEX idx_policy_result ON ai_decision_events (policy_result, timestamp);
CREATE INDEX idx_approval ON ai_decision_events (event_type, approval_status, timestamp)
    WHERE event_type = 'approval';

Errores comunes

  1. Registrar prompts sin procesar como pista de auditoría. Los prompts contienen PII. Tu almacenamiento de auditoría se convierte en un sistema regulado por GDPR. Usa eventos estructurados con IDs de tokens en su lugar.

  2. Sin enlace de cadena entre eventos. Sin previous_event_id, no puedes probar la secuencia de decisiones. Los eventos se pueden insertar, eliminar o reordenar sin detección.

  3. Sin firma HMAC. Los registros de base de datos se pueden modificar. Sin recibos criptográficos, la pista de auditoría no es a prueba de manipulación. "Confía en nosotros, no editamos los logs" no es defendible.

  4. Misma retención para todo. Los datos de depuración necesitan 90 días. Los datos de cumplimiento necesitan 7 años. Mezclarlos desperdicia dinero (guardar datos de depuración demasiado tiempo) o crea riesgos (eliminar datos de cumplimiento demasiado pronto).

  5. Sin contexto de aprobación. Registrar que "el usuario X aprobó la acción Y" no es suficiente. Registra qué información vio el aprobador al decidir. Sin contexto, la aprobación no tiene sentido para la auditoría.

  6. Falta detección de aprobación mecánica. Si la supervisión humana es un requisito de cumplimiento, necesitas verificar que los humanos realmente están revisando, no solo haciendo clic en "aprobar" de forma reflexiva. Rastrea approval_duration_ms.

  7. Sin correlación entre servicios. Si tu sistema de IA abarca múltiples servicios, los eventos de cada servicio están aislados. Sin un correlation_id, no puedes reconstruir la cadena de decisiones completa.

  8. Almacenamiento frío mutable. Si tu archivo a largo plazo se puede editar o eliminar por administradores, no es una pista de auditoría. Usa almacenamiento write-once con bloqueos en modo de cumplimiento.

Conclusiones clave

  • "Usamos GPT-4" no es una respuesta defendible. Registra el modelo específico, la versión, el proveedor, los tokens de entrada, los tokens de salida, las herramientas invocadas, las políticas evaluadas y los humanos que aprobaron. Cada dimensión de la decisión.

  • Eventos estructurados, no líneas de log. Los campos tipados permiten consultas estructuradas, dashboards, detección de anomalías e informes de cumplimiento. Los logs de texto libre no permiten nada excepto grep.

  • Sin PII en eventos de decisión. Usa IDs de tokens de tu capa de protección de datos. La pista de auditoría no debe convertirse en sí misma en una responsabilidad de protección de datos.

  • El enlace de cadena prueba la secuencia. Cada evento apunta a su predecesor. Los huecos e inserciones son detectables. Combinado con la firma HMAC, la cadena es a prueba de manipulación.

  • Los recibos HMAC proporcionan prueba criptográfica. Claves de firma por tenant, serialización JSON canónica, comparación timing-safe. Cualquier modificación a cualquier campo invalida el recibo.

  • Los registros de aprobación humana deben incluir contexto. ¿Qué vio el aprobador? ¿Cuánto tiempo tardó? Sin esto, "supervisión humana" es un checkbox, no un control.

  • La retención en tres niveles refleja la realidad regulatoria. Caliente para depuración (90 días), templado para auditorías (2 años), frío con bloqueos write-once para reguladores (7 años).

Aplicamos estos patrones en todos nuestros sistemas de IA, desde runtimes de protección de datos hasta plataformas de comercio agéntico. Si estás construyendo sistemas de IA que necesitan satisfacer requisitos de cumplimiento empresarial, habla con nuestro equipo o solicita un presupuesto. Puedes explorar nuestros servicios de IA, nuestro enfoque de confianza y cumplimiento, y nuestras guías sobre arquitectura de sistemas de IA y modos de fallo de IA para más contexto.

Temas cubiertos

auditabilidad IAtrazabilidad IAregistro de decisiones IAauditoría de cumplimiento IAprueba de decisiones IAgobernanza IA producciónauditoría LLMresponsabilidad IA

¿Listo para construir sistemas de IA listos para producción?

Nuestro equipo se especializa en sistemas de IA listos para producción. Hablemos de cómo podemos ayudar.

Iniciar una conversación