Files
ki-engineeering/16-orchestrierung-im-code.md
grok-bot ea82f772ad P1 Welle B: Tippfehler und Term-Align
Tippfehler-Cluster (02–05, 09, 12, 23, 27–28) und Terminologie
(Outcomes 16↔18, Budget 16↔23, prompt_version, Coding-Agent,
fester Workflow). Handoff: Git-Remote, P0/P1A/P1B erledigt,
nächster Slice Faktencheck.
2026-08-02 23:23:17 +02:00

14 KiB
Raw Permalink Blame History

Orchestrierung im Code

Prompt, RAG, Tools, Workflow und optional Fine-Tune stehen (Kapitel 11–15). Im Review wirkt das Feature „fertig“: Demo-Happy-Path, Schema meist grün, ein Tool, ein Modell. In Produktion: Timeout beim Provider, kaputtes JSON nach Model-Update, doppelte Buchung nach Retry, Repair-Schleife ohne Budget, und niemand weiß, ob der Fallback jemals feuerte.

Die Bausteine sind notwendig — ohne Orchestrierung bleiben sie lose Enden. Orchestrierung ist der Control Flow, der probabilistische Knoten einklammert: wann rufen, was validieren, wie oft reparieren, wohin ausweichen, wann abbrechen.

Kern in einem Satz: Thin orchestration im Code — Control Flow, State, Caps, Validate/Repair/Fallback und Telemetrie gehören euch; das Modell füllt Contracts an benannten Stationen, es steuert nicht das System (T5, T6).

Dieses Kapitel bündelt die Bausteine zu einem Harness. Patterns aus Kapitel 07 werden hier implementierbar. Eval-Tiefe → Kapitel 17; Security-Guardrails → Kapitel 19.


Bridge: Klassisches SE → AI Engineering

Klassisches SE Orchestrierung bei LLMs …
Service-Orchestrator / Saga Harness: Reihenfolge, State, Compensation, Caps
Request Validation + DTO Validate vor und nach dem Modell (Schema, Policy)
Retry mit Backoff / Circuit Breaker Retry-Budget + Provider-Failover — nicht blindes Re-Generate
Dead-letter / Fallback-Handler Repair (begrenzt) → Fallback (Template, Regel, Mensch, refuse)
Idempotency-Key Pflicht bei Write-Tools und Retry über Tool-Grenzen
Feature-Flag / Kill-Switch Flag pro Capability + hard stop bei Budget/Policy
Health checks Model/Provider-Latency, error classes, repair rate
Transaction boundaries Side-Effect-Klassen und HITL vor irreversiblen Writes

Die Brücke: ihr orchestriert unsichere Worker (T2). Mehr Magic im Framework ersetzt keine State-Maschine, keine Timeouts und keine harten Validatoren.


Was Orchestrierung ist — und was nicht

Ist Orchestrierung Ist nicht Orchestrierung
Control Flow und State außerhalb des Transcripts 400 Zeilen System-Prompt als „Workflow“
Validate / Repair / Fallback mit Caps „Bitte antworte korrekt“ ohne Parser
Timeouts, Budgets, Kill-Switch unbegrenzter Agent-Loop
Routing zu Model-Tier und Provider immer das stärkste Modell „für Qualität“
Trace-IDs, Versionen, Fehlerklassen Demo-Happy-Path als Architektur

Harness (kanonisch): Software-Schicht ums Modell — Orchestrierung, Policies, Telemetrie. Kein Produktname. Frameworks (LangGraph, Semantic Kernel, eigene Thin Layer, … — Stand August 2026) mappen unterschiedlich; die Verantwortlichkeiten bleiben.

Request
  → Input-Gates (AuthZ, Rate, Guardrails)
  → Context bauen (Slots, Retrieval, Memory)
  → Model call(s) an benannten Knoten
  → Validate Output
       fail → Repair (budget) oder Fallback
  → Side effects nur nach Policy / HITL
  → Response + Telemetrie

Thin Orchestration

Dünn heißt: wenige, lesbare Schritte; Substanz in Schemas, Tool-Contracts, Policies und Eval — nicht in Framework-Spaghetti und nicht in Prompt-Prosa.

Do

  • ein klarer Graph oder Pipeline pro Capability
  • deterministische Schritte im Code, LLM nur wo Spec es braucht
  • Caps: max_model_calls, max_repairs, max_tool_steps, max_cost, wall-clock timeout
  • jeder Knoten: Eingabe-Schema, Ausgabe-Schema, Fehlerklasse

Don’t

  • „der Agent findet den Prozess schon“ ohne Caps (Kapitel 14)
  • Business-Rules nur im Prompt („nie Rabatt > 10 %“) ohne Code-Check
  • Retry = denselben Call 10× ohne Diagnose
  • State nur im Chat-Log

Faustregel: Wenn On-Call den Ablauf nicht in einer Seite skizzieren kann, ist die Orchestrierung zu dick — oder unsichtbar im Modell.


Schichten im Harness (implementierbar)

