Human-in-the-loop en LangGraph: cuándo pausar para aprobación humana

By Carlos Montiel | Especialista en IA Empresarial
Publicado: 2026-07-28 | Por: Carlos Montiel | Lectura: ~4 minutos

No todas las acciones de un agente deben ejecutarse sin supervisión. LangGraph permite pausar un grafo en cualquier nodo, esperar aprobación humana, y reanudar exactamente donde quedó.

Por qué esto no es opcional en dominios sensibles

Un agente que envía correos a clientes, ejecuta transferencias, modifica registros en un ERP, o genera comunicados públicos no debería tener autonomía completa desde el primer día en producción, sin importar qué tan bien se comportó en pruebas. El patrón human-in-the-loop no es una limitación temporal mientras "el modelo mejora": es un control de gobernanza permanente para acciones de alto impacto, exactamente igual que un proceso de aprobación de doble firma en un sistema financiero tradicional.

El mecanismo interrupt()

LangGraph ofrece la función `interrupt()`, que pausa la ejecución del grafo dentro de un nodo, persiste el estado vía el checkpointer configurado, y devuelve el control al proceso que invocó el grafo:

from langgraph.types import interrupt, Command def nodo_solicitar_aprobacion(estado: EstadoAgente): decision = interrupt({ "accion_propuesta": estado["accion"], "monto": estado["monto"], "mensaje": "¿Aprobar esta transferencia?", }) if decision == "aprobar": return {"estado_aprobacion": "aprobado"} return {"estado_aprobacion": "rechazado"}

Al ejecutarse `interrupt()`, el grafo se detiene por completo en ese punto. La llamada a `app.invoke()` que lo disparó retorna con un objeto de tipo interrupción en lugar del resultado final, indicando que se necesita input humano para continuar.

Reanudando con Command(resume=...)

La ejecución se retoma con un objeto `Command`, pasando el mismo `thread_id` original para que el checkpointer recupere el estado exacto donde se pausó:

config = {"configurable": {"thread_id": "aprobacion-transferencia-9931"}} resultado = app.invoke( {"accion": "transferencia", "monto": 15000}, config=config, ) # resultado contiene la interrupción pendiente # ... un humano revisa en un panel administrativo y aprueba ... resultado_final = app.invoke( Command(resume="aprobar"), config=config, )

Nótese que el segundo `invoke()` no repite la entrada original: LangGraph reconstruye el estado desde el checkpoint y continúa desde el punto exacto de la interrupción, sin re-ejecutar los nodos anteriores.

interrupt_before y interrupt_after como alternativa declarativa

Para casos donde el punto de pausa es siempre el mismo nodo (por ejemplo, siempre antes de ejecutar una herramienta que escribe en un sistema externo), se puede declarar en la compilación en lugar de dentro de la lógica del nodo:

app = builder.compile( checkpointer=checkpointer, interrupt_before=["ejecutar_transferencia"], )

Esto pausa automáticamente antes de que `ejecutar_transferencia` corra, sin necesidad de una llamada explícita a `interrupt()` dentro de esa función, útil cuando el punto de control es estructural y no depende de una condición evaluada en tiempo de ejecución.

Editando el estado antes de reanudar

Un caso frecuente no es solo aprobar o rechazar, sino que el humano corrija un parámetro antes de continuar —por ejemplo, ajustar el monto de la transferencia propuesta por el agente. Esto se resuelve actualizando el estado directamente vía el checkpointer antes de reanudar:

app.update_state( config, {"monto": 12000}, # el humano corrige el monto propuesto por el agente ) resultado_final = app.invoke(Command(resume="aprobar"), config=config)

`update_state()` modifica el checkpoint persistido sin ejecutar ningún nodo, lo que permite que la interfaz de aprobación humana sea también una interfaz de edición, no solo un botón binario de sí/no.

Diseñando el panel de aprobación

En despliegues reales, el flujo de aprobación vive fuera del proceso del agente: un backend que expone las interrupciones pendientes (consultando `app.get_state(config)` para listar hilos pausados) y una interfaz —panel administrativo, canal de Slack, ticket— donde un operador humano revisa el contexto completo antes de decidir. La recomendación de arquitectura es nunca acoplar el timeout de esta espera al proceso del agente: el checkpointer persiste el estado indefinidamente hasta que alguien reanude, por lo que una aprobación puede tardar minutos o días sin que el sistema pierda contexto ni consuma recursos de cómputo mientras espera.

Carlos Montiel
Arquitecto de Soluciones IA Empresarial
Especialista en LLMs, Agentes y Orquestación
guatemalia.com/#contacto · info@guatemalia.com

¿Necesitas implementar IA en tu empresa?

Carlos Montiel es arquitecto de soluciones IA empresarial. Implementa LLMs, Agentes, RAG y orquestadores en empresas de Guatemala y Latinoamérica. Contáctalo para una consultoría.

Contactar a Carlos Montiel

info@guatemalia.com