So funktioniert es

Das Modell schlägt vor.
SQAI entscheidet.

Ein Agent schreibt weder SQL noch ausführbaren Code. Er formuliert eine typisierte Anfrage — und jede Anfrage durchläuft dieselbe Strecke: Validierung gegen einen versionierten Vertrag, Prüfung gegen Ihre Richtlinie, Ausführung auf einer deterministischen Engine, Rückgabe mit den Hashes, die sie reproduzierbar machen.

Jede Anfrage — ask(), compute() oder ein AI SDK Tool Call — durchläuft dieselbe Strecke. Nichts erreicht die Engine, bevor jede Prüfung bestanden ist.

01Typisierte Anfrage

Eine Anfrage, die die Engine parsen kann. Kein String, dem sie vertrauen muss.

Das Modell gibt ein typisiertes Objekt aus — niemals SQL, niemals Code. Eine Abfrageabsicht ist ein QuerySpec: eine Metrik, die über eine benannte Quelle aggregiert wird. Eine Berechnungsabsicht ist ein ComputationSpec: eine benannte Funktion aus dem Vertrag, mit Argumenten und Bindungen. Eine diskriminierte Union, zwei Formen — und in keiner davon Platz für einen ausführbaren String.

Das ist die gesamte Authoring-Oberfläche. Was die Form nicht ausdrücken kann, kann das Modell nicht anfordern.

QuerySpecAufbau
{
"kind": "query",der Union-Tag — Abfrage oder Berechnung
"version": "1",die Spec-Version, fixiert
"source_name": "sales",eine verbundene Quelle, beim genauen Namen
"metric": "revenue",die zu aggregierende Spalte
"aggregation": "sum",eines von sum · avg · count · min · max
"group_by": "region"optional — Ergebnis nach einem Feld aufteilen
}

ebenfalls optionalfilter · limit · order

die Berechnungsformmodule · function · args · kwargs · bindings · seed?

02Vertragsvalidierung

Ein Vertrag, hash-fixiert. Das Unbekannte wird mit Hinweisen abgewiesen.

Die Spec wird gegen den Capability-Vertrag validiert — eine generierte, hash-fixierte Datei, die jede Operation, ihre genaue Signatur und ihre Determinismus-Flags auflistet. Eine Capability ist nur erreichbar, wenn sie lesend und deterministisch ist oder deterministisch bei gesetztem Seed. Schreibende und nicht-deterministische Operationen werden nicht zur Laufzeit blockiert; sie wurden erst gar nicht in die Oberfläche generiert.

Eine unbekannte Funktion schlägt als unsupported_operation fehl und antwortet mit nearest_matches aus demselben Index — das Modell korrigiert sich selbst, anstatt in eine Schleife zu geraten.

Capability-Vertrag

contract_hashsha256:79f1c5a6c7164e7e9e1750e70a5c03292fa87eb52d8148a740c06695924be9a1

4,778
im Vertrag aufgeführte Operationen
4,574
den SDKs zugänglich, lesend
4,564
vollständig deterministisch
10
seed-pflichtige Simulationen
204
von der Oberfläche ausgeschlossen

Zulässigkeitread_only && (deterministic || deterministic_when_seeded)

bei unbekanntem Namenunsupported_operation + nearest_matches

03Richtlinienprüfung

Ihre Positivliste entscheidet, ob — und wie — es ausgeführt wird.

Die Richtlinie wird beim Konstruieren der Instanz durch createSQAI() festgelegt und prozessintern durchgesetzt, bevor irgendetwas ausgeführt wird — auf der Quelle, auf jeder Metrik, Gruppe, jedem Filter und jeder gebundenen Spalte sowie auf dem Funktionsnamen. Sie kann den Vertrag nur einschränken: Eine Capability außerhalb der zulässigen Oberfläche zu benennen, löst weiterhin unsupported_operation aus.

Die Tool-Eingabe des Modells enthält kein allowed*-Feld. Nichts in der Anfrage kann den Zugriff erweitern — es gibt also nichts, das eine Prompt-Injection ausweiten könnte.

allowedSourcesQuellen, die das Modell benennen darf

  • "sales"

allowedFieldsSpalten, die es lesen darf, je Quelle

  • sales.region
  • sales.revenue
  • sales.order_date

allowedFunctionsder Standard — jede lesende Capability, nicht mehr

  • "all-readonly"

eine Ablehnung ist präzise, zugeordnet, endgültig

  • policy_denied_source
  • policy_denied_field
  • policy_denied_function