Anschluss an den Production Stack (Kapitel 07):

Schicht im Code Verantwortung Typische Artefakte
Entry / API AuthN/Z, Rate Limit, Request-Schema Middleware, Feature-Key
Orchestrator Graph, State, Caps, Flags run_capability(ctx)
Adaptation adapters Prompt-Template, RAG, Tool-Bindings versionierte Config
Model access Tier, Pin, Provider-Failover Router, client wrappers
Validators Schema, Business rules, Grounding-Checks pure functions, tests ohne LLM
Effectors Tool-Ausführung, HITL-Queue Contracts (Kapitel 13)
Telemetry Trace, Tokens, Costs, Outcomes spans + redacted payloads

Trennung zahlt sich aus: Validatoren und Tool-Adapter testet ihr ohne Modell. Model Access wechselt ihr hinter einer schmalen Schnittstelle. Orchestrierung bleibt lesbar, wenn Adaptation und Effects nicht in einer 800-Zeilen-Funktion vermischt sind.


Validate → Repair → Fallback

Das Kernmuster für Structured Output und kontrollierte Wirkung (Kapitel 07, Generate-then-Validate; Kapitel 11).

Validate (hart)

Prüfung Beispiel
Schema / Typen JSON Schema, Enums, Pflichtfelder
Business rules Betrag ≤ Limit, Status-Übergang erlaubt
Grounding Claim nur mit Citation / Snippet-ID
Policy keine PII im öffentlichen Reply; Safety-Block
Tool-Args vor Ausführung gegen Contract

Validate ist Code, nicht „Modell, bitte prüfe dich selbst“ als einzige Linie.

Repair (begrenzt)

Bei Validate-Fail: gezielter Repair-Call mit Fehlerdiagnose (maschinenlesbar: welche Felder, welche Regel) — nicht den Original-Prompt nochmal.

  • Cap: typisch 1–2 Repairs, feature-spezifisch
  • gleiches Schema, enger Task: „korrigiere nur X“
  • Telemetrie: repair_count, repair_reason

Repair ist teurer (Latenz + Tokens) und kein Ersatz für schlechte Contracts.

Fallback (explizit)

Wenn Budget erschöpft oder Fehlerklasse „nicht reparierbar“:

Fallback Wann
Template / Regelwerk enge Klassifikation, bekannte Defaults
schwächeres/anderes Modell nur wenn Eval das stützt; sonst Provider-Failover
Mensch (Queue) Gelb/Rot, hohe Wirkung
Refuse / unable ehrlicher als Halluzination
Degraded UX „Entwurf nicht verfügbar“ statt leere 200 mit Müll

Jeder Fallback ist spezifiziert in der Feature-Spec — nicht still im Catch-Block erfunden.

generate → validate
   │ fail
   ├─ repairs left? → repair → validate …
   └─ else → fallback (template | human | refuse | other model*)

Retry, Timeouts, Idempotenz

Was ihr wiederholt

Fehlerklasse Retry? Hinweis
Provider 429 / transient 5xx ja, Backoff + jitter, Cap Circuit breaker pro Provider
Timeout (kein Response) vorsichtig Idempotenz bei bereits ausgelösten Tools
Validate fail Repair, nicht blind Retry desselben
4xx Auth / Policy nein fix config / deny
Tool business error (not_found) meist nein; an Modell als structured error kein Re-Fire des Writes

Retry-Budget und Repair-Budget sind getrennt. Beides multipliziert Kosten und Latenz (T7).

Timeouts

  • wall-clock pro Request und pro Model-/Tool-Call
  • Streaming ändert UX, nicht die Notwendigkeit von Deadlines
  • Agent/Pipeline: Step-Timeout und Gesamt-Timeout (Kapitel 14)

Idempotenz

Retries über Netzwerkgrenzen erzeugen Doppel-Wirkung. Write-Tools: Idempotency-Key, upsert-Semantik, „at-most-once“-Gates vor HITL. Ohne das ist „einfach nochmal“ ein Incident.


Patterns und Trade-offs

Pattern: Capability als Funktion

Eine öffentliche Operation: triage_ticket(input) -> Result. Intern Pipeline; außen ein Contract. Prompts und Modelle sind Implementierungsdetails hinter der Version.

Trade-off: etwas mehr Struktur; klare Ownership und Testbarkeit.

Pattern: Pure validators, impure edges

Schema- und Rule-Checks pure und unit-testbar. I/O (Model, Tools, DB) an den Rändern.

Trade-off: etwas Boilerplate; On-Call und CI werden einfacher.

Pattern: Budget object im State

Budget: {
  max_cost_per_request,   # bzw. max_cost_eur
  max_tokens,             # pro Request / Pfad
  max_steps,              # inkl. max_model_calls / Tool-Steps
  max_repairs,
  deadline_at
}

Felder und Tenant-Tagescaps: Kapitel 23. Jeder Call dekrementiert; bei 0 → Fallback/Abort. Kein implizites „noch ein Versuch“.

