Intervention humaine pour LangGraph et LangChain

L’intervention humaine pour les agents LangGraph, avec réponse sur téléphone.

Votre nœud LangGraph interroge votre utilisateur sur son téléphone, puis attend ou se met en pause sur une interruption jusqu’à sa réponse.

Ce que propose LangGraph

interrupt() et le checkpointer

Avec un checkpointer et un identifiant de fil, interrupt() met le graphe en pause et rend le contrôle à votre code. Ensuite, Command(resume=...) fournit la réponse et réexécute le nœud interrompu. À vous de recueillir la réponse et de rendre les effets de bord sûrs en cas de double exécution.

natif
def approval_node(state):
    answer = interrupt({"question": "Approve the refund?"})
    return {"approved": answer == "yes"}

# somewhere else, eventually:
graph.invoke(Command(resume="yes"), config)

Le point de blocage

  • interrupt() ne prévient personne. Le graphe est en pause et aucune notification n’est envoyée.
  • Un composant doit appeler Command(resume=...). À vous de construire ce déclencheur et l’écran sur lequel la personne répond.
  • MemorySaver perd la pause si le processus s’arrête. Toute attente réelle exige un checkpointer persistant.
  • Le checkpoint indique que le graphe s’est arrêté. Il n’enregistre ni qui a décidé ni ce que cette personne a vu.

La solution

Pushary recueille la réponse de votre utilisateur.

interrupt() met le graphe en pause. Pushary envoie la question sur le téléphone de votre utilisateur, attend une approbation ou un refus, enregistre la réponse et la transmet à votre serveur par webhook signé. Votre code peut alors reprendre le bon fil.

connect() renvoie un lien que votre utilisateur ouvre une seule fois. Dans le nœud, ask_human envoie la question et attend la réponse, 55 secondes par défaut. Le nœud renvoie approved uniquement après un oui explicite : dirigez l’étape sensible vers cette branche.

bash
pip install pushary-langgraph
deux appels
from pushary_langgraph import connect, ask_human

# Once per user: show them this link.
link = connect("user_123")

# Ask from inside a LangGraph node. No answer means no.
def approve_transfer(state):
    d = ask_human("Approve this transfer?", external_id=state["user_id"], node="approval")
    return {"approved": d["approved"]}

Pour une longue attente, utilisez une interruption

Avec un callback_url, pushary_interrupt met le graphe en pause via interrupt() de LangGraph et rend la main immédiatement. Rien ne s’exécute pendant que votre utilisateur décide. Pushary transmet la réponse à votre serveur par webhook signé. Votre worker la vérifie et reprend le fil avec Command(resume=...).

attente longue
from pushary_langgraph import pushary_interrupt

def review_order(state):
    answer = pushary_interrupt(
        f"Submit order {state['order_id']}, revision {state['revision']}?",
        external_id=state["customer_id"],
        idempotency_key=state["review_operation_id"],
        type="confirm",
        node="submit-order",
        callback_url="https://your-app.example/pushary/callback",
    )
    return {"approved": answer == "yes"}

Fonctionnement

De l’installation à la première réponse

Connectez votre utilisateur une seule fois. Exigez son approbation à l’étape sensible. Pushary envoie la question, attend la réponse et l’enregistre.

  1. 01

    Installez l’adaptateur

    Exécutez pip install pushary-langgraph pour Python, ou npm i @pushary/langgraph pour TypeScript. Placez votre clé API dans PUSHARY_API_KEY.

  2. 02

    Connectez votre utilisateur une seule fois

    connect() renvoie un lien. Votre utilisateur l’ouvre sur son téléphone avec l’application Pushary gratuite. Les questions oui/non affichent Approuver et Refuser sur l’écran verrouillé.

  3. 03

    Posez la question dans le nœud avant l’étape sensible

    Appelez ask_human pour une courte attente, ou pushary_interrupt avec une URL de rappel pour une attente longue. Ne dirigez l’exécution vers l’étape sensible qu’après un oui.

  4. 04

    Agissez selon la réponse

    Une approbation emprunte la branche sensible. Un refus, une expiration ou l’absence de réponse ne l’emprunte jamais. Un choix ou une réponse écrite fournit des données pour l’étape suivante, jamais une autorisation d’agir.

Une question peut demander un oui ou un non, un choix dans une liste ou une réponse écrite. Chaque réponse est enregistrée.

Avant la mise en production

Les pièges à éviter avec LangGraph

