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 der SQAI runtime, 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 SQAI-Bereitstellung, bevor jede Prüfung bestanden ist.

01Typisierte Anfrage

Eine Anfrage, die die SQAI-Bereitstellung 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

04SQAI runtime

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 SQAI runtime, 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 SQAI-Bereitstellung. Die SQAI 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