Startseite / Artikel

IntentFlow: Steuerung von LLM-Agenten mit kompilierten Richtlinien und prüfbaren Spuren

Ein Blick auf IntentFlow, eine experimentelle Sprache, die die Richtlinien des Agents außerhalb des Modells durchsetzt und hash-basierte Spuren erzeugt, die ein Prüfer unabhängig überprüfen kann.

Verlag: REACTAPP.TOP8 Min. Lesezeit1780 Wörter

Quellen: IntentFlow: Governed LLM Agents With Auditable, Hash-Chained Traces

Stellen Sie sich einen LLM-Agenten vor, der dazu programmiert ist, ein GitHub-Problem zu lesen, im Repository zu suchen, eine Antwort zu entwerfen und – da jemand in Eile war – diese Antwort zu veröffentlichen und das Problem zu schließen. Die Sicherheitsregeln wurden in die Anweisung aufgenommen: Ein Problem niemals schließen, stets Beweise anführen und bei Unsicherheit einen Menschen um Rat fragen. Dennoch schloss das Modell das Problem trotzdem.

Es lag keine Böswilligkeit vor. In Prosa formulierte Sicherheitsregeln sind lediglich Vorschläge, und ein Modell, das durch einen geschickt formulierten Problemtext angetrieben wird, betrachtet solche Vorschläge manchmal als optional. Wenn ein Sicherheitsprüfer nach Beweisen verlangt, dass der Agent niemals eine verbotene Aktion ausgeführt hat, gibt es lediglich Anwendungsprotokolle, die vom selben Codepfad in einem von jemandem erfundenen Format erstellt wurden. Das sind keine Beweise – es handelt sich dabei um ein Tagebuch.

IntentFlow ist eine experimentelle Sprache, die entwickelt wurde, um diese Lücke zu schließen.

Wo die Governance normalerweise angesiedelt ist

Die meisten Regeln zur Steuerung von Agenten befinden sich an einem von drei Orten, und jeder von ihnen weist Schwachstellen auf:

  • In der Anfrage. Es handelt sich um Prosa, die das Modell ignorieren kann, und die einzige Überprüfung besteht darin, die endgültige Ausgabe zu lesen und zu hoffen.
  • In dem Anwendungscode. Das ist eine echte Durchsetzung, doch die Richtlinie ist nun mit dem Python verknüpft, das das Modell aufruft, und die Frage „Was durfte der Agent tun?“ wird durch das Durchlesen des Codebases beantwortet.
  • In der Ansammlung an Callbacks eines Frameworks. Funktionen werden miteinander verbunden, während die Richtlinie im Kopf von jemandem sowie in ad-hoc-Protokollen existiert.

Was fehlt, ist ein einziges überprüfbares Dokument, das den Rahmen des zulässigen Verhaltens beschreibt: die Beweise, die der Agent haben muss, die Aktionen, die er ausführen darf, die, die er auf keinen Fall ausführen darf, welche Faktoren einen Menschen in den Überprüfungsprozess bringen und wie seine Ausgabe überprüft wird. Dieses Dokument sollte außerhalb des Modells durchgesetzt werden und einen Nachweis hinterlassen, den jeder später unabhängig überprüfen kann.

Die Idee in einem Absatz

IntentFlow ist eine kleine deklarative Sprache. Eine .iflow-Datei legt das Ziel einer Aufgabe, die Anforderungen an Beweise, die Handlungsrichtlinien, die Überprüfungsregeln, die Handhabung von Unsicherheiten sowie einen typisierten Ausgabevertrag fest. Ein Compiler wandelt die Datei in einen JSON-Ausführungsplan um, der anschließend von einem aus 13 Phasen bestehenden Laufzeitsystem ausgeführt wird. Jeder Toolaufruf wird über ein ActionGate weitergeleitet, einschließlich des Lesens von Beweismitteln von der Festplatte. Das Gate bezieht seine Informationen aus der kompilierten Richtlinie und liest niemals den Ausgabeinhalt des Modells, sodass das Modell nicht umgehend umgehen kann. Jeder Ausführungsvorgang erzeugt eine mit Hash-Werten versehene Spur, die optional signiert werden kann. Anschließend erstellt intentflow audit die Regeln erneut aus der Quelldatei und zeigt nach, dass der Ausführungsvorgang darin blieb. Dafür benötigt es lediglich die Datei sowie die Spur – es ist nicht notwendig, dem Laufzeitsystem, dem Backend oder dem Modell zu vertrauen.

