Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Agent Hooks ist eine Kernfunktion des Agent-Frameworks, mit der sich Governance- und Laufzeitkontrollen an klar definierten Punkten während der Ausführung eines Agenten anwenden lassen. Es implementiert die framework-neutrale AGENT-HOOKS-0.1-Spezifikation, sodass Policy-Engines, Genehmigungs-Gateways, Budgetkontrollen, Inhaltsfilter und Egress-Kontrollen eine gemeinsame Kontrollschnittstelle ansprechen können.
Important
Agent Hooks ist eine Steuerebene, keine Telemetrieebene. Jeder Interceptor gibt eine Bewertung zurück. Im enforce Modus fungiert das Framework für diese Bewertung. Im evaluate_only Modus zeichnet es die Bewertung auf, ohne die Ausführung zu ändern. Verwenden Sie Observability für passives Tracing, Metriken und Protokolle.
Agent Hooks sind für .NET noch nicht verfügbar. Verwenden Sie Agent-Middleware, Toolgenehmigung und Agentsicherheit, um Laufzeitsteuerelemente zu .NET Agents hinzuzufügen.
Agent Hooks ist experimentell in Python. Bei der ersten Verwendung gibt die Factory ein ExperimentalWarning aus, und ihre API kann sich vor der allgemeinen Verfügbarkeit noch ändern.
Wann Agent-Hooks verwendet werden sollen
Verwenden Sie Agent Hooks, wenn unabhängig entwickelte Steuerungen einen gemeinsamen, durchsetzbaren Vertrag für Agent-Eingaben, Modellaufrufe, Toolaufrufe und die endgültige Ausgabe benötigen.
| Capability | Verwenden Sie es für |
|---|---|
| Agent-Hooks | Standardisierte Richtlinienentscheidungen, Transformationen, Genehmigungen, Budgets und Egress-Kontrollen über den gesamten Agent-Lebenszyklus hinweg. |
| Middleware für Agenten | Anwendungsspezifisches Querschneidverhalten, das den Agent Hooks-Vertrag oder seine Kernlaufzeitgarantien nicht benötigt. |
| Agent-Sicherheit mit FIDES | Deterministische Informationsflussbezeichnungen und Richtlinien für nicht vertrauenswürdige oder vertrauliche Inhalte. |
| Toolgenehmigung | Menschliche Bestätigung einzelner Funktionstoolaufrufe. |
| Beobachtbarkeit | Passive Ablaufverfolgungen, Metriken und Protokolle, die die Ausführung nicht steuern. |
Was das Agent-Framework erzwingt
Wenn Sie Agent-Hooks zu einem Agent hinzufügen, wendet Agent Framework eine koordinierte Erzwingungsgrenze für Agentausführungen, Modellanrufe und Toolaufrufe an. Die Laufzeit bietet die folgenden Garantien:
- Fail-Closed: Eine Verweigerung blockiert die geschützte Aktion. Ungültige Kontexte, ungültige Entscheidungen, Fehler bei Interzeptoren und Erzwingungsfehler umgehen Kontrollen nicht stillschweigend.
- Transform-Rückschreiben: Eine Transformation ändert die nativen Nachrichten, Tool-Argumente, Tool-Ergebnisse oder die endgültige Antwort, die bei der Ausführung tatsächlich verwendet werden. Wenn eine Transformation nicht angewendet werden kann, wird die Ausführung mit Fail-Closed beendet.
- Gepuffertes Streaming: Keine Aktualisierung der Antwort kommt beim Aufrufer an, bis die vollständige Modellantwort und die endgültige Ausgabe ihre Abfangpunkte durchlaufen haben.
-
Urteilsabhängige Persistenz: Die Persistenz wartet auf das Urteil, das sie betrifft. Die standardmäßige Persistenz nach der Ausführung wartet auf
output. Die Persistenz des Verlaufs pro Dienstaufruf wartet auf jedespost_model_call. - Vollständige Bundleinstallation: Die Agent-, Chat- und Funktionsteile werden als eine Einheit installiert, sodass eine unvollständige Erzwingungsgrenze nicht versehentlich konfiguriert werden kann.
Der Vertrag ist kooperativ und nicht eine Prozessisolationsgrenze. Interceptors werden im Hostprozess ausgeführt und empfangen den Inhalt, der für Entscheidungen erforderlich ist. Registrieren Sie nur Interceptors, die Sie als vertrauenswürdig einstufen.
Agent-Hooks installieren
Installieren Sie das Agent Hooks SDK als direkte Abhängigkeit:
pip install agent-hooks-sdk
Wenn Sie uv verwenden:
uv add agent-hooks-sdk
Die Abhängigkeit agent-hooks-sdk wird verzögert importiert. Beim Importieren agent_framework wird das SDK nicht geladen, es sei denn, Sie erstellen ein Agent Hooks Middleware-Bundle.
Note
agent-framework-core enthält kein agent-hooks extra. Installieren Sie agent-hooks-sdk separat, bevor Sie ein Agent Hooks Middleware-Bundle erstellen.
Hinzufügen eines Interceptors
Ein Interceptor empfängt ein agent_hooks.AgentContext (die Kontextzuordnung der Spezifikation, nicht das agent_framework.AgentContext, das von der Agent-Middleware verwendet wird) und gibt ein Urteil zurück. Der folgende Interceptor blockiert die endgültige Ausgabe, die das Wort secret enthält. Es wird angenommen, dass es sich client um einen bereits konfigurierten Agent Framework-Chatclient handelt.
from agent_framework import Agent, create_agent_hooks_middleware
from agent_hooks import ALLOW, AgentContext, InterceptionBlocked, Verdict
class SecretEgressGuard:
def intercept(self, context: AgentContext) -> Verdict:
if (
context["interception_point"] == "output"
and "secret" in str(context["target"]).lower()
):
return Verdict.deny(
reason="secret_in_output",
message="The final response contains restricted content.",
)
return ALLOW
hooks = create_agent_hooks_middleware(
{"secret-egress": SecretEgressGuard()},
)
agent = Agent(
client=client,
instructions="You are a helpful assistant.",
middleware=[hooks],
)
try:
response = await agent.run("Summarize the account details.")
except InterceptionBlocked as exc:
print(f"Blocked: {exc.result.verdict.reason}")
Übergeben Sie das Bundle als ein Element der middleware-Liste des Agents. Installieren Sie genau ein Agent Hooks Bundle auf jedem Agent.
Abfangpunkte
Das Agent-Framework gibt automatisch die entsprechenden Abfangenpunkte aus:
| Abfangenpunkt | Wenn sie ausgegeben wird | Transformationsziel |
|---|---|---|
agent_startup |
Vor der ersten Eingabe in einer Agent Hooks-Sitzung | Nicht transformierbar |
input |
Wenn eine externe Anfrage beim Agenten eingeht | Eingabeinhalt und -rolle |
pre_model_call |
Vor jeder Modellanforderung | Nachrichten, die an das Modell gesendet werden |
post_model_call |
Nach jeder vollständigen Modellantwort | Antwortinhalte, vom Framework ausgeführte Toolaufrufe und Endgrund |
pre_tool_call |
Vor jedem vom Framework ausgeführten Toolaufruf | Toolargumente |
post_tool_call |
Nachdem ein Tool erfolgreich war oder fehlschlägt | Ergebnis des Tools |
output |
Bevor die endgültige Antwort den Anrufer erreicht | Endgültiger Antwortinhalt |
agent_shutdown |
Wenn die Agent-Hooks-Sitzung abgeschlossen, fehlgeschlagen oder abgebrochen wird | Nicht transformierbar |
agent_startup.tools_registered ist der Snapshot des Run-Start-Tools. Jede pre_model_call-Payload enthält die effektiven Tools für diesen Modellaufruf in ihrem optionalen tools-Feld. Dazu gehören Tools, die während der Ausführung von Kontextanbietern, verbundenen MCP-Servern oder progressiver Offenlegung hinzugefügt werden. Das Feld wird weggelassen, wenn der Aufruf keine Tools enthält oder der Toolsatz nicht projiziert werden kann.
Eine Ausführung, die ein Tool aufruft, gibt in der Regel Folgendes aus:
agent_startup
input → → pre_model_call → post_model_call → pre_tool_call → post_tool_call → pre_model_call → post_model_call → → outputagent_shutdown
Urteile
Der Vertrag hat drei Entscheidungen: allow, , denyund transform. Das Python-SDK bietet außerdem Hilfsfunktionen für Warnungen und aufhebbare Sperren.
| Ergebnis | Python-API | Behavior |
|---|---|---|
| Allow |
ALLOW oder Verdict(decision=Decision.ALLOW) |
Fahren Sie mit dem Ziel unverändert fort. |
| Zulassen mit Warnung | Verdict.warn(...) |
Fahren Sie fort, und schließen Sie die Warnung in den Abfangendatensatz ein. |
| Verweigern | Verdict.deny(...) |
Blockieren der geschützten Aktion. |
| Ausstehende Genehmigung verweigern | Verdict.escalate(...) |
Blockieren, sofern der konfigurierte Genehmigungs-Resolver keine Permit-Entscheidung zurückgibt. |
| Umwandeln | Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) |
Überschreiben Sie einen Wert unter $target, und fahren Sie dann mit dem überschriebenen Wert fort. |
Verweigerungen auf Ausführungs- und Modellebene lösen InterceptionBlocked aus und verhindern, dass das geschützte Ergebnis den Aufrufer oder die nächste Phase erreicht. An einer Toolschnittstelle verhindert eine Richtlinienverweigerung die Toolaktion oder verwirft deren Ergebnis und gibt einen Steuerungsfehler mit dem Richtliniengrund ohne die verweigerte Zielnutzlast an das Modell zurück. Dadurch kann die Agenten-Schleife fortgesetzt werden. Ein Hostfehler oder ein Fehler bei der Durchsetzung stoppt die Ausführung.
Abbrechen einer Ausführung von Funktions-Middleware
Importiere MiddlewareFailure aus agent_framework. Die Funktions-Middleware wandelt eine gewöhnliche Ausnahme in der Regel in ein Fehlerergebnis des Tools um und lässt die Agent-Schleife dann weiterlaufen. Wenn Funktions-Middleware nicht sicher fortgesetzt werden kann, lösen Sie MiddlewareFailure aus der zugrunde liegenden Ausnahme aus. Die Laufzeit bricht die Ausführung ab und verteilt den Fehler an den Aufrufer, anstatt ihn in ein Toolergebnis zu konvertieren.
Fangen Sie MiddlewareFailure nicht in der Middleware ab. Das Abfangen der Ausnahme ermöglicht, dass die Schleife weiterläuft, und ändert das Verhalten von fail-closed zu fail-open. Agent Hooks verwendet dieses Signal intern, wenn seine Funktions-Middleware-Erzwingungsebene fehlschlägt. Übergeben Sie benutzerdefinierte Fail-Closed-Middleware in einer Sequenz, zum Beispiel middleware=[policy_middleware].
Bei parallelen Toolaufrufen bricht die Laufzeit gleichgeordnete, in Ausführung befindliche Aufrufe ab, bevor der Fehler weitergegeben wird. Abbruch ist kooperativ, sodass ein synchrones Tool, das bereits in einem Arbeitsthread ausgeführt wird, seine Nebenwirkungen beenden kann, aber das Ergebnis wird verworfen.
Anwenden einer Transformation
Ein Transformationspfad muss bei $target beginnen. Ein Interceptor kann z. B. den endgültigen Antwortinhalt ersetzen:
from agent_hooks import ALLOW, AgentContext, Decision, Transform, Verdict
class OutputRedactor:
def intercept(self, context: AgentContext) -> Verdict:
if context["interception_point"] != "output":
return ALLOW
return Verdict(
decision=Decision.TRANSFORM,
reason="redacted_output",
transform=Transform(
path="$target.content",
value="[Response removed by policy]",
),
)
Transformationen werden auf Agent Framework-Werte Content angewendet, wobei unterstützte Rich-Inhalte beibehalten werden, anstatt jeden Wert auf Nur-Text zu reduzieren. Ein fehlerhafter Pfad oder eine inkompatible Ersetzung führt zu einem Fail-Closed, anstatt mit dem ursprünglichen Wert fortzufahren.
Toolfreigabe und Argumentumwandlungen
Die Freigabe für das Agent-Framework-Tool und die Freigabestelle für Agent Hooks sind zwei getrennte Mechanismen. Für ein Funktionstool mit approval_mode="always_require" erstellt Agent Framework die Anfrage zur menschlichen Genehmigung, bevor die Funktionsmiddleware ausgeführt wird.
Wenn eine pre_tool_call Transformation genehmigungsgebundene Argumente ändert, führt die ursprüngliche Erteilung nichts aus. Das Framework gibt eine Ersetzungsanforderung zurück, die die geänderten Argumente enthält, und die Ausführung erfordert eine zweite Genehmigung.
Warnung
Für Tools, die approval_mode="always_require" verwenden, passen Sie den Toolaufruf bei post_model_call so an, dass die erste Genehmigungsanfrage des Frameworks die effektiven Werte enthält. Alternativ können Sie bei pre_tool_call zu Verdict.escalate(...) zurückkehren und die Genehmigung über die Agent Hooks resolver auflösen.
Argumenttransformationen müssen vor der Sicherheits- oder Richtlinienverarbeitung ausgeführt werden. Die Mutation schlägt anschließend im geschlossenen Zustand mit MiddlewareFailure fehl.
Streaming und Persistenz
Agent Hooks behält die Streaming-API bei, verwendet jedoch die Semantik gepufferter Ausgabe. Das Agent-Framework setzt die vollständige Modellantwort zusammen, gibt post_model_call aus, setzt die endgültige Agentenantwort zusammen und gibt output aus, bevor Aktualisierungen freigegeben werden. Wenn eines der Punkte die Antwort verweigert, empfängt der Anrufer keine partiellen Aktualisierungen.
Dieses Verhalten tauscht die Token-für-Token-Latenz gegen die Erzwingung der Fail-Closed-Ausgabe ein. Eine Ausgabetransformation spiegelt sich auch in den Updates wider, die schließlich für den Aufrufer freigegeben werden.
Die Persistenz wird durch den Abfangpunkt gesteuert, der den Persistenzvorgang abdeckt:
- Standardmäßig warten der Verlauf und andere Anbieteraufgaben nach der Ausführung auf das Urteil
output. Eine verweigerte Ausgabe wird nicht beibehalten, und eine Ausgabetransformation wird nach der Transformation beibehalten. - Wenn Sie
require_per_service_call_history_persistence=Truefür den KonstruktorAgentoderclient.as_agent(...)festlegen, wird jeder Modellaustausch beibehalten, nachdem das Urteilpost_model_calldies zulässt. Eine spätere Verweigerung vonoutputmacht diesen bereits zulässigen Verlauf nicht rückgängig. - Bei der standardmäßigen Persistenz nach der Ausführung bleiben Wiederholungsversuche hinter der endgültigen Entscheidung
outputzurück. Im Modus pro Dienstaufruf wird stattdessen jede Modellantwort beibehalten, diepost_model_callpassiert.
Important
Wenn Modellinhalte nicht dauerhaft werden dürfen, erzwingen Sie diese Richtlinie bei post_model_call, wenn require_per_service_call_history_persistence=True. Eine Egress-Richtlinie nur für die Ausgabe schützt das, was den Aufrufer erreicht, entfernt jedoch nicht rückwirkend Modellaustausche, die bereits bei post_model_call zugelassen und beibehalten wurden.
Sitzungen und Auditprotokolle
Standardmäßig erstellt jeder Ausgeführte Agent eine Agent Hooks-Sitzung.
agent_startup und agent_shutdown klammern die Ausführung ein, und Datensätze erhalten eine Sitzungs-ID mit einer monoton steigenden Sequenz.
Verwenden Sie record_sink, um jede InterceptionRecord zu empfangen:
records = []
hooks = create_agent_hooks_middleware(
{"secret-egress": SecretEgressGuard()},
record_sink=records.append,
)
Abfangdatensätze erfassen die Entscheidung, den Grund, die Interceptor-Zusammenfassung, den Modus, die Identität und die Sequenz, ohne die abgefangene Nutzlast in den Überwachungsdatensatz zu kopieren. Der Interceptor selbst erhält weiterhin den vollständigen Kontext.
Übergreifen mehrerer Ausführungen mit einer Sitzung
Verwenden Sie create_agent_hooks_middleware_from_emitter(), wenn die Anwendung über eine länger andauernde Agent Hooks-Sitzung verfügt, z. B. eine Unterhaltung mit einem Genehmigungsledger:
from agent_framework import Agent, create_agent_hooks_middleware_from_emitter
from agent_hooks import AgentContextBuilder, InterceptionEmitter
emitter = InterceptionEmitter().register(SecretEgressGuard())
builder = AgentContextBuilder(
agent_id="support-agent",
framework="agent-framework",
session_id="conversation-42",
)
hooks = create_agent_hooks_middleware_from_emitter(emitter, builder)
agent = Agent(client=client, middleware=[hooks])
await emitter.emit(builder.agent_startup(tools_registered=[]))
await agent.run("First turn")
await agent.run("Second turn")
await emitter.emit(builder.agent_shutdown(reason="completed"))
In dieser Form konfiguriert die Anwendung den Emitter und übernimmt den Startvorgang, das Herunterfahren und die Fehlerbehandlung. Die Middleware gibt die Punkte pro Ausführung von input bis output aus.
Konfigurieren der Erzwingung
create_agent_hooks_middleware() akzeptiert die folgenden Steuerelemente:
| Parameter | Purpose |
|---|---|
interceptors |
Eine Abfolge von Interzeptoren oder eine Zuordnung von Namen zu Interzeptoren. Mindestens eines ist erforderlich. |
resolver |
Löst aufhebbare Verweigerungen über einen Genehmigungskanal auf. Ohne einen Resolver bleibt die Verweigerung in Kraft. |
mode |
"enforce" wendet Urteile an.
"evaluate_only" zeichnet auf, was passiert, aber jede Aktion zulässt. |
composition |
Wählt aus, wie mehrere Interceptor-Entscheidungen kombiniert werden. |
identity_provider |
Erzeugt inhaltsgebundene Kontextidentitäten. Der Standardwert lautet "jcs-sha256". |
timeout |
Timeout pro Interceptor und Resolver für erwartbare Aufrufe. Der Standardwert ist fünf Sekunden. Ein synchroner Interceptor oder Resolver, der die Ereignisschleife blockiert, kann durch dieses Timeout nicht unterbrochen werden. |
record_sink |
Empfängt jeden nutzlastfreien Abfangdatensatz. |
Die Standardkomposition ist sequenziell first_deny, wobei die Genehmigung so konfiguriert ist, dass die Faltung beendet wird. Die Reihenfolge der Interceptors ist daher wichtig: Platzieren Sie Steuerungen, die immer ausgeführt werden müssen, vor Steuerungen, die eine Genehmigung anfordern können. Lesen Sie die Produktionscheckliste für Agent Hooks, bevor Sie ein anderes Kompositionsprofil auswählen.
Führen Sie das Rollout im Modus „Nur auswerten“ durch.
Verwenden Sie evaluate_only, um das Richtlinienverhalten vor der Erzwingung zu messen:
hooks = create_agent_hooks_middleware(
{"secret-egress": SecretEgressGuard()},
mode="evaluate_only",
record_sink=records.append,
)
In diesem Modus werden Interceptors ausgeführt, und Datensätze enthalten ihre Urteile, es wird jedoch keine Aktion blockiert oder transformiert. Beschreiben Sie eine evaluate_only-Bereitstellung nicht als verbindliche Governance.
Kompositionsregeln
Platzieren Sie das Bündel zuerst in der Middlewareliste des Agents, sodass es die äußerste Erzwingungsgrenze bildet:
agent = Agent(
client=client,
middleware=[
create_agent_hooks_middleware([SecretEgressGuard()]),
application_middleware,
],
)
Folgen Sie diesen Regeln:
- Installieren Sie genau ein Agent Hooks Bundle pro Agent. Gestapelte Bündel werden abgelehnt.
- Halten Sie das Bündel intakt. Die Middleware für Agent, Chat und Funktionen kann nicht separat installiert werden.
- Installieren Sie das Bundle auf
Agent, nicht direkt auf einem Chatclient oder über einen Kontextanbieter. - Middleware, die vor dem Bundle platziert ist, befindet sich außerhalb der Durchsetzungsgrenze. Behandeln Sie die äußere Position als äußeres Vertrauen.
- Geben Sie jedem geschachtelten Agent ein eigenes Bundle, wenn dessen internes Modell und die Toolaktivität ebenfalls abgefangen werden müssen.
Aktuelle Einschränkungen
- Python nur: Agent-Hooks sind noch nicht in den .NET oder Go SDKs implementiert.
- Experimentelle API: Factory-Signaturen und Verhalten können sich vor der allgemeinen Verfügbarkeit ändern.
- Gepuffertes Streaming: Updates werden nicht Token für Token freigegeben, da die Ausgabe vor einem Fail-Closed-Urteil vollständig sein muss.
-
Gehostete Tools: Tools, die von einem Modellanbieter ausgeführt werden, laufen nicht über die Schnittstelle für Funktionsaufrufe des Agent Frameworks. Ihre Aufrufe und Ausgaben werden in
post_model_callangezeigt, aberpre_tool_callundpost_tool_callkönnen die serverseitige Ausführung des Anbieters nicht blockieren. - Kooperative Grenze: Agent Hooks führt Interceptors nicht in einer Sandbox aus und schützt nicht vor einem feindlichen Host. Codepfade, die die geschützte Agentpipeline umgehen, sind nicht abgedeckt.
- Die Verfügbarkeit von Interceptor wirkt sich auf die Verfügbarkeit des Agents aus: Im Erzwingungsmodus blockiert ein Interceptor-Fehler oder Timeout die überwachte Aktion standardmäßig.
Informationen zum Produktionsrollout, zu Fehlerursachen und zur Alarmierung finden Sie im Operations-Runbook für Agent Hooks.
Agent Hooks ist für Go noch nicht verfügbar. Verwenden Sie Agent-Middleware, Tool-Freigabe und Agentensicherheit, um Go-Agenten Laufzeitkontrollen hinzuzufügen.