Human-in-the-loop für LangChain

Menschliche Entscheidungen für LangChain-Agenten, auf dem Handy.

Ein Aufruf in deinem riskanten LangChain-Tool reicht: Es wartet, bis dein Nutzer auf dem Handy zustimmt.

Was LangChain mitbringt

Middleware, die vor einem Tool unterbricht

LangChain 1.0 verarbeitet Freigaben in Middleware. Du legst fest, welche Tools eine Freigabe brauchen. Vor diesen Aufrufen unterbricht der Agent mit einer ausstehenden Anfrage, die dein Code genehmigt, bearbeitet oder verwirft. Intern nutzt das LangGraphs Interrupt.

nativ
agent = create_agent(
    model=model,
    tools=[issue_refund],
    middleware=[
        HumanInTheLoopMiddleware(
            interrupt_on={"issue_refund": True},
        ),
    ],
    checkpointer=checkpointer,
)

Wo es nicht weitergeht

  • Es braucht einen Checkpointer. Die Graph-Laufzeit läuft also mit, ob du das vorhattest oder nicht.
  • Der Interrupt erreicht deinen Code, keinen Menschen. Jemanden zu erreichen ist deine Aufgabe.
  • Es wird nichts protokolliert. Es gibt keinen Nachweis darüber, was die Middleware angehalten hat.

Die Lösung

Pushary holt die Antwort deines Nutzers ein.

Die Middleware hält das Tool an und übergibt deinem Code eine ausstehende Anfrage. decisions.ask() schickt die Frage auf das Handy deines Nutzers, wartet auf Freigabe oder Ablehnung und speichert die Antwort.

Das ask_human-Tool ruft decisions.ask() auf. Es schickt die Frage auf das Handy deines Nutzers und wartet bis zu 55 Sekunden auf die Antwort. Nur bei einem ausdrücklichen Ja gibt es approved zurück. Nutze pushary in Python oder @pushary/server in TypeScript. Du musst keinen Wrapper installieren.

bash
pip install pushary
zwei Aufrufe
import os
from langchain_core.tools import tool
from pushary import PusharyServer

px = PusharyServer(api_key=os.environ["PUSHARY_API_KEY"])

# Once per user: show them this link to connect their phone.
link = px.enroll("user_123")["universalLink"]

@tool
def ask_human(question: str) -> str:
    """Ask a real person to approve before acting."""
    d = px.decisions.ask(question=question, external_id="user_123", type="confirm")
    return "approved" if d["approved"] else f"not approved ({d['status']})"

# agent = create_agent(model, tools=[ask_human])

So funktioniert es

Von der Installation zur ersten Antwort

Verbinde deinen Nutzer einmal. Sichere den riskanten Schritt mit einer Freigabe ab. Pushary schickt die Frage, wartet auf die Antwort und speichert sie.

  1. 01

    SDK installieren

    Führe pip install pushary für Python oder npm i @pushary/server für TypeScript aus. Speichere deinen API-Schlüssel in PUSHARY_API_KEY.

  2. 02

    Nutzer einmal verbinden

    Ein SDK-Aufruf pro Nutzer liefert einen Verbindungslink. Dein Nutzer öffnet ihn einmal mit der kostenlosen Pushary-App auf seinem Handy. Kein Konto, keine Zahlung.

  3. 03

    decisions.ask in ein @tool einbinden

    Definiere ein @tool, das px.decisions.ask() aufruft, und füge es den Tools deines Agenten hinzu. Der Docstring sagt dem Modell, wann es das Tool verwenden soll.

  4. 04

    Auf die Antwort reagieren

    Das Tool gibt nur bei einem ausdrücklichen Ja approved zurück. Bei Nein, abgelaufener Anfrage oder fehlender Antwort führt der Agent die Aktion nicht aus.

Eine Frage kann ein Ja oder Nein verlangen, eine Auswahl aus einer Liste oder eine Texteingabe. Jede Antwort wird gespeichert.

Vor der Veröffentlichung

Stolperfallen bei LangChain

Ein optionales Tool erzwingt keine Freigabe
ask_human ist ein Tool, dessen Aufruf das Modell selbst wählt. Es ist daher optional. Ein Prompt mit „erst fragen“ verhindert keine Erstattung. Rufe decisions.ask() direkt im Erstattungs-Tool auf oder sichere es mit interrupt_on der Middleware ab.
Ohne Checkpointer kein Interrupt
Ohne Checkpointer kann die Middleware nichts Sinnvolles tun, weil sie den Zustand nirgendwo ablegen kann. Die Tools laufen direkt durch. Es wirkt, als würde die Konfiguration ignoriert.
Edit lässt einen Menschen Tool-Argumente ändern
Freigeben ist einfach. Beim Bearbeiten ändert ein Mensch die Argumente vor der Tool-Ausführung. Texteingaben gelangen damit direkt in dein Tool. Prüfe bearbeitete Argumente genauso wie Modellausgaben.
Tool-Namen müssen exakt übereinstimmen
interrupt_on verwendet den Tool-Namen als Schlüssel. Benennst du das Tool um, greift die Sperre stillschweigend nicht mehr, ohne Fehler oder Warnung. Schreibe einen Test, der prüft, ob das geschützte Tool wirklich unterbrochen wird.