source: "sqai" · nicht wiederholbar

04Deterministische Engine

Fixiert vor der Ausführung: float64, ein Thread, eine Runtime.

Zuerst werden Bindungen aufgelöst. Das Modell hat eine Quelle und ein Feld benannt; SQAI zieht die tatsächlichen Werte über das zeilenausgerichtete extractColumns-Primitiv der Engine, Nullwerte paarweise behandelt. SQAI zippt Arrays nie selbst — der gehashte Input ist damit exakt der Input, der ausgeführt wurde.

Erst jetzt erreicht die Anfrage die Engine. Die Runtime ist signiert, versioniert und fixiert: float64-Präzision, ein einzelner Thread. Das erste compute() provisioniert sie einmalig in etwa 110 Sekunden; danach bleibt sie resident — finance.npv misst 0,83–0,93 ms im Warmzustand.

Determinismus-Envelope
runtime_bundle_version0.1.0
runtime_bundle_sha2564d64142e4c1ff63d299cfc8b172fdf97cb59169b545e1e02978e678a632ce6e1
platformdarwin
architecturearm64
precision_modefloat64
thread_count1
seed
input_hash2ea5ede72acd2912fe9e1230cef34afad4c9436bfa8a709bac2da02b478e3212

Mit jedem Ergebnis aufgezeichnet — der Envelope benennt den Geltungsbereich der Garantie, ohne ihn zu überdehnen.

05Antwort + Herkunft

Zwei Hashes. Einer davor, einer danach.

invocation_hash wird vor der Ausführung gestempelt — über Modul, Funktion, Argumente, aufgelöste Bindungen, Seed, Vertrag und Scope. computation_hash wird danach gestempelt: der Invocation-Hash gefaltet mit dem kanonischen Ergebnis. Replay bedeutet: erneut ausführen und Bytes vergleichen.

Beide SDKs teilen einen kanonischen Serializer, sodass dieselbe Berechnung byte-identische Hashes in TypeScript und Python liefert. Abfrageantworten unterliegen derselben Disziplin: ein plan_hash über den kanonisch aufgelösten Plan, ergänzt um den Entscheidungspfad und den genauen Scope, in dem er ausgeführt wurde.

3188.1687606249325finance.npv · an eine Live-Spalte gebunden · 0,83 ms warm

vor der Ausführung gestempelt

invocation_hash

8223a694250fc751fcf8a7777b8e1f524c44ff1f0e7e83451467f554a6123950

Modul · Funktion · Argumente · aufgelöste Bindungen · Seed · Vertrag · Geltungsbereich

gestempelt nach der Ausführung

computation_hash

ff5280ea128113f528dd1e9a28b9bc4a81469075ed7c981c7176fb172d98085d

der Aufruf-Hash, gefaltet mit dem kanonischen Ergebnis

Byteidentisch in TypeScript und Python — ein in einer Sprache berechnetes Ergebnis lässt sich in der anderen wiedergeben und verifizieren.

beide berechnet gegencontract_hash sha256:79f1c5a6…

auf der Query-Ebeneplan_hash f87610d8afeb…decision_path "exact_spec"deterministic_scope "local_registered_source"

06Der Discovery-Loop

Nie raten. Entdecken, trocken laufen lassen, dann ausführen.

Feldnamen und Funktionssignaturen werden entdeckt, nicht halluziniert. Das AI SDK stellt genau drei Tools bereit — und nur eines davon führt aus.

  1. 01listSources()

    Was kann ich anfassen?

    Verbundene Quellen mit exakten Feldnamen, Typen und den erlaubten Operationen je Feld. Führt nie aus.

  2. 02listSources({ capabilitySearch: "npv" })

    Was kann ich berechnen?

    Dasselbe Tool, das den deterministischen Katalog durchsucht — passende Module, exakte Signaturen und ob ein Seed erforderlich ist.

  3. 03explainQuery({ … })

    Wird es laufen?

    Ein Trockenlauf. Gibt den aufgelösten Plan, die Konfidenz und einen vorläufigen invocation_hash zurück — eine Vorschau, kein ausgeführter Hash.

  4. 04queryData({ … })

    Ausführen.

    Das einzige Tool, das ausführt. Gibt das Ergebnis samt vollständiger Herkunft zurück; zu große Ergebnisse bleiben per result_id abrufbar.

Die Tools werfen nie — jedes Ergebnis ist typisiertok · needs_clarification · rejected · error

Die Mechanik, Feld für Feld.

Dokumentation lesen