Módulo 9: Human-in-the-Loop

Introducción: Agentes con Oversight Humano

Descripción

Tu AI Research Assistant es persistente. Tiene checkpointing con MemorySaver, crash recovery, time-travel debugging, long-term memory con Store, y soporte multi-usuario con thread_id. Lo construiste en el Módulo 8 y es un sistema que recuerda.

Pero recuerda todo y actúa sobre todo sin preguntar.

Imagina este escenario: le pides a tu agente "investiga las mejores herramientas de AI para healthcare." El agente descompone la consulta, busca en la web, y decide que necesita datos más profundos. Entonces:

  1. Llama a una API de papers académicos que cobra $0.10 por consulta — 50 veces
  2. Encuentra un resultado relevante y decide enviarlo por email al equipo
  3. Para "limpiar" los datos temporales, ejecuta un DELETE en la tabla de resultados parciales

Nadie le pidió que hiciera el paso 2 ni el 3. Y el paso 1 costó $5 cuando $0.50 habría bastado. Cada una de estas acciones era técnicamente correcta según la lógica del agente — pero operacionalmente inaceptable sin supervisión.

La autonomía del agente es un privilegio, no un derecho. Tú decides cuánta libertad darle.

Eso es Human-in-the-Loop (HITL): la capacidad de pausar la ejecución de un agente, mostrarle al humano lo que planea hacer, y esperar una decisión antes de continuar. No es un parche de seguridad — es una decisión de diseño fundamental que separa prototipos de sistemas de producción.


¿Dónde estamos en la guía?

Este es el Módulo 9 de la guía LangChain & LangGraph: From Chains to Agents. Es el segundo módulo del Bloque 3 (LangGraph Avanzado).

Bloque 1: LangChain Core (Módulos 1-4)           ✅ Completado
Bloque 2: LangGraph Fundamentals (Módulos 5-7)   ✅ Completado
Bloque 3: LangGraph Avanzado (Módulos 8-10)      ← ESTÁS AQUÍ (Módulo 9)
Bloque 4: Producción (Módulos 11-12)
Tu progreso:

Bloque 1 — LangChain Core                   ✅ Completado
    │
    │  Módulo 1: Modelos y Proveedores       ✅
    │  Módulo 2: Tools y Tool Calling        ✅
    │  Módulo 3: Agents (create_agent)       ✅
    │  Módulo 4: Middleware y Customización   ✅
    │
    ▼
Bloque 2 — LangGraph Fundamentals           ✅ Completado
    │
    │  Módulo 5: Introducción a LangGraph    ✅
    │  Módulo 6: Functional API              ✅
    │  Módulo 7: Flujos Avanzados            ✅
    │
    ▼
Bloque 3 — LangGraph Avanzado
    │
    │  Módulo 8: Memoria y Persistencia      ✅ Completado
    │  Módulo 9: Human-in-the-Loop           ← ESTÁS AQUÍ
    │  Módulo 10: Multi-Agent Systems        🔒 Siguiente
    │
    ▼
Bloque 4 — Producción                       🔒
    │
    │  Módulo 11: Deep Agents                🔒
    │  Módulo 12: LangSmith y Producción     🔒

El Bloque 3 convierte tus herramientas de construcción en capacidades enterprise. El Módulo 8 te dio persistencia (checkpointing, memoria, multi-usuario). Este módulo agrega supervisión humana. El Módulo 10 escalará a múltiples agentes coordinados.


El puente desde el Módulo 8

Lo que ya tienes

Tu Research Agent v3 es un sistema persistente:

  • ✅ Checkpointing con MemorySaver: el estado se guarda después de cada nodo
  • ✅ Crash recovery: si el proceso se interrumpe, resume desde el último checkpoint
  • ✅ Time-travel debugging: puedes navegar el historial de estados y crear bifurcaciones
  • ✅ Long-term memory: recuerda preferencias del usuario entre sesiones
  • ✅ Multi-usuario: cada thread_id tiene su propio contexto aislado

La pregunta que falta

Tu agente recuerda y persiste. Pero, ¿debería actuar sobre todo de forma autónoma?

Tu agente recibe: "Investiga las tendencias de AI en finanzas"

Con persistencia (M8):
  ✅ Guarda el progreso paso a paso
  ✅ Puede resumir si se interrumpe
  ✅ Recuerda investigaciones previas

Sin supervisión (todavía):
  ❌ Llama a APIs de pago sin preguntar
  ❌ Decide enviar emails sin aprobación
  ❌ Ejecuta queries destructivas "para optimizar"
  ❌ Sigue una dirección equivocada sin que puedas corregirlo