Der Partner-Tarif

Dein Agent fragt deine Nutzer, nicht nur dich

Stelle deinen Nutzern deinen Agenten bereit. Jeder gibt dessen riskante Aktionen vom eigenen Handy aus frei, unter deiner Marke.

$99/ Monat, alle Frameworks enthalten
Start free

Deine Nutzer brauchen kein Pushary-Konto und zahlen nichts an uns.

Deine Nutzer antworten auf ihren eigenen Handys

Verbinde jeden Nutzer einmal über einen Link. Er installiert die kostenlose Pushary-App und antwortet vom Sperrbildschirm aus, ohne eigenes Konto.

Keine Antwort heißt Nein

Führe die Aktion nur nach einer ausdrücklichen Freigabe aus. Eine wartende, abgelaufene oder abgebrochene Anfrage zählt nie als Ja. Pushary behält jede Anfrage, damit dein Code sie nach einem Neustart wieder aufnehmen kann.

Erreicht sie auf dem Handy

Die App kommt zuerst, denn nur sie zeigt „Genehmigen“ und „Ablehnen“ auf dem Sperrbildschirm. Browser-Benachrichtigungen folgen danach. Du musst kein Zustellsystem bauen.

Jede Antwort gespeichert

Zu jeder Antwort wird gespeichert, wer wann geantwortet hat. Du kannst sie durchsuchen und exportieren. Mit einer Callback-URL geht jede Antwort außerdem als signierter Webhook an deinen Server.

FAQ

Fragen und Antworten

Brauche ich ein spezielles Paket für LangChain?
Nein. Ein LangChain-Tool ist eine normale Funktion. Der Aufruf von decisions.ask() aus pip install pushary oder @pushary/server in TypeScript ist daher die gesamte Integration. Baust du auch LangGraph-Graphen, ergänzt pushary-langgraph ein fertiges ask_human und einen Interrupt, der den Graphen pausiert, bis dein Nutzer antwortet.
Funktioniert das mit create_agent und älteren Agenten-Laufzeiten?
Ja. ask_human ist ein normales LangChain-Tool und funktioniert überall, wo LangChain-Tools funktionieren: in create_agent, vorgefertigten LangGraph-Agenten und eigenen Executors. Der Aufruf darin hängt nicht von der Laufzeit ab.
Was passiert, wenn niemand antwortet?
Die Aktion läuft nicht. decisions.ask() meldet alles außer einem ausdrücklichen Ja als nicht genehmigt. Pushary behält die Anfrage nach Ende der Wartezeit. Eine späte Antwort wird weiter gespeichert, geht bei einem Neustart nicht verloren und kann später von deinem Code gelesen werden.
Können meine Endnutzer statt mir antworten?
Ja. Übergib bei jedem Aufruf deine eigene Nutzer-ID der betreffenden Person. Jeder Nutzer verbindet sein Handy einmal über einen Link und die kostenlose Pushary-App und antwortet danach für seine eigenen Aktionen.
Gibt es einen Weg mit TypeScript?
Ja. Nutze @pushary/server und rufe pushary.decisions.ask() auf dieselbe Weise in einem LangChain.js-Tool auf. Der Aufruf ist wie im Python-SDK aufgebaut. Für LangGraph.js ergänzt @pushary/langgraph createAskHumanTool und pusharyInterrupt.
Wie ergänzt das die Human-in-the-loop-Middleware von LangChain?
Nutze beides. Die Middleware bestimmt, welche Tools anhalten. Das kann LangChain gut. Dann übergibt sie die ausstehende Anfrage an deinen Code. Pushary übernimmt den nächsten Teil: Es erreicht deinen Nutzer auf dem Handy, wartet auf die Antwort, wertet keine Antwort als Nein und speichert den Nachweis.

Lass deinen LangChain-Agenten fragen, bevor er handelt.

Verbinde einen Nutzer einmal, frage mit einem Aufruf und führe die Aktion nur bei einem Ja aus. Jede Antwort wird gespeichert.

Start free

Partner-Tarif, $99 im Monat. Deine Nutzer brauchen kein Pushary-Konto und zahlen nichts an uns.