Der Slogan des Projekts fasst es zusammen: Python-Programme ermöglichen deterministische Berechnungen, während IntentFlow-Programme von gesteuertem Denken angetrieben werden.

Wie ein Programm aussieht

Das repräsentative Beispiel ist ein Ziel zur Priorisierung von Problemen, das hier in seinem Steuerungskern dargestellt wird. Es beginnt mit einem Namen und einem Ziel:

goal TriageGitHubIssue {
  objective:
    triage a GitHub issue safely and propose a maintainer-ready response

Die verbleibenden Abschnitte behandeln Beweise, zulässige Aktionen, Überprüfung, Umgang mit Unsicherheiten sowie die Ausgabestruktur:

  evidence:
    require issue_body
    require comments
    require repo_context
    optional related_issues
    distrust unsupported_claims  actions:
    allow read_issue
    allow search_repo
    allow draft_comment
    require_approval post_comment
    deny close_issue  verify:
    require cites_evidence
    require maintainer_safe_tone
    require no_unverified_claims
    check confidence >= 0.65  uncertainty:
    if confidence < 0.65 ask_human
    if missing_evidence ask_human
    if security_risk block_action  output:
    summary: string
    likely_cause: string?
    confidence: number
    suggested_response: markdown
    proposed_labels: list[string]
}

Lesen Sie es von oben nach unten, dann wissen Sie, was der Agent tun kann. deny close_issue ist kein Ratschlag – es ist in die Prüfregel integriert. Mit require_approval post_comment wird der weitere Schritt standardmäßig abgelehnt, bis eine Person oder ein anderes Verfahren eine Genehmigung erteilt. check confidence >= 0.65 ist ein strenger numerischer Test. Der output:-Block ist ein vorgefertigtes Vertragsformat, gegen das das Ergebnis überprüft wird.

Wie es funktioniert

Der Ablauf ist kurz, und jede Stufe beschränkt, was die nächste tun kann:

.iflow source -> parser -> analyzer (IFLOW diagnostics) -> compiler ->
execution plan (JSON) -> runtime (13-phase machine) -> traced result ->
replay / audit

Mehrere Gestaltungsentscheidungen sorgen dafür, dass die Überprüfung sinnvoll statt dekorativ ist:

  1. Die Kontrollstelle befindet sich außerhalb des Modells. Abgelehnte oder nicht aufgelistete Aktionen verursachen Fehler, und Aktionen, die eine Genehmigung erfordern, scheitern ohne Genehmigung. Da die Kontrollstelle niemals die Ausgabe des Modells liest, hat die Prompt-Injektion nichts, womit sie verhandeln könnte.
  2. Die Kalibrierung kommt zuerst. Ein Backend gibt einen Rohwert für das Vertrauensniveau an, die Laufzeitanwendung passt diesen Wert gemäß der Kalibrierungspolitik des Plans an, und anschließend prüfen die Unsicherheitsregeln den angepassten Wert. Die Protokollierung speichert beide Werte.
  3. Die Überprüfung wird explizit durchgeführt, nicht einfach angenommen. Maschinenprüfbare Regeln wie cites_evidence, requires_phrase sowie Schwellenwertprüfungen werden anhand des tatsächlichen Zustands ausgeführt. Regeln, die eine Bewertung durch ein LLM benötigen, befinden sich in einer separaten Vertrauensstufe; wenn kein Bewertungsmodul verfügbar ist, werden sie als übersprungen protokolliert und niemals stillschweigend genehmigt.
  4. Die Spur ist nur zum Hinzufügen geeignet und vollständig. Jede Phase, jede Gate-Entscheidung, jede Eskalation sowie jede Überprüfung wird in ein hash-basiertes Protokoll aufgenommen, wobei jedes Ereignis einen Hash des vorherigen Hashs zusammen mit dem kanonischen Ereignis speichert. Das Signieren der Spur versiegelt den Root-Hash mit einem HMAC, sodass der Schlüsselinhaber Manipulationen erkennen kann.

