Werkzeug-Dispatch — Ausgehende Function-Call-Anfragen
Dieses Dokument beschreibt die Anfrage, die Audact an den eigenen HTTP-Endpunkt des Mandanten sendet, wenn das LLM während eines Anrufs ein benutzerdefiniertes Werkzeug (Function Call) aufruft, das für einen Agenten konfiguriert wurde.
Authentifizierung — X-Signature
Wenn für ein Werkzeug ein Signing-Secret konfiguriert ist, enthält jeder ausgehende Dispatch:
X-Signature: <hex_hmac_sha256_of_raw_request_body>
- Algorithmus: HMAC-SHA256 über die exakten rohen JSON-Body-Bytes, die gesendet
werden. Anders als die Webhook-Signatur (siehe Webhook-Zustellung)
enthält die Werkzeug-Dispatch-Signatur keine Zeitstempel-Komponente — es handelt
sich um einen einfachen HMAC nur über den Body; ein Begleit-Header im Stil von
X-Audact-Timestampist nicht vorhanden. - Wenn für das Werkzeug kein Signing-Secret konfiguriert ist, wird
X-Signaturevollständig weggelassen — konfigurieren Sie ein Secret für das Werkzeug, wenn Sie den Aufrufer verifizieren müssen. - Nicht verwechseln mit
X-Audact-Signature(der Webhook-Zustellungs-Signatur, die einen Zeitstempel enthält und Dual-Key-Rotation unterstützt). Es handelt sich um zwei unabhängige Schemata für zwei unabhängige Oberflächen (Webhooks vs. Werkzeug-Dispatch). - Verifizierung auf Ihrer Seite: Berechnen Sie
hex(hmac_sha256(secret, raw_body))neu und vergleichen Sie das Ergebnis zeitkonstant mit demX-Signature-Header-Wert.
Format des Anfrage-Bodys
Standard (args_only = false):
json
{
"name": "<tool_name>",
"args": { "...": "LLM-supplied arguments, merged with any const fields" },
"call": {
"tenant_id": "<uuid>",
"call_id": "<uuid>",
"turn": 3,
"jurisdiction": "NL",
"direction": "inbound",
"vars": { "...": "current dynamic-variable snapshot" }
}
}call.call_idist immer vorhanden, wenncall-Kontext verfügbar ist — dies ist die Sicherheitsgrenze, auf die eincall_id → tenant_id-Guard Ihres Endpunkts basieren sollte.call.tenant_idist ebenfalls immer zusammen mit diesem Feld vorhanden.call.varsist die aktuelle Map der dynamischen Variablen der Pipeline (Werte, die aus{{varName}}-Substitution und bisher aus Tool-Antwort-Variablen extrahiert wurden) — kein Feld namenscall.metadata. Pro-Anruf-Metadaten sind eine separate Funktion und werden diesem Objekt hinzugefügt, sobald sie verfügbar sind.call.directionist"inbound"oder"outbound".call.turnist die aktuelle Gesprächsrundennummer (Ganzzahl, 1-basiert).
args_only = true: Der {name, args, call}-Wrapper wird vollständig weggelassen
und der Anfrage-Body besteht nur aus args — einem flachen JSON-Objekt ohne Wrapper,
ohne name, ohne call. Dies ist ein bewusstes, explizites boolesches Feld pro Werkzeug
(ToolConfig.ArgsOnly, JSON-Feld args_only), das ein Mandant setzt, wenn sein Endpunkt
einen flachen Body erwartet; es ist kein versteckter Dashboard-Schalter.
Timeout, Wiederholungsversuche und Antwortverarbeitung
- Timeout pro Werkzeug:
ToolConfig.Execution.TimeoutMs; wenn nicht gesetzt (Null), beträgt der Standardwert 120.000 ms (120 s). Der akzeptierte Bereich bei expliziter Angabe ist[1, 300000]ms (max. 5 Minuten). - Wiederholungsversuche: bis zu 3 Versuche insgesamt, mit 500 ms Wartezeit zwischen den Versuchen. Ein abgelaufener Versuch wird niemals wiederholt — Wiederholungen gelten nur für Nicht-Timeout-Fehler (Netzwerkfehler, Nicht-2xx-Antworten). Wiederholungsversuche werden auch sofort abgebrochen, wenn der übergeordnete (In-Call-)Kontext abgebrochen wird.
- Begrenzung des Antwort-Bodys: 15.000 Zeichen; längere Bodies werden abgeschnitten, bevor sie an das LLM weitergegeben werden.
- Extraktion von Antwortvariablen:
ToolConfig.ResponseVars-Dot-Paths werden aus der JSON-Antwort in den dynamischen Variablen-Speicher der Pipeline extrahiert (nur Blattknoten vom Typ string/number/bool; Arrays und Objekte werden nicht extrahiert) und stehen für nachfolgende{{varName}}-Substitutionen und zukünftige Werkzeugaufrufe im selben Anruf zur Verfügung. - Der HTTP-Client des Werkzeugs ist SSRF-geschützt: Adress-Lookups werden vor dem Verbindungsaufbau bei jedem Versuch gegen private, Loopback- und Link-Local-Bereiche validiert.
Beispiel: Verifizierung und Auslesen einer Werkzeug-Dispatch-Anfrage (Pseudocode)
sig := request.header("X-Signature")
if sig != hex(hmac_sha256(secret, raw_body)):
reject()
body := json.parse(raw_body)
call_id := body.call.call_id # always present
tenant_id := body.call.tenant_id # always present
args := body.args # or the whole body if args_only