Pausar y reanudar agentes de LangGraph con interrupt() y Command
Cómo LangGraph utiliza las funciones interrupt() y Command, junto con puntos de control y hilos, para pausar a un agente a fin de obtener la aprobación humana, realizar ediciones o recibir entrada, y luego reanudarlo de forma segura más tarde.
Un agente que puede mover dinero, eliminar recursos o desplegarse en producción no siempre debe tener permiso para terminar lo que comenzó. A veces el grafo debe detenerse intencionadamente, esperar horas a que llegue una persona y luego continuar exactamente desde donde se detuvo. Este artículo explica cómo LangGraph hace eso con interrupt() y Command, por qué depende de puntos de control y hilos, y qué decisiones aún están en tus manos antes de ejecutar agentes con intervención humana (HITL) en producción.
Los componentes básicos subyacentes
HITL se basa en tres capas. Primero, la ejecución del grafo: el estado ingresa a un nodo y un arco selecciona el siguiente nodo.
STATE
↓
NODE
↓
EDGE
↓
NEXT NODE
Segundo, la gestión de estados: los nodos devuelven actualizaciones y los reductores las fusionan en el nuevo estado.
NODE
↓
STATE UPDATE
↓
REDUCER
↓
NEW STATE
Tercero, la persistencia: un punto de control guarda el estado como puntos de verificación agrupados bajo un hilo.
STATE
↓
CHECKPOINT
↓
CHECKPOINTER
↓
THREAD
↓
PERSISTENCE
Juntos, estos elementos permiten que un agente funcione, recuerde y sobreviva a los reinicios. Lo que falta es una forma de decidir si realmente debe continuar.
Cuándo un agente no debería simplemente continuar
Un usuario le dice a un asistente de pagos: “Transfiera ₹50,000 a esta cuenta”. El agente prepara la transacción, y técnicamente no hay nada que impida su ejecución.
User
↓
Agent
↓
Prepare Transfer
↓
Transfer ₹50,000
↓
Execute
Para una acción tan importante, una persona debería revisar primero la propuesta, de modo que el flujo se divida según una decisión humana.
User
↓
Agent
↓
Prepare Transfer
↓
┌─────────────────────┐
│ HUMAN APPROVAL │
└──────────┬──────────┘
│
┌───┴───┐
↓ ↓
Approve Reject
│ │
↓ ↓
Execute Cancel
El gráfico ahora debe detenerse intencionadamente: no por un error o caída, sino porque el proceso requiere una intervención humana en este punto.
Qué significa la intervención humana
HITL introduce decisiones humanas en un flujo automatizado. En lugar de pasar directamente de una decisión a una acción,
Agent
↓
Decision
↓
Action
el agente propone, hace una pausa y espera la revisión.
Agent
↓
Proposed Action
↓
PAUSE
↓
Human Review
↓
Decision
↓
Continue
El revisor puede aprobar, rechazar, editar la propuesta, proporcionar datos faltantes, corregir al agente o elegir entre alternativas. Eso se aplica a cualquier paso con consecuencias reales.
Financial transactions
Sending emails
Deleting resources
Production deployments
Database modifications
Legal workflows
Publishing content
Access approvals
Sensitive tool calls
Lo que realmente se necesita para pausar un gráfico
Tomemos una cadena con un paso de aprobación antes del último nodo.
Node A
↓
Node B
↓
Human Approval
↓
Node C
Si el revisor responde seis horas después, bloquear el proceso es la respuesta incorrecta: desperdicia a un trabajador y falla al reiniciarse por primera vez.
sleep(21600)
Lo que se desea en su lugar es guardar el estado y detenerse,
Node B
↓
SAVE STATE
↓
PAUSE EXECUTION
↓
luego restaurarlo más tarde, posiblemente en otro proceso, y continuar con el siguiente nodo.
Application can stop──────── 6 HOURS LATER ────────Human responds
↓
RESTORE STATE
↓
CONTINUE EXECUTION
↓
Node C
La persistencia ya resuelve la mitad de este problema. Los puntos de control, el controlador de puntos de control, los hilos y thread_id son exactamente lo que se necesita para una pausa prolongada.
Checkpoint
Checkpointer
Thread
thread_id
Persistence
Cómo interrumpe() detiene la ejecución
interrupt() pausa un grafo y solicita un valor al entorno exterior. Se llama desde dentro de un nodo con una carga útil serializable en JSON que describe lo que debe ver el revisor. El fragmento está escrito en Python, a pesar de su etiqueta original.
from langgraph.types import interrupt
def approval_node(state):
decision = interrupt({
"question": "Do you approve this transaction?",
"amount": state["amount"]
})
return {
"decision": decision
}
Cuando la ejecución llega a la llamada,
interrupt(...)
el nodo no llega a su instrucción de retorno. La ejecución se suspende y la carga útil vuelve al llamante para su visualización.
approval_node
│
↓
interrupt()
│
↓
┌─────────────────┐
│ EXECUTION PAUSED│
└─────────────────┘
Hay dos detalles importantes. interrupt() requiere un grafo compilado con un checkpointer, ya que el estado pausado debe almacenarse en algún lugar. Además, al reanudar, LangGraph vuelve a ejecutar el nodo interrumpido desde el principio; ahora interrupt() devuelve el valor proporcionado por el usuario, por lo que el código anterior a la llamada se ejecuta dos veces. Evite efectos secundarios en esa parte del nodo y verifique el comportamiento de su versión en la documentación de LangGraph.
¿Qué se guarda durante una interrupción?
Considere este gráfico.
START
↓
Prepare Transfer
↓
Human Approval
↓
Execute Transfer
↓
END
El nodo de preparación actualiza el estado, se escribe un punto de control y el nodo de aprobación llama a interrupt().
START
↓
Prepare Transfer
↓
State Updated
↓
Checkpoint
↓
Approval Node
↓
interrupt()
El estado actual se captura y se escribe en el almacenamiento.
Current State
│
↓
Checkpoint
│
↓
Persistent Storage
El hilo ahora contiene los detalles de la transferencia, un estado pendiente y el motivo para detenerse.
THREAD: transaction-123
Checkpoint
────────────────────
amount ₹50,000
recipient Account X
status pending
────────────────────
Execution:
PAUSED
Reason:
Human approval required
Eso es todo lo necesario para continuar más adelante. Sin persistencia, el proceso simplemente desaparecería después de la interrupción.
Agent
↓
interrupt
↓
process disappears
↓
???
Cuando el revisor dice “Aprobado” al día siguiente, nadie podría saber qué fue aprobado, dónde se detuvo el gráfico o qué nodo viene a continuación. Con puntos de control, el estado se carga desde el hilo y se restaura antes de reanudar.
INTERRUPT
│
↓
CHECKPOINT
│
↓
THREAD
│
↓
PERSISTENT STORAGE
...time passes...
HUMAN INPUT
│
↓
THREAD
│
↓
LOAD CHECKPOINT
│
↓
RESTORE STATE
│
↓
RESUME
Reanudación con comando
La aplicación muestra el contenido de la interrupción como una pregunta
Approve transfer of ₹50,000?
con dos botones,
[ APPROVE ] [ REJECT ]
y el revisor elige uno de ellos.
APPROVE
La respuesta vuelve a través de Command, el cual indica al grafo cómo proceder. Para reanudar, invoque el grafo con Command(resume=...) en lugar de una entrada normal.
from langgraph.types import Command
graph.invoke(
Command(resume="approved"),
config=config
)
El config debe utilizar el mismo hilo que la ejecución pausada,
thread_id = transaction-123
ya que el ID del hilo es lo que permite a LangGraph saber a qué ejecución suspendida se refiere.
El ciclo de vida paso a paso
Una ejecución comienza con una invocación ordinaria,
graph.invoke()
lee su hilo desde el config,
thread_id = transaction-123
ingresa al nodo de preparación,
START
↓
Prepare Transfer
y escribe la transferencia en el estado.
amount = ₹50,000
recipient = Account X
status = pending
El nodo de aprobación llama a interrupt(),
Approval Node
↓
interrupt()
y la ejecución se suspende.
EXECUTION PAUSED
El último punto de control permanece seguro bajo el hilo.
Thread
↓
Checkpoint
↓
Persistent Storage
Una persona ve la solicitud
Approve ₹50,000 transfer?
y responde.
YES
La aplicación envía una orden de reanudación
Command(resume="approved")
al mismo hilo.
transaction-123
LangGraph reanuda la ejecución, transfiere la decisión al nodo de aprobación y continúa hasta el final.
Restore Execution
↓
Human Decision = approved
↓
Continue Graph
↓
Execute Transfer
↓
END
Cada patrón a continuación es una variante de este ciclo de vida.
Decisiones humanas más allá de sí o no
La respuesta de un revisor no tiene por qué ser binaria.
YES / NO
La aprobación ejecuta la propuesta.
Agent Proposal
↓
Human
↓
APPROVE
↓
Execute
El rechazo la cancela.
Agent Proposal
↓
Human
↓
REJECT
↓
Cancel
La edición modifica parte de ella, como la cantidad, antes de que el grafo continúe.
Agent:
Send ₹50,000
↓
Human:
Change to ₹40,000
↓
Graph continues with
updated information
Proporcionar información faltante convierte la interrupción en una pregunta.
Agent
↓
Missing Account Number
↓
INTERRUPT
↓
Human provides account
↓
RESUME
Al elegir, el agente puede ofrecer alternativas y dejar la decisión a una persona.
Agent generates:
Option A
Option B
Option C
↓
Human chooses B
↓
Graph continues
HITL es una forma general de insertar entrada humana en un grafo en ejecución, no solo un diálogo de aprobación.
Comando como flujo de datos y flujo de control
Command también puede actualizar el estado y elegir el siguiente destino.
Resume Execution
Update State
Choose Next Destination
Un único comando puede establecer un estado y enviar la ejecución a un nodo específico; en LangGraph esta forma suele ser devuelta por un nodo.
Command(
update={
"status": "approved"
},
goto="execute"
)
Eso une dos aspectos,
DATA FLOW
+
CONTROL FLOW
ya que el enrutamiento solía pertenecer únicamente a las aristas.
Edges control where we go.
Ahora un único objeto puede contener tanto el cambio de estado como el siguiente paso.
Command can participate in
state updates + control decisions.
Corregir el estado antes de continuar
Supongamos que el estado contiene esta cantidad,
amount = 50000
y el revisor aprueba con una corrección.
Approve, but change amount to 40000.
El flujo va desde el valor original, pasando por la revisión, hasta un valor actualizado, y solo entonces se reanuda (el segundo fragmento aparece en una sola línea).
BEFORE
amount = 50000 ↓Human Review ↓UPDATEamount = 40000 ↓RESUME
La pregunta cambia de “¿Puedo continuar?” a “Inspeccionar, corregir si es necesario y luego continuar.”
Control de llamadas a herramientas sensibles
HITL es lo más práctico frente a herramientas riesgosas.
search_web()
read_database()
send_email()
delete_resource()
transfer_money()
Una búsqueda en la web puede ejecutarse automáticamente,
search_web()
↓
Execute Automatically
mientras que la eliminación de un recurso debe esperar aprobación.
delete_resource()
↓
INTERRUPT
↓
Human Approval
Cada llamada a una herramienta pasa por una verificación de sensibilidad: las llamadas seguras se ejecutan, mientras que las sensibles se interrumpen para solicitar aprobación o cancelación.
Agent
│
↓
Tool Call
│
↓
Sensitive Tool?
/ \
NO YES
│ │
↓ ↓
Execute INTERRUPT
│ │
│ ↓
│ Human
│ / \
│ Approve Reject
│ │ │
└─────────┘ ↓
Cancel
Para una implementación más completa respaldada por un almacén, consulte agentes con control de aprobación en LangGraph.
La revisión como límite de control deliberado
La revisión humana no es una solución para agentes que no son lo suficientemente inteligentes. Es un límite que se establece intencionadamente. Las tareas de bajo riesgo se ejecutan automáticamente,
LOW RISK
Search
Read
Summarize
↓
Automatic
y las tareas de alto riesgo pasan por una persona.
HIGH RISKSend
Delete
Purchase
Transfer
Deploy
↓
Human Approval
El objetivo es decidir dónde es apropiada la autonomía, no reducirla en todas partes.
Manejo de rechazos y silencio
El rechazo merece un diseño adecuado.
Agent
↓
Prepare Action
↓
Interrupt
↓
Human
↓
REJECT
Registre el resultado en el estado,
status = "rejected"
luego diríjalo mediante un borde condicional.
Decision
/ \
approved rejected
│ │
↓ ↓
Execute Cancel
│ │
↓ ↓
END END
Cada concepto anterior participa, y la entrada humana es simplemente más información que da forma a la ejecución.
State
Reducers
Conditional Routing
Checkpoints
Threads
Commands
Los revisores también pueden no responder nunca.
Interrupt
↓
Waiting for approval
↓
1 hour
↓
1 day
↓
7 days
Un hilo en pausa puede esperar indefinidamente, por lo que su aplicación necesita políticas al respecto.
Expiration
Timeout
Cancellation
Reminder
Escalation
Una solución común es una espera con límite de tiempo, generalmente impuesta por un planificador que reanuda los hilos obsoletos tras superar dicho tiempo.
Approval Requested
│
↓
Wait up to 24 hours
│
┌───┴────┐
↓ ↓
Response Timeout
│ │
↓ ↓
Resume Cancel
LangGraph proporciona primitivas; las reglas de negocio son responsabilidad del usuario.
Varios puntos de control y transmisión en tiempo real
Un agente de despliegue puede solicitar la aprobación de su plan y nuevamente antes de ponerlo en producción.
START
↓
Analyze Code
↓
Generate Deployment Plan
↓
Human Approval #1
↓
Deploy to Staging
↓
Run Tests
↓
Human Approval #2
↓
Deploy Production
↓
END
Cada punto de control pausa y reanuda el mismo hilo, dejando un historial de puntos de verificación e interrupciones.
Thread
│
├── CP1
│
├── CP2
│
├── INTERRUPT
│
├── RESUME
│
├── CP3
│
├── INTERRUPT
│
├── RESUME
│
└── END
Ese es un flujo de trabajo duradero compartido por personas y agentes. Hasta ahora, cada ejemplo utilizó una llamada bloqueante,
graph.invoke(...)
que solo devuelve cuando la ejecución finaliza o se pausa.
START → A → B → C → END
↓
RESULT
Las aplicaciones interactivas necesitan ver el progreso en tiempo real, hasta el momento de la solicitud de aprobación.
START
↓
Planner Update ─────────→ UI
↓
Tool Call ──────────────→ UI
↓
Tool Result ────────────→ UI
↓
Approval Required ──────→ UI
La transmisión en flujo entrega esos eventos para que la interfaz pueda mostrar los pasos completados y la decisión pendiente.
┌──────────────────────────────────┐
│ Deployment Agent │
├──────────────────────────────────┤
│ │
│ ✓ Analyzed repository │
│ │
│ ✓ Generated deployment plan │
│ │
│ ✓ Staging tests passed │
│ │
│ ⚠ Production deployment ready │
│ │
│ Human approval required │
│ │
│ [ APPROVE ] [ REJECT ] │
│ │
└──────────────────────────────────┘
Detrás de esa pantalla, los eventos fluyen hacia el frontend y la decisión se devuelve a través de Command(resume=...).
LangGraph
│
↓
Streaming
│
↓
Frontend
│
↓
Human Decision
│
↓
Command(resume=...)
│
↓
LangGraph
El modelo de ejecución completo
En un único diagrama: el usuario invoca el grafo en un hilo, el estado pasa por nodos y reductores, se escriben puntos de control, la redirección elige el siguiente paso, y las acciones sensibles derivan a una interrupción que un humano resuelve.
USER
│
↓
graph.invoke()
│
↓
THREAD
│
↓
CHECKPOINTER
│
↓
STATE
│
↓
NODE
│
↓
STATE UPDATE
│
↓
REDUCER
│
↓
NEW STATE
│
↓
CHECKPOINT
│
↓
EDGE / ROUTING
│
↓
SENSITIVE ACTION?
/ \
NO YES
│ │
↓ ↓
NEXT NODE interrupt()
│
↓
PAUSED
│
↓
HUMAN
/ | \
/ | \
Approve Edit Reject
│ │ │
└────────┼────────┘
↓
Command(resume)
│
↓
SAME thread_id
│
↓
RESTORE CHECKPOINT
│
↓
CONTINUE GRAPH
│
↓
END
Como historia, llega una solicitud
User Input
y comienza la ejecución.
START
Los nodos leen el estado y devuelven actualizaciones, los reductores las fusionan, los puntos de control las guardan bajo un hilo, y las aristas deciden qué se ejecuta a continuación. El grafo puede ramificarse, formar bucles o llamar a herramientas.
BRANCH
LOOP
CALL TOOLS
Cuando se necesita ayuda humana, una interrupción suspende la ejecución.
interrupt()
La persona responde,
APPROVE
REJECT
EDIT
PROVIDE INPUT
una orden de reanudación continúa desde el hilo persistido,
Command(resume=...)
y el grafo finaliza.
END
La mayoría de los proyectos comienzan con una sola llamada al modelo,
LLM
↓
Response
y terminan con un grafo que combina nodos de LLM y herramientas, reductores, puntos de control, enrutamiento, interrupciones y órdenes.
USER
│
↓
START
│
↓
STATE
│
↓
NODE
│
┌──────┴──────┐
│ │
LLM TOOL
│ │
└──────┬──────┘
↓
STATE UPDATE
│
↓
REDUCER
│
↓
NEW STATE
│
↓
CHECKPOINT
│
↓
THREAD
│
↓
ROUTING
/ | \
/ | \
NODE LOOP INTERRUPT
│
↓
HUMAN
/ | \
Approve Edit Reject
\ | /
\ | /
↓
COMMAND
│
↓
RESUME
│
↓
NEXT NODE
│
↓
END
Lista de verificación para producción
Mantener los nodos enfocados
Los nodos pequeños de un solo propósito son más fáciles de probar, reintentar e interrumpir de forma segura,
Plan Node
Search Node
Validate Node
Execute Node
a diferencia de un nodo que hace todo.
do_everything_agent()
Diseñe el estado y los reducers de forma deliberada
Mantenga solo lo que necesitan los nodos, ya que todo se guarda como punto de control y podría mostrarse a los revisores. Elija cuidadosamente los reducers para los campos que acumulan datos.
messages
events
results
observations
Haga que los efectos secundarios sean idempotentes
Las operaciones irreversibles requieren especial atención.
Send Email
Charge Card
Delete Resource
Deploy
Transfer Money
Las reintentos y las continuaciones nunca deben repetir esas operaciones. Dado que un nodo interrumpido se reinicia al continuar, coloque las llamadas irreversibles después del punto de aprobación o en un nodo separado, y utilice claves de idempotencia donde las APIs lo permitan.
Utilice persistencia duradera
Los puntos de control en memoria son adecuados para el aprendizaje; la producción necesita almacenamiento duradero acorde a sus requisitos de fiabilidad.
Escriba las fronteras y límites
Decida estos de forma explícita para cada flujo de trabajo,
What can AI do automatically?
What requires approval?
What can humans modify?
When does approval expire?
y defina las condiciones de terminación de los bucles.
Maximum attempts
Timeouts
Validation
Failure paths
Escalation
Cuándo vale la pena usar HITL
La revisión humana es útil en situaciones específicas.
Cost of wrong action is high
Action is irreversible
Policy requires approval
Agent confidence is insufficient
Sensitive information is involved
Human judgment adds value
Disperso por todas partes, invalida la automatización y hace que los revisores hagan clic sin leer.
Agent
↓
Ask Human
↓
Agent
↓
Ask Human
↓
Agent
↓
Ask Human
Un diseño mejor proporciona al agente una zona autónoma para la planificación y el razonamiento, con un límite antes de la acción consecuente.
AUTONOMOUS ZONE
┌───────────────────────┐
│ │
│ Plan → Search → Think │
│ │
└───────────┬───────────┘
│
↓
CONTROL BOUNDARY
│
↓
HUMAN
│
↓
APPROVED ACTION
Cómo se integran las capas
La ejecución del grafo abarca nodos, aristas y enrutamiento;
Graph
Nodes
Edges
START
END
Loops
Conditional Routing
La gestión de estado abarca actualizaciones y reducers;
State
State Updates
Reducers
Messages
State Evolution
La persistencia abarca puntos de control, hilos y recuperación;
Checkpoints
Checkpointer
Threads
thread_id
State History
Recovery
Y HITL agrega interrupciones, comandos y patrones de revisión.
interrupt()
Command
Pause
Resume
Approve
Reject
Edit
Human Control
Apilados, forman un único pipeline.
GRAPH
↓
STATE
↓
NODE
↓
UPDATE
↓
REDUCER
↓
CHECKPOINT
↓
THREAD
↓
ROUTING
↓
INTERRUPT
↓
HUMAN
↓
COMMAND
↓
RESUME
↓
END
Conclusiones clave
El vocabulario puede parecer abrumador,
StateGraph
MessagesState
Reducers
Checkpointers
Threads
Commands
Interrupts
Pero cada componente resuelve una parte de un único objetivo: un agente que conoce, actúa, actualiza, toma decisiones, guarda el progreso, se detiene cuando debe hacerlo, consulta a una persona y reanuda de forma segura.
Remember what it knows
↓
Perform some work
↓
Update what it knows
↓
Decide what to do next
↓
Persist its progress
↓
Pause when necessary
↓
Ask a human
↓
Resume safely
↓
Continue until complete
- El estado es lo que conoce el agente, los nodos son lo que hace, las aristas indican a dónde va y los reductores definen cómo cambia el estado.
- Los puntos de control registran dónde se encontraba; los hilos indican a cuál historia pertenece cada ejecución.
interrupt()marca dónde detenerse y hacer una consulta;Commandindica cómo continuar, siempre en el mismo hilo.- Los nodos interrumpidos se reinician al reanudarse, por lo que hay que evitar efectos secundarios irreversibles después del punto de aprobación.
- Colocar las revisiones en los verdaderos límites de control, con reglas explícitas de tiempo de espera y escalada.
Lectura relacionada
- Puertas de Aprobación en LangGraph.js: Pausando Agentes con interrupt() y Command — Construir una puerta de aprobación mínima en LangGraph.js que haga una pausa antes de un efecto secundario, recopile la decisión humana en la terminal y reanude de forma segura a partir de un punto de control.
- Agentes Especialistas, un Enrutador de Palabras Clave y interrupt(): Un Coach de LangGraph — Diseñar un asistente de LangGraph con dos especialistas, un enrutador determinista, un estado compartido que sobrevive a los cambios de responsabilidad y un punto de control humano basado en interrupt y Command.