Cap 4: Workflows Multi-step, Hooks y Handoffs

Por: Artiko
claudeworkflowshookshandoffscompliance

Workflows Multi-step, Hooks y Handoffs

Los workflows reales requieren más que delegación de tareas. Necesitan enforcement de reglas, normalización de datos, prerequisitos y transferencias estructuradas entre agentes o humanos.


Enforcement programático vs guidance via prompt

Hay dos formas de controlar el comportamiento de un agente:

Guidance via prompt

Instrucciones en el system prompt o tarea que Claude debería seguir:

System prompt: "Nunca proceses un reembolso mayor a $500 sin aprobación."

Claude seguirá esta instrucción la mayoría de las veces, pero no hay garantía determinística. En escenarios de alto riesgo, guidance no es suficiente.

Enforcement programático

Código que impide que una acción ocurra sin cumplir condiciones:

function processRefund(amount: number, approved: boolean) {
  if (amount > 500 && !approved) {
    throw new Error("Refunds > $500 require manager approval");
  }
  // procesar...
}

Cuándo usar cada uno

EscenarioMecanismo
Formato de respuesta preferidoGuidance (prompt)
Tono y estilo de comunicaciónGuidance (prompt)
Verificación de identidad antes de operaciones financierasEnforcement (código)
Límites de reembolsoEnforcement (código)
Bloqueo de acciones destructivasEnforcement (código)
Orden sugerido de pasosGuidance (prompt)

Regla: si el incumplimiento causa daño material (dinero, datos, seguridad), usa enforcement programático. Si es una preferencia, usa guidance.

PostToolUse hooks

Los hooks PostToolUse interceptan el resultado de una herramienta después de su ejecución y antes de que Claude lo procese. Son ideales para normalizar datos.

Normalización de timestamps

Una herramienta externa puede devolver timestamps en formatos inconsistentes:

API A: "1710547200"        (Unix epoch)
API B: "2024-03-16T00:00Z" (ISO 8601)
API C: "March 16, 2024"    (texto)

Un PostToolUse hook normaliza todo a un formato consistente:

const postToolHook = {
  event: "PostToolUse",
  matcher: { toolNames: ["get_order", "get_payment", "get_shipment"] },
  handler: async (result) => {
    // Normalizar todos los campos de fecha a ISO 8601
    return normalizeTimestamps(result);
  }
};

Claude siempre recibe ISO 8601, independientemente de la fuente.

Normalización de status codes

Diferentes APIs usan diferentes convenciones:

// Normalizar a un vocabulario consistente
const statusMap = {
  "ACTIVE": "active", "Active": "active", "1": "active",
  "INACTIVE": "inactive", "Inactive": "inactive", "0": "inactive",
  "PENDING": "pending", "In Progress": "pending",
};

Hooks para bloquear acciones

Los hooks pueden interceptar antes de ejecutar una herramienta (PreToolUse) para bloquear acciones que violan políticas:

Escalación por monto

const refundGuard = {
  event: "PreToolUse",
  matcher: { toolNames: ["process_refund"] },
  handler: async (toolCall) => {
    if (toolCall.input.amount > 500) {
      return {
        blocked: true,
        message: "Refund > $500 requires escalation to manager",
        action: "escalate",
        metadata: {
          customer_id: toolCall.input.customer_id,
          amount: toolCall.input.amount,
          reason: toolCall.input.reason,
        }
      };
    }
    return { blocked: false };
  }
};

Bloqueo de operaciones sin prerequisitos

const requireCustomerFirst = {
  event: "PreToolUse",
  matcher: { toolNames: ["process_refund", "update_subscription"] },
  handler: async (toolCall, context) => {
    if (!context.toolHistory.includes("get_customer")) {
      return {
        blocked: true,
        message: "Must call get_customer before financial operations"
      };
    }
    return { blocked: false };
  }
};

Prerequisite gates programáticos

Un prerequisite gate es un mecanismo que bloquea la ejecución de una herramienta hasta que se cumplan condiciones previas:

get_customer ──prerequisito──► process_refund
get_customer ──prerequisito──► update_subscription
verify_identity ──prerequisito──► transfer_funds

Implementación

const prerequisites: Record<string, string[]> = {
  "process_refund": ["get_customer"],
  "update_subscription": ["get_customer"],
  "transfer_funds": ["verify_identity", "get_account"],
};

function checkPrerequisites(toolName: string, history: string[]): boolean {
  const required = prerequisites[toolName] || [];
  return required.every(req => history.includes(req));
}

Esto es enforcement programático: no importa lo que diga el prompt, process_refund no puede ejecutarse sin get_customer previo.

Ventajas sobre guidance

AspectGuidance (prompt)Prerequisite gate
GarantíaBest-effortDeterminística
BypassClaude podría saltar pasosImposible
AuditoríaDifícil de verificarFácil de loguear
MantenimientoHay que actualizar promptsCódigo versionable

Structured handoff summaries

Cuando un agente transfiere una conversación a otro agente o a un humano, el handoff summary debe ser estructurado para evitar pérdida de información:

interface HandoffSummary {
  customer_id: string;
  root_cause: string;
  actions_taken: string[];
  refund_amount: number;
  recommended_action: string;
  conversation_sentiment: "positive" | "neutral" | "frustrated";
  unresolved_issues: string[];
}

Ejemplo concreto

{
  "customer_id": "CUST-12345",
  "root_cause": "Producto defectuoso recibido (modelo XYZ-100)",
  "actions_taken": [
    "Verificada identidad del cliente",
    "Confirmado pedido #ORD-98765",
    "Revisadas fotos del producto dañado"
  ],
  "refund_amount": 750,
  "recommended_action": "Aprobación de manager para refund > $500",
  "conversation_sentiment": "frustrated",
  "unresolved_issues": [
    "Cliente también solicita envío gratuito en próximo pedido"
  ]
}

Por qué estructurado

Workflow completo: soporte al cliente

Combinando todos los conceptos:

1. Cliente contacta → Agente de soporte
2. Agente llama get_customer (prereq satisfecho)
3. Agente diagnostica → root cause identificado
4. Agente intenta process_refund($750)
5. PreToolUse hook BLOQUEA: amount > $500
6. Agente genera handoff summary estructurado
7. Escalación a manager con toda la metadata
8. Manager aprueba → refund se procesa

Cada paso tiene enforcement programático donde es necesario y guidance donde es preferencia.

Resumen

ConceptoDetalle
EnforcementCódigo para acciones de alto riesgo
GuidancePrompt para preferencias de estilo
PostToolUseNormalizar datos (timestamps, status)
PreToolUseBloquear acciones sin prerequisitos
PrerequisitesGates programáticos determinísticos
HandoffsStructured summaries con campos obligatorios

Anterior: Subagentes: Invocación | Índice: Índice | Siguiente: Sesiones y Forking