El checkpointing del Módulo 8 es el prerequisito técnico de HITL. Para que un agente se pause y espere aprobación humana, necesita guardar su estado en un checkpoint, esperar indefinidamente, y luego resumir exactamente donde se pausó. Sin persistencia, el agente no puede "recordar" dónde estaba cuando lo pausaste.


Por qué no todo debe ser autónomo

Ejemplo 1: La acción costosa

Agente: "Para investigar a fondo, voy a consultar estas APIs:"
  - Google Scholar API: $0.10/consulta × 50 consultas = $5.00
  - Patent API: $0.25/consulta × 20 consultas = $5.00
  - News API Premium: $0.05/consulta × 100 consultas = $5.00
  
  Total estimado: $15.00

Sin HITL: El agente ejecuta todo. Recibes la factura.
Con HITL: "¿Procedo con $15 en APIs? [sí/no/reducir consultas]"
  → Usuario: "Reduce a 10 consultas por fuente"
  → Total: $4.00 — mismo resultado útil, 73% menos costo

Ejemplo 2: La acción irreversible

Agente: "Encontré datos duplicados en la tabla de resultados."
  → Decisión autónoma: DELETE FROM research_results WHERE is_duplicate = true
  
Sin HITL: 200 registros eliminados. Algunos no eran realmente duplicados.
Con HITL: "Encontré 200 posibles duplicados. ¿Los elimino? [sí/no/revisar lista]"
  → Usuario: "Muéstrame los primeros 10"
  → Usuario revisa: "Estos 3 no son duplicados. Elimina los otros 197."

Ejemplo 3: La acción con impacto externo

Agente: "Completé la investigación. Voy a enviar el reporte al equipo."
  → Envía email a 15 personas con información parcialmente incorrecta
  
Sin HITL: El equipo recibe datos erróneos. Pierdes credibilidad.
Con HITL: "Reporte listo. ¿Lo envío al equipo? [sí/no/editar primero]"
  → Usuario revisa: "La cifra del Q3 está mal. Corrijo y luego envío."

El patrón es claro: acciones costosas, irreversibles, o de alto impacto necesitan supervisión. Acciones baratas, reversibles, y de bajo impacto pueden ser autónomas.


El espectro de autonomía

Los agentes no son binarios "autónomo" o "supervisado." Existen en un espectro:

Totalmente             Mayormente              Supervisión           Totalmente
autónomo               autónomo                selectiva             supervisado
    │                      │                        │                     │
    ▼                      ▼                        ▼                     ▼
Sin interrupts.        Solo interrumpe          Interrumpe antes      Interrumpe en
Decide y actúa         para acciones            de acciones           CADA paso.
sin consultar.         destructivas o           costosas, externas,   Pide permiso
                       de alto costo.           o que generan         para todo.
                                                datos permanentes.
    
    ⚠️ Peligroso          ← La mayoría de              ⚠️ Inútil
    en producción           agentes de producción        (¿para qué tener
                            están aquí                    un agente?)

Demasiados interrupts hacen que el agente sea inútil — si pide permiso para cada búsqueda web, el usuario habría sido más rápido haciéndolo manualmente. Cero interrupts lo hacen peligroso — el agente actúa sin supervisión en acciones que pueden tener consecuencias reales.

El sweet spot: interrumpir en acciones costosas, irreversibles, o de alto impacto. Todo lo demás, autónomo.

Criterios para decidir qué interrumpir

CriterioAutónomoRequiere aprobación
CostoGratis o centavosMás de $1 por operación
ReversibilidadFácilmente reversibleDifícil o imposible de revertir
Impacto externoSolo afecta al agenteAfecta a personas, sistemas, o datos
Confianza en los datosDatos verificadosDatos inciertos o parciales
FrecuenciaOperación rutinariaPrimera vez o caso inusual

Patrones de HITL: no es solo aprobar o rechazar

HITL no es un checkbox "sí/no." El usuario tiene múltiples formas de intervenir:

1. Approval Gate — pedir permiso antes de actuar

El agente planea una acción, la presenta al usuario, y espera aprobación antes de ejecutar.

Agente: "Voy a llamar a la API de Google Scholar (costo: $0.50). ¿Procedo?"
Opciones: [Sí] [No] [Reducir scope]

2. Review & Edit — revisar y corregir antes de continuar

El agente produce un resultado parcial y el usuario lo revisa antes de que el agente continúe.

Agente: "Encontré estos 5 papers relevantes:"
  1. "RAG for Healthcare" (2025) — relevancia: alta
  2. "Vector Search Optimization" (2024) — relevancia: media
  ...