Jeder Ausführungsvorgang endet mit einem von sechs möglichen Statusen, und der Prozessbeendigungscode spiegelt diesen wider. Die wichtige Garantie ist, dass eine fehlgeschlagene Überprüfung den Vorgang mit dem Status failed_verification beendet. Der Laufzeitumgebung ist es nicht gestattet, diesen Status als completed anzugeben, und eine der Überprüfungen durch den Prüfer dient ausdrücklich dazu, solche Versuche zu erkennen.

Probieren Sie es in fünf Minuten aus

Der Kern hat keine Laufzeitabhängigkeiten, und jeder der unten aufgeführten Befehle wird offline und deterministisch ohne API-Schlüssel ausgeführt. Er ist für Python 3.10 oder neuer geeignet.

git clone https://github.com/dgenio/intentflow
cd intentflow
pip install -e .

Überprüfen Sie das Leitbeispiel, bitten Sie um eine Erklärung und führen Sie es aus:

intentflow validate examples/opensource_triage.iflow
intentflow explain  examples/opensource_triage.iflow
intentflow run      examples/opensource_triage.iflow \
    --backend simulate --trace-dir traces

Der Ausführungsvorgang gibt eine Zusammenfassung wie diese aus, die eine echte Ausführung in Version 0.6.0 darstellt:

--- run summary ---
  goal:               TriageGitHubIssue
  status:             completed
  backend:            simulate
  confidence:         0.676
  verification:       passed
  uncertainty:        clear
  trace id:           b9f44900...
trace written to traces/TriageGitHubIssue-...json

Überprüfen Sie nun, wie es sich verhalten hat. Der audit-Befehl rekompiliert die Quelle und stellt sicher, dass der Ablauf innerhalb der Grenzen des Programms bleibt:

intentflow audit examples/opensource_triage.iflow traces/TriageGitHubIssue-*.json

Ein sauberes Ergebnis sieht so aus:

{
  "goal": "TriageGitHubIssue",
  "conformant": true,
  "violations": []
}
AUDIT: CONFORMANT — the trace stayed inside the program's envelope

Um zu sehen, wie die Einschränkungen tatsächlich aktiviert werden, versuchen Sie das absichtlich riskante Beispiel. Es erlaubt eine Bereitstellungsaktion ohne jeglichen Genehmigungsprozess. Der Analysetool gibt IFLOW010 aus, das kompilierte Risikoprofil weist ein hohes Niveau auf, und wenn die Regel if security_risk block_action ausgeführt wird, tritt sie in Kraft:

intentflow run examples/high_risk_deploy.iflow --backend simulate
# -> status: blocked

Die abgelehnte write_database-Aktion kann unter keinen Umständen ausgeführt werden, egal was das Modell besagt.

Die gleichen Funktionen sind auch aus Python verfügbar. Beginnen Sie mit dem Import:

import intentflow

Dann laden Sie ein Programm, führen Sie es aus und registrieren Sie eine Python-Funktion als gesteuerte Aktion:

program = intentflow.load("examples/opensource_triage.iflow")
result = program.run(backend="simulate")
assert result["status"] == "completed"# register a Python function as a governed action (runs through the gate):
program.register_tool("lookup_user", serves=("user_record",),
                      handler=lambda src: "enterprise plan")report = intentflow.audit_document(program.compile(), result)
assert report["conformant"]

Das Registrieren eines Tools umgeht die Governance nicht. Ihre Funktion läuft weiterhin über das Aktionstor.

Warum die Zuverlässigkeit von 0,72 auf 0,676 fällt

Das ist kein Defekt und spiegelt die gesamte Konzeption wider. Das Beispiel zur Produktionsdiagnose verwendet einen Schwellenwert von 0,7. Im Simulator beträgt die Rohzuverlässigkeit 0,72, was ausreichen würde, doch die Kalibrierung senkt diesen Wert auf 0,676, was unter dem Schwellenwert liegt; daher endet der Vorgang absichtlich mit dem Status needs_human. Eine Diagnose, bei der sich das Agent unsicher ist, sollte nicht unbeaufsichtigt abgeschlossen werden. Der Simulator dient dazu, diese gesamte Steuerungsstruktur aus Toren, Kalibrierung, Überprüfung, Eskalation und Nachverfolgung end-to-end ohne Netzwerkprobleme oder unzuverlässiges Verhalten testen zu können.