Trade-off: Disziplin im Code; schützt p95 und Rechnung.

Pattern: Explicit outcome taxonomy

Outcomes: success, success_degraded, refuse, needs_human, error_provider, error_validation_exhausted, … — für Metrics und UX, nicht nur HTTP 200.

Trade-off: Mapping-Aufwand; messbare Produktion (Kapitel 18).

Pattern: Shadow path für Orchestrierungs-Änderungen

Neue Validate-Regel oder Repair-Logik zuerst loggen (shadow), dann enforce — analog Model-Canary.

Trade-off: doppelte Logik kurzfristig; weniger Big-Bang-Incidents.

Decision Frame: noch ein Repair — oder Fallback?

Signal Tendenz
Schema-Fehler, klare Diagnose 1 Repair
semantisch unsicher / out of scope refuse oder human
transient Provider retry provider, nicht repair content
Write bereits unsicher ausgelöst kein blindes Retry; reconcile
Repair-Rate steigt nach Model-Change Contract/Eval, nicht Cap erhöhen

Trade-off: Framework-Orchestrierung vs. eigene Thin Layer

Framework-Graph Eigene dünne Schicht
schnell sichtbar volle Kontrolle, weniger Magie
Defaults werden Architektur mehr Code ownership
Vendor-Lifecycle passt zu eurem Stack
gut für Exploration oft besser ab festem Production-Graph

Wählt das, was Caps, State und Telemetrie explizit macht — nicht das mit dem beeindruckendsten Diagramm-Generator (T6).


Anti-Patterns

Anti-Pattern Symptom Besser
Prompt as Orchestrator Ablauf nur in Prosa Graph im Code
Infinite Repair validate-fail → ewige Schleife Cap + Fallback
Retry everything 10× gleicher Call Fehlerklassen trennen
Happy-Path only kein Fallback in Spec Outcome-Taxonomy
Chat as State Business-State im Transcript externes State-Objekt
SDK in the Controller UX ruft Provider direkt Model Access + Orchestrator
Silent 200 Müll oder leerer Body refuse / degraded UX
Budget im Bauchgefühl Rechnung überrascht Budget object + Alerts
Idempotenz später Doppel-Refunds Keys vor erstem Write-Tool
Framework = Design niemand kennt den echten Graph eine Seite Architektur-Skizze

Production Notes

Cost. Jeder Repair und Retry ist ein Multiplikator. Misst calls_per_success, repair_rate, €/capability. Caps in der Spec-Envelope (Kapitel 06); Alerts bevor Finance anruft (T7).

Latency. p95 bricht zuerst an sequentiellen Model+Tool-Ketten und an Repair. Parallelisiert nur wo unabhängig; setzt Deadlines; async für lange Pipelines.

Observability. Minimum: Request/Trace-ID, capability, model_id, prompt_version, step, validate/repair counts, outcome, token in/out, cost estimate — redacted (observability-minimum.md). Ohne Outcome-Taxonomy sind Dashboards Kosmetik. Tiefe: Kapitel 22.

Security. Orchestrierung erzwingt Trust Boundaries: untrusted slots, Tool-Allowlist, Output nicht ungeprüft an Shell/SQL/HTML. Kill-Switch und Policy-Gates gehören in den Graphen, nicht „ins Prompt-Update nächste Woche“ (Kapitel 19, T8).

Lifecycle. Orchestrator-Config (Caps, Fallbacks, Flags) versionieren wie Code. Model-Update: Canary auf Task Success und repair_rate / fallback_rate (T9). Named Owner für Capability-Graph und für Prompt/Eval (T10).


Key Takeaways

  • Orchestrierung schlägt Magic (T6): Control Flow, Caps und Fallbacks leben im Code.
  • Thin orchestration: lesbarer Graph; Substanz in Contracts, Validators und Eval.
  • Validate → Repair (cap) → Fallback ist das Standardmuster um probabilistische Knoten.
  • Retry ≠ Repair; Fehlerklassen und Idempotenz trennen.
  • Harness-Schichten trennen Testbarkeit (pure validators) von Model Access und Effects.
  • Jeder Outcome und Fallback ist spezifiziert — Silent Success ist ein Incident-Muster.
  • Bausteine 11–15 werden hier gebündelt; Qualität beweist Kapitel 17.

Praktische nächste Schritte

  1. Zeichne eure wichtigste Capability als Graph (max. eine Seite): Knoten, Caps, Fallback.
  2. Implementiert Validate als pure Funktion mit Unit Tests — ohne LLM.
  3. Setzt max_repairs, wall-clock und cost budget vor dem nächsten Prod-Traffic.
  4. Führt eine Outcome-Taxonomy ein und loggt sie (redacted) pro Request.
  5. Prüft Write-Pfade auf Idempotenz-Keys und HITL-Gates.
  6. Legt fest: was passiert bei Provider-Outage? (Failover, queue, refuse) — und testet den Pfad einmal.
  7. Nächster Baustein-Abschluss: Offline-Eval und CI-Gates in Evaluation und Testing.