Opciones: [Continuar con todos] [Eliminar #2 y #4] [Agregar criterio]

3. Guided Execution — redirigir la investigación

El usuario observa el progreso y cambia la dirección del agente a mitad de camino.

Agente: "Procesé 3 de 5 fuentes. Los hallazgos hasta ahora se enfocan en RAG."
Usuario: "Enfócate más en fine-tuning, ignora los resultados de RAG."
Agente: Ajusta la estrategia → continúa con el nuevo enfoque

4. State Edit — corregir datos directamente

El usuario edita el estado interno del agente para corregir información incorrecta.

Agente: "Según mis datos, el CEO de TechCorp es John Smith."
Usuario: "Incorrecto. El CEO actual es Jane Doe (cambió en enero 2026)."
Agente: Actualiza su estado → continúa con la información correcta

Estos cuatro patrones cubren la mayoría de escenarios de HITL. En las cápsulas técnicas de este módulo los implementarás uno por uno.


El prerequisito: persistencia

Toda la mecánica de HITL depende de un concepto que ya dominas: checkpointing.

Flujo de HITL:

1. El grafo ejecuta nodos normalmente
2. Un nodo llama a interrupt("mensaje para el humano")
3. El grafo se PAUSA — el estado se guarda en un checkpoint
4. El humano ve el mensaje y toma una decisión
   (esto puede tomar segundos, minutos, o días)
5. El humano envía su respuesta con Command(resume=valor)
6. El grafo RESUME desde el checkpoint — el nodo recibe la respuesta
7. La ejecución continúa normalmente

El paso 3 es la clave: sin checkpointer, el estado se pierde cuando el grafo se pausa. El agente no puede esperar al humano si no tiene dónde guardar su progreso. Por eso el Módulo 8 viene antes de este — necesitas persistencia funcionando para que HITL tenga sentido.

from langgraph.checkpoint.memory import MemorySaver

checkpointer = MemorySaver()
graph = builder.compile(checkpointer=checkpointer)

Si ya tienes esta línea en tu código (y la tienes, desde el M8), estás listo para HITL.


Mapa del módulo

#CápsulaQué aprenderásTipo
01Introducción (esta)Por qué los agentes necesitan supervisión, espectro de autonomía, patrones HITLIntro
02Interrupts: pausar ejecucióninterrupt(), Command(resume=), flujo pause/resume, UX completaTécnica
03Approval gates: validar antes de actuarAprobación antes de acciones costosas, routing condicional post-aprobaciónTécnica
04Review & edit: revisar y corregir estadoupdate_state(), editar datos a mitad de ejecución, corregir al agenteTécnica
05Feedback loops: redirigir al agenteFeedback durante la ejecución, cambiar la dirección, guided executionTécnica
06Diseño de UX para HITLQué interrumpir, qué no, cómo no frustrar al usuario, niveles de confianzaDiseño
07Reglas y anti-patterns de interruptsIdempotencia, re-ejecución de nodos, try/except, side effectsTécnica
08Proyecto: Research Agent con supervisiónResearch Agent v4: approval gates + review + editable state + feedbackProyecto

Flujo de aprendizaje

Empiezas con interrupts (cápsula 02) — el mecanismo fundamental para pausar y resumir un grafo. Es la base de todo lo demás. Luego implementas approval gates (cápsula 03) — el patrón más común: pedir permiso antes de acciones costosas o irreversibles. Con eso dominado, aprendes review & edit (cápsula 04) — el usuario revisa resultados parciales y corrige el estado del agente. Después agregas feedback loops (cápsula 05) — el usuario redirige la investigación a mitad de camino. La cápsula 06 (diseño de UX) te enseña a decidir qué interrumpir y cuándo — la decisión de diseño más importante de HITL. La cápsula 07 (reglas y anti-patterns) cubre las trampas técnicas que debes evitar. Finalmente, integras todo en el Research Agent v4 (cápsula 08).

La progresión es: mecanismo → aprobación → revisión → feedback → diseño → reglas → proyecto.


Conexión con el proyecto

Research Agent v4: el agente supervisado

Tu Research Agent evoluciona significativamente en este módulo:

v1 (Módulo 6): Funcional pero frágil
    ↓
v2 (Módulo 7): Robusto (retry, branching, error handling)
    ↓
v3 (Módulo 8): Persistente (checkpointing, memoria, multi-usuario)
    ↓
v4 (Este módulo): Supervisado
    │
    │  + Approval gate antes de APIs de pago
    │  + Review del plan de investigación antes de ejecutar
    │  + Feedback para redirigir la investigación a mitad de camino
    │  + State edit para corregir datos antes del reporte final
    │
    ▼
v5 (Módulo 10): + Multi-agent (especialistas coordinados)

Después de este módulo, tu Research Agent no es "fire and forget." Es un agente supervisado que:

  1. Presenta su plan de búsqueda y espera aprobación
  2. Pide permiso antes de llamar APIs que cuestan dinero
  3. Permite que corrijas datos incorrectos antes de generar el reporte
  4. Acepta redirección si la investigación va por mal camino

La prueba de éxito: ejecutas una investigación, el agente te dice "planeo buscar en 3 fuentes (costo estimado: $0.30), ¿procedo?", tú respondes "sí, pero solo 2 fuentes", y el agente ajusta su plan y continúa.


Conexión con el Módulo 10: Multi-Agent Systems

Cuando tienes un solo agente, la supervisión es directa: tú apruebas o rechazas. ¿Pero qué pasa cuando tienes 5 agentes?

Agente Investigador: busca información (bajo riesgo → autónomo)
Agente Analista: procesa datos (bajo riesgo → autónomo)
Agente Escritor: genera reportes (medio riesgo → review antes de publicar)
Agente Comunicador: envía emails (alto riesgo → approval obligatorio)
Agente DBA: modifica base de datos (alto riesgo → approval obligatorio)

¿Quién aprueba qué? ¿El humano aprueba cada agente individualmente? ¿Un agente supervisor puede aprobar a otros? ¿Cómo evitas que el humano se ahogue en 20 aprobaciones simultáneas?

Esas preguntas son del Módulo 10. Lo que necesitas saber ahora: los patrones de HITL que aprendes en este módulo (approval gates, review & edit, feedback) son los mismos que usarás en multi-agent — solo que aplicados a nivel de sistema en lugar de a nivel de nodo individual.


Qué NO cubre este módulo

  • Multi-agent supervision — Cómo coordinar aprobaciones entre múltiples agentes se cubre en el Módulo 10. Aquí trabajamos con un solo agente supervisado.
  • UI/Frontend para HITL — Simulamos la interacción humana en la terminal. Construir una interfaz web con botones de aprobación es un tema de deployment (Módulo 12).
  • Deployment de agentes con HITL — Cómo desplegar un agente supervisado con webhooks, APIs, o LangGraph Cloud es del Módulo 12.
  • Seguridad y autenticación — Quién puede aprobar qué, roles de usuario, y permisos son temas de producción, no de HITL.
  • Interrupts en streaming avanzado — Cubrimos el flujo básico de interrupt/resume. Streaming con HITL asíncrono es un patrón avanzado de deployment.

Setup técnico

Prerequisitos

  • Módulo 8 completado — tienes un Research Agent v3 con checkpointing, long-term memory, y multi-usuario
  • Python 3.11+ instalado
  • ✅ Al menos una API key de un proveedor (OpenAI recomendado)
  • Checkpointer funcionando — ya usas MemorySaver desde el M8

Instalación

No necesitas paquetes nuevos. Todo lo que necesitas ya lo instalaste en el Módulo 8:

pip install langgraph langchain-openai python-dotenv

Verifica que las importaciones de HITL funcionan:

from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, MessagesState, START, END

print("interrupt disponible")
print("Command disponible")
print("MemorySaver disponible")
# Output esperado:
# interrupt disponible
# Command disponible
# MemorySaver disponible

Variables de entorno

Tu .env del Módulo 8 sigue funcionando:

# .env
OPENAI_API_KEY=sk-...

Verificación rápida: interrupt básico

Ejecuta este script para verificar que el mecanismo de interrupt funciona:

from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END
from typing import TypedDict


class SimpleState(TypedDict):
    task: str
    status: str
    human_decision: str


def plan_node(state: SimpleState) -> dict:
    return {"status": "plan_ready"}


def approval_node(state: SimpleState) -> dict:
    decision = interrupt(f"¿Apruebas la tarea '{state['task']}'? [sí/no]")
    return {"human_decision": decision, "status": "decision_received"}


def execute_node(state: SimpleState) -> dict:
    if state["human_decision"] == "sí":
        return {"status": "completed"}
    return {"status": "cancelled"}


builder = StateGraph(SimpleState)
builder.add_node("plan", plan_node)
builder.add_node("approval", approval_node)
builder.add_node("execute", execute_node)
builder.add_edge(START, "plan")
builder.add_edge("plan", "approval")
builder.add_edge("approval", "execute")
builder.add_edge("execute", END)

checkpointer = MemorySaver()
graph = builder.compile(checkpointer=checkpointer)

config = {"configurable": {"thread_id": "verify_hitl_001"}}

result = graph.invoke(
    {"task": "Investigar RAG", "status": "", "human_decision": ""},
    config
)
print(f"Estado: {result['status']}")
print(f"Interrupt: {result.get('__interrupt__', 'ninguno')}")

result = graph.invoke(Command(resume="sí"), config)
print(f"Estado final: {result['status']}")
print(f"Decisión humana: {result['human_decision']}")
# Output esperado:
# Estado: plan_ready
# Interrupt: [Interrupt(value="¿Apruebas la tarea 'Investigar RAG'? [sí/no]", ...)]
# Estado final: completed
# Decisión humana: sí

Si ves "Estado final: completed" y "Decisión humana: sí", el mecanismo de HITL está funcionando correctamente. El grafo se pausó en approval_node, esperó tu decisión, y continuó.


Evidencia de éxito

Al terminar este módulo, sabrás que tuviste éxito si:

  • ✅ Puedes pausar un grafo con interrupt() y resumirlo con Command(resume=) — el flujo básico funciona
  • ✅ Implementas approval gates que piden permiso antes de acciones costosas o irreversibles
  • ✅ El usuario puede revisar resultados parciales y editar el estado del agente antes de continuar
  • ✅ El usuario puede redirigir la investigación a mitad de camino con feedback
  • ✅ Sabes decidir qué interrumpir y qué dejar autónomo sin paralizar al agente con demasiadas pausas
  • ✅ Tu Research Agent v4 presenta un plan, pide aprobación, y acepta correcciones

Test de autoevaluación

Si puedes responder estas preguntas, vas por buen camino:

  1. ¿Por qué un interrupt requiere un checkpointer configurado?
  2. ¿Cuál es la diferencia entre un approval gate y un review & edit?
  3. ¿Qué pasa cuando el nodo que contiene interrupt() se reanuda — ejecuta desde el principio del nodo o desde donde se pausó?
  4. Si tu agente interrumpe 15 veces en una investigación de 5 minutos, ¿es un buen diseño? ¿Por qué?
  5. ¿Cómo decides si una acción debe ser autónoma o requiere aprobación?

Resumen

  • Tu Research Agent v3 es persistente, pero actúa sobre todo sin preguntar. Acciones costosas, irreversibles, o de alto impacto necesitan supervisión humana. HITL no es un parche de seguridad — es una decisión de diseño
  • El espectro de autonomía va de totalmente autónomo (peligroso) a totalmente supervisado (inútil). El sweet spot: interrumpir en acciones costosas, irreversibles, o de alto impacto. Todo lo demás, autónomo
  • HITL no es solo aprobar/rechazar. El usuario puede: aprobar, rechazar, aprobar con modificaciones, pedir más info, redirigir la tarea, o editar el estado directamente. Cuatro patrones: approval gate, review & edit, guided execution, state edit
  • Persistencia es prerequisito técnico. interrupt() pausa el grafo y guarda el estado en un checkpoint. Sin checkpointer, el estado se pierde durante la pausa y el agente no puede resumir. Todo el HITL de LangGraph depende del checkpointing del Módulo 8
  • El Research Agent v4 agrega: aprobación antes de APIs de pago, review del plan de investigación, feedback para redirigir, y state edit para corregir datos
  • Este módulo prepara para multi-agent (M10). Cuando tienes 5 agentes, la pregunta cambia: ¿quién aprueba qué? Los patrones son los mismos, pero aplicados a nivel de sistema

Recursos adicionales

  1. LangGraph — Human-in-the-Loop — Documentación oficial de HITL en LangGraph: interrupts, approval patterns, state editing
  2. LangGraph — Interrupts — Referencia completa de interrupt() y Command(resume=), reglas, y anti-patterns
  3. How to add human-in-the-loop — Guía práctica paso a paso para implementar HITL
  4. How to edit graph state — Cómo dejar que el humano edite el estado del agente durante una pausa
  5. How to review tool calls — Patrón para revisar y aprobar tool calls antes de que se ejecuten
  6. LangGraph — Persistence (prerequisito) — Repaso del sistema de checkpointing que habilita HITL

Módulo 9 — LangChain & LangGraph: From Chains to Agents

Siguiente cápsula: Interrupts: Pausar Ejecución — aprenderás cómo interrupt() pausa tu grafo, cómo Command(resume=) lo reanuda, y cómo simular la experiencia completa de un humano interactuando con un agente.