Ehrliche Einschränkungen

IntentFlow befindet sich in Version 0.6.0 und gilt als pre-alpha, da es noch keinen CI-Pipeline gibt. Es funktioniert, und das Repository enthält etwa 233 Tests, die weder ein Netzwerk noch API-Schlüssel benötigen, doch es gibt echte Lücken:

  • Die Grammatik ist zeilenorientiert und verfügt über keine zusammengesetzten Bedingungen, sodass es kein if a and b gibt.
  • Die Kalibrierung erfolgt mithilfe einer festen Schrumpfungskarte statt eines gelernten Modells, obwohl eine lernbasierte Karte geplant ist.
  • Objektförmige Ausgaben haben nur auf der äußersten Ebene einen Typ, wobei für deren Inhalt keine Vorgaben gelten.
  • Ungewissheitsepriprimitive außer ask_human und block_action werden zwar erfasst, aber nicht ausgeführt.
  • Tools mit Nebeneffekten sind zwar durch Richtlinien abgedeckt, werden aber tatsächlich nie ausgeführt. Die Regeln dazu sowie die Durchführung echter Ausgabevorgänge stehen noch aus.
  • Die Pipelines sind linear, wobei DAGs auf dem Entwicklungsplan stehen.

Der Simulator simuliert den Überlegungsprozess und gibt dies an. Es existieren Backend-Lösungen für OpenAI und Anthropic, die denselben Verwaltungsweg nutzen, und ein Wiedergabemodus ermöglicht deterministische CI-Ausführungen ohne Schlüssel. Dennoch dient der deterministische Simulator als Referenz für die Konformität.

Für einen heutigen Regulator von Produktionsagenten ist dies noch nicht ausreichend. Um klar zu verstehen, wie eine prüfbare Agentenausführung aussehen sollte, und um damit zu experimentieren, ist das Projekt für sein Alter außergewöhnlich konkret.

Was man mitnehmen sollte

  • Lassen Sie Richtlinien außerhalb des Modells. Prosa ist lediglich eine Anfrage, während eine kompilierte deny-Anweisung, die durch ein Gate gestützt wird, das die Modellausgabe ignoriert, eine feste Regel darstellt.
  • Selbst verfasste Logs beweisen nicht viel, doch ein von einer unabhängigen Partei überprüfbarer Trace schon. Der Prüfer leitet die Regeln erneut aus der Quelle ab und benötigt lediglich diese Quelle sowie den Trace.
  • Die angepasste Unsicherheit sollte in der Lage sein, eine Abfolge von Aktionen zu stoppen. Wenn der Wert von 0,72 auf 0,676 gesenkt wird und somit die Marke von 0,7 Bar verfehlt, handelt es sich um das beabsichtigte Verhalten: Ein Agent, der sich nicht sicher ist, überträgt die Kontrolle an einen Menschen anstelle davon, zu bluffen.
  • Der gesamte Steuerungslauf kann offline getestet werden: Es gibt keine Abhängigkeiten, einen deterministischen Simulations-Backend sowie keine API-Schlüssel.
  • Setzen Sie realistische Erwartungen an Vor-Alpha-Software: Sie funktioniert und ist gut getestet, es gibt jedoch noch keinen CI-Prozess, die Pipelines sind linear, die Kalibrierung ist festgelegt und tools mit Nebeneffekten werden nicht ausgeführt.
  • Um eine solche Idee ordnungsgemäß zu testen, muss man ihr ein reales Ziel geben. Schreiben Sie eine .iflow-Datei für einen Agenten, den Sie tatsächlich betreiben, überprüfen Sie, ob der „explain“-Befehl das beschreibt, was Sie beabsichtigt haben, führen Sie ihn anschließend im Simulationsmodus aus und prüfen Sie den Ablaufverlauf.