À la reprise, le nœud entier est réexécuté
C’est un piège fréquent. LangGraph réexécute le nœud depuis le début, pas depuis l’appel interrupt(). Tout effet de bord situé avant l’interruption se produit deux fois. Débitez une carte puis posez la question dans le même nœud : vous débitez deux fois. Rendez ce travail sûr en cas de répétition, ou déplacez-le dans son propre nœud.
Deux interruptions dans un nœud sont associées par ordre
Deux appels interrupt() dans le même nœud reçoivent leurs valeurs de reprise selon leur position, pas leur nom. Ajoutez une branche qui saute le premier : le second reçoit silencieusement la mauvaise réponse.
Question bloquante et interruption impliquent des compromis différents
ask_human maintient la requête ouverte et peut atteindre son délai limite. Une interruption exige un checkpointer persistant, un identifiant de fil enregistré et du code qui vérifie la réponse puis reprend le graphe. Une URL de rappel seule ne fournit rien de tout cela.

L’offre Partner

Votre agent interroge vos utilisateurs, pas seulement vous

Proposez votre agent à vos utilisateurs. Chacun approuve ses actions sensibles depuis son téléphone, sous votre marque.

$99/ mois, tous les frameworks inclus
Start free

Vos utilisateurs ne créent jamais de compte Pushary et ne nous paient rien.

Vos utilisateurs répondent sur leur propre téléphone

Connectez chaque utilisateur une seule fois avec un lien. Il installe l’application Pushary gratuite et répond depuis l’écran verrouillé, sans créer de compte.

Sans réponse, c’est non

Exécutez l’action uniquement après une approbation explicite. Une demande en attente, expirée ou annulée ne vaut jamais un oui. Pushary conserve chaque demande : votre code peut la reprendre après un redémarrage.

Joignez-les sur leur téléphone

L’application passe en premier, car elle seule affiche Approuver et Refuser sur l’écran verrouillé. Les notifications du navigateur viennent ensuite. Vous n’avez aucun système d’envoi à construire.

Chaque réponse est enregistrée

Chaque réponse est enregistrée avec son auteur et sa date. Vous pouvez effectuer des recherches et exporter les réponses. Avec une URL de rappel, chaque réponse est aussi envoyée à votre serveur par webhook signé.

FAQ

Les réponses à vos questions

Existe-t-il un package Pushary pour LangGraph ?
Oui. pushary-langgraph pour Python et @pushary/langgraph pour TypeScript, sur PyPI et npm. Les deux proposent connect(), une question bloquante (ask_human, ou createAskHumanTool en TypeScript) et pushary_interrupt ou pusharyInterrupt, qui met le graphe en pause via interrupt de LangGraph jusqu’à la réponse de votre utilisateur.
Faut-il utiliser ask_human ou pushary_interrupt ?
Utilisez ask_human si la réponse arrive en moins d’une minute ; l’attente dure 55 secondes par défaut. Utilisez pushary_interrupt avec une URL de rappel si votre utilisateur peut répondre plus tard. Le graphe se met en pause avec un checkpointer persistant, et votre code reprend le fil correspondant à l’arrivée du webhook signé.
Que se passe-t-il si personne ne répond ?
L’étape sensible ne s’exécute pas. ask_human renvoie approved false, et pushary_interrupt renvoie None pour une demande expirée ou annulée. Pushary n’envoie aucun webhook dans ces cas : vérifiez périodiquement la demande si vous attendez le webhook. Distinguez « personne n’a répondu » de « votre utilisateur a dit non ». La réponse enregistrée et le checkpoint du graphe sont séparés ; aucun des deux ne reprend le graphe seul.
Mes propres utilisateurs finaux peuvent-ils approuver sur leur téléphone ?
Oui. Votre code choisit qui répond, avec votre propre identifiant utilisateur. La personne installe l’application Pushary gratuite et ouvre votre lien de connexion une fois, sans clé API ni abonnement payant personnel.
Cela fonctionne-t-il avec des agents LangChain classiques ?
Oui. ask_human est une fonction ordinaire : vous pouvez l’appeler dans tout outil ou callback LangChain, comme dans un nœud LangGraph. En TypeScript, createAskHumanTool fournit un outil prêt à l’emploi pour createReactAgent.
Pourquoi mon interruption LangGraph ne fonctionne-t-elle pas ?
Le plus souvent, le graphe n’a pas de checkpointer, vous avez repris avec une entrée ordinaire, ou l’interruption se trouve dans un outil ou un sous-graphe. Sans checkpointer, aucun état de pause ne peut être conservé : le graphe continue. Une entrée ordinaire lance une nouvelle exécution ; reprenez avec Command(resume=value). Une interruption dans un outil ou un sous-graphe n’apparaît pas dans la sortie du graphe parent. Des effets de bord répétés signifient que le nœud a été réexécuté depuis le début.

Laissez votre agent LangGraph demander avant d’agir.

Connectez un utilisateur une seule fois, posez une question en un appel et exécutez l’action uniquement après un oui. Chaque réponse est enregistrée.

Start free

Offre Partner, $99 par mois. Vos utilisateurs ne créent jamais de compte Pushary et ne nous paient rien.