Una aprobación debe autorizar una acción concreta. Si alguien revisa un texto y después cambia el destino o el contenido, conservar un simple approved: true permite ejecutar algo que nunca se aprobó. La solución que proponemos es guardar una versión inmutable de la acción y comprobar su identidad antes del efecto externo.
Esta guía de diseño se dirige a equipos que ya usan LangGraph y necesitan una pausa de revisión humana. La referencia consultada el 12 de octubre de 2026 es LangGraph 1.2.14, con Python 3.10 o posterior según su ficha en PyPI. No hemos ejecutado LangGraph ni un sistema de aprobación para este artículo: los casos y las pruebas propuestas son hipotéticos. No es una aplicación lista para producción.
Lo que resuelve la pausa
LangGraph permite llamar a interrupt() con datos serializables en JSON y reanudar con Command(resume=...) usando el mismo thread_id y un checkpointer. Al reanudar, el nodo vuelve a empezar: el código anterior a la interrupción se ejecuta otra vez. InMemorySaver pierde los checkpoints al reiniciar el proceso; para conservarlos hace falta almacenamiento persistente. Estas capacidades están documentadas; el control de autorización que sigue es una propuesta de arquitectura propia.
El hilo identifica la ejecución que hay que recuperar. No demuestra quién responde ni qué permisos tiene. Para decidir qué controles pertenecen al código y cuáles al agente, sirve el antecedente sobre workflow o agente.
1. Congela exactamente lo que se va a aprobar
Imagina la acción A42, revisión 7: publicar el texto T7 en un destino de pruebas. Guarda esa propuesta como registro inmutable. Incluye operación, destino, contenido exacto y parámetros que cambien el efecto. Una pantalla de revisión debe mostrar esos datos, además del plazo de validez que decida la aplicación.
Si se edita el texto a T8, crea la revisión 8. Si cambia el destino a producción, también requiere nueva revisión. No reutilices la aprobación de 7. El identificador de acción agrupa el trabajo; la revisión identifica la propuesta concreta.
Puedes añadir una huella criptográfica de una representación canónica del contenido y sus parámetros para detectar cambios. Define antes qué campos entran y cómo se serializan. Una huella del resumen visible deja fuera posibles diferencias del documento completo. La huella tampoco autentica al revisor ni demuestra que el texto sea correcto.
2. Recibe una decisión vinculada a esa propuesta
El nodo de aprobación lee la versión guardada y prepara el mensaje de interrupt() sin publicar ni enviar nada. Como ejemplo de contrato de respuesta, diseñado por la aplicación:
{"action_id": "A42", "revision": 7, "decision": "approve"}
El servidor debe comprobar formato, correspondencia con la revisión pendiente y caducidad. La identidad del revisor procede de la sesión autenticada; no confíes en un campo reviewer enviado por el cliente. Verifica que esa persona puede aprobar esa operación y ese destino. El contrato de una herramienta debe incluir también esos límites.
Un true aislado puede servir para una demostración mínima, pero no expresa qué contenido se autorizó. Registra la decisión, la revisión, la identidad validada y el momento. Evita meter credenciales en el mensaje de revisión y establece cuánto tiempo se conservarán los datos sensibles.
3. Comprueba y reclama antes de ejecutar
Separa la aprobación del nodo que realiza el efecto. Este último debe comprobar que la revisión aprobada sigue vigente, que no caducó y que los permisos actuales permiten ejecutarla. Después debe reclamar la operación de forma atómica: comprobar la condición y cambiar su estado como una única operación indivisible en el almacenamiento elegido.
Una lectura seguida de una escritura sin protección permite que dos trabajadores vean el mismo estado y actúen ambos. Puedes usar una transacción o una actualización condicionada al estado y revisión esperados. Si la reclamación falla, ese trabajador no ejecuta. Mantén inmutable la propuesta reclamada; una edición posterior abre otra revisión, no modifica los parámetros en mitad del envío.
Son estados de negocio propios, separados del checkpoint: pendiente de revisión, aprobada, rechazada o caducada; después, ejecutando, completada o con resultado incierto. Define qué transición permite cada actor. Si cambia la propuesta antes de reclamarla, impide el efecto y vuelve a pedir aprobación para la nueva versión.
4. Trata el reintento como otro problema
Haber aprobado A42/7 no evita una duplicación si el receptor acepta la publicación y el proceso cae antes de registrar la respuesta. Mover el envío después de la pausa evita hacerlo antes de aprobar, pero no elimina esa ventana de fallo.
Si el receptor admite idempotencia, conserva una clave estable por operación lógica durante sus reintentos, conforme a su contrato. No generes otra por cada intento ni uses la misma para contenidos diferentes. Ante una respuesta incierta, consulta o reconcilia el resultado antes de repetir. Si no hay una consulta fiable ni protección del receptor, no prometas ejecución exactamente una vez.
Nuestro laboratorio de reintentos explica esa frontera con efectos locales en SQLite. No ejecutó LangGraph ni acredita este diseño: un checkpoint no convierte una llamada externa en parte de una transacción local.
Qué comprobar antes de adoptarlo
Estas son pruebas recomendadas, no resultados medidos:
| Caso hipotético | Comportamiento que debe verificarse |
|---|---|
Aprobar A42/7 y mantener la propuesta |
Permitir la reclamación si siguen vigentes permiso y plazo |
Responder con aprobación de 7 cuando está pendiente 8 |
Rechazar la respuesta y solicitar revisión de 8 |
| Caducar o perder permiso antes de ejecutar | Bloquear el efecto |
| Recibir dos respuestas o dos trabajadores simultáneos | Una sola reclamación de la misma operación |
| Caer después de la aceptación del receptor | Conciliar el resultado antes de reintentar |
Al implementar la pausa, evita capturar interrupt() con un except amplio y no cambies el orden de varias interrupciones dentro de un nodo: la documentación explica que los valores de reanudación se corresponden por índice. Son reglas del runtime, distintas de la política de autorización.
Si solo necesitas aprobar una operación sencilla, una cola administrativa convencional puede ser suficiente. Este diseño tiene sentido cuando el proceso ya necesita pausas y recuperación con LangGraph. Su criterio de aceptación es concreto: ninguna ejecución puede usar una propuesta distinta de la que se autorizó, y cualquier resultado incierto queda visible hasta resolverlo.