Anwendungsteil 9. Modell-Routing und Token-Budget
Status: Empfehlung. Ein günstiges Modell für Routineaufgaben und ein teures Modell für kritische Reviews zu trennen, ist eine bewährte Praxis. Konkrete Schwellenwerte, die Failover-Formel und der Budgetverwalter als eigenständiger Dienst sind Grenzbereich: Qwen Code verwaltet das Budget nicht selbst, die Umsetzung hängt von der Infrastruktur ab.
Für den Lerndurchlauf reicht es aus, den Ausfall von local-coder in examples/budget-keeper/ durchzuspielen und zu prüfen, dass nicht die gesamte Warteschlange in die teure Stufe wandert. Ein separater Budgetverwalter und die Integration mit Anbietern gehören zum vollständigen Produktions-Track.
In der Lehr-Version von AgentClinic haben wir in Teil 4 des ersten Bandes ein Modell ausgewählt und den Prozess unabhängig davon gehalten (Teil 15). In der Produktion reicht ein einzelnes Modell nicht aus. Das teure Modell darf nicht spontan die gesamte Incident-Warteschlange aufsaugen. Das günstige Modell darf nicht stillschweigend bei strittigen Fällen degradieren. Hier kommt eine Dimension hinzu, die es im Lehrprojekt nicht gab: die Verwaltung der Modellmischung nach Phasen der Pipeline. Das Routing fügt sich bequem in einen benutzerdefinierten Befehl oder Hook ein – Techniken aus Teil 14. Eigener Prozess über Qwen-Code-Skills.
Vor dem Lesen
- Anknüpfung aus dem ersten Band: Teil 15 verlangt Austauschbarkeit des Agenten, Teil 14 zeigt projektspezifische Skills und Hooks.
- Lokaler Lernfall:
autoscale_200pct, weil der Ausfall der günstigen Stufe eine beobachtbare Budgetsimulation liefert. - Spur für
capstone/: ein Risiko fürhigh_memory_usage: was passiert beim Ausfall vonlocal-coder, wie viele Aufgaben werden infrontier-reviewerzugelassen, welchertoken_healthblockiert die Umschaltung.
- Hauptbegriffe des ersten Durchgangs: Stufe (Tier) und
token_health. Budgetverwalter (budget keeper),failover_to_frontier,manual_queue_after_120s– nachschlagbar. - Was zurückzustellen ist: Anbieterintegration, separater Budget-Keeper-Dienst und regelmäßige Drills.
Ziel
Das Ziel des Kapitels ist es, das tägliche Token-Budget (im Beispiel 10M) von einem statischen Limit in eine steuerbare Routing-Tabelle der SDD-Pipeline zu verwandeln. Das ist Stufen-Budgetierung (tier-budgeting): die Verteilung von Tokens zwischen Modellebenen nach Arbeitsphasen. Das günstige Modell (local-coder) übernimmt Routineaufgaben. Das teure Modell (frontier-reviewer) wird nur für kritische Reviews und strittige Entscheidungen eingeschaltet.
Die Zahl 10M ist so gewählt, dass sie einen Strom von etwa 200 Incidents pro Tag bei durchschnittlichen Phasenkosten von rund 50K Tokens abdeckt. Für größere Ströme skalieren Sie das Budget proportional, für kleinere verringern Sie es, wobei Sie die Proportionen zwischen den Phasen beibehalten. Die Aufteilung 9M / 1M zwischen den Stufen spiegelt eine Beobachtung wider: Im ruhigen Modus entfallen rund 10% des Gesamtbudgets auf strittige Reviews. Wenn Ihr Projekt häufiger komplexe Aufgaben stellt, erhöhen Sie den Anteil der oberen Stufe auf 15–20%.
Nach dem Abschnitt können Sie eine Token-Verteilung über die Phasen des Incident-Managements aufbauen, SLA-Schwellen für jede Stufe festlegen, das Systemverhalten beim Ausfall des günstigen Modells prüfen und nachweisen, dass die Einsparungen MTTR (Mean Time To Repair), die Qualität der Eskalationen und die Belastbarkeit der Post-Analyse nicht zerstören. local-coder und frontier-reviewer sind Rollen in Ihrer Infrastruktur, keine Modellnamen: In einem Projekt können es verschiedene Modelle desselben Anbieters sein, in einem anderen ein lokales und ein Cloud-Modell.
Grundniveau: Modellauswahltabelle nach Aufgabe
Bevor wir zur Stufung nach Phasen, Risiko und Warteschlange übergehen (die den Rest des Kapitels beschreibt), ist es sinnvoll, die Ausgangsheuristik für die Modellauswahl festzuhalten. Sie arbeitet nicht mit den Modellnamen eines bestimmten Anbieters, sondern mit Klassen nach Leistung und Kosten: leicht, mittel und schwer. In verschiedenen Projekten entsprechen diesen Klassen unterschiedliche Modelle – wichtig ist nicht die Marke, sondern das Verhältnis „teuer/klug".
| Modellklasse | Wann einsetzen |
|---|---|
| Leicht | Erkundung und Dateisuche, einfache Ein-Datei-Änderungen, Dokumentationserstellung |
| Mittel | Implementierung über mehrere Dateien, Review von Pull-Requests – Standardmodell für ~90% der Codieraufgaben |
| Schwer | komplexe Architektur, Sicherheitsanalyse, Debugging komplexer Bugs |
Halten Sie die mittlere Klasse als Standardwert: Sie deckt die meisten Codieraufgaben ab. Verwenden Sie die leichte Klasse für günstige Routine, wo Fehler leicht erkannt und zurückgerollt werden können. Schalten Sie die schwere Klasse nicht gewohnheitsmäßig ein, sondern nach folgender Upgrade-Regel:
- der erste Versuch in der mittleren Klasse ist gescheitert;
- die Aufgabe berührt fünf oder mehr Dateien;
- eine Architekturentscheidung wird getroffen;
- der Code ist sicherheitskritisch.
Diese Tabelle ist die Grundstufe derselben Logik, die im weiteren Verlauf des Kapitels ausgeführt wird. Der Zusammenhang ist direkt: local-coder entspricht der leichten/mittleren Klasse im Routine-Strom, frontier-reviewer der schweren Klasse bei strittigen und hochriskanten Entscheidungen. Der Unterschied besteht darin, dass die Basistabelle das Modell nach dem Typ einer einzelnen Aufgabe auswählt, während die Stufung (tier-budgeting) drei Dimensionen hinzufügt, die in der Basisheuristik fehlen: Risiko und Rückrollbarkeit der Entscheidung, Warteschlangendruck und SDD-Pipeline-Phase mit eigenem Token-Budget. Der Entwicklungspfad ist also: „Grundniveau der Auswahl nach Aufgabe → Stufung nach Risiko, Warteschlange und Phase". Die Upgrade-Regel auf die schwere Klasse verschwindet dabei nicht – sie wird zu einer der Bedingungen für die Eskalation von local-coder zu frontier-reviewer.
Minimales Lernszenario
Lernfall
Produktions-Incident autoscale_200pct für die MVP-Phase appointments-api aus book/part-12-mvp.md. Morgens ist die lokale Stufe 45 Minuten lang nicht verfügbar (11:00–11:45), 20 Incidents landen in der Warteschlange, das manuelle Timeout beträgt 120 Sekunden. Das Ziel des Lerndurchlaufs ist es, sicherzustellen, dass die Failover-Umschaltung nur Hochrisikoaufgaben in die obere Stufe lässt, nicht die gesamte Warteschlange, und dass token_health_min über der sicheren Schwelle bleibt.
Vorbereitung
book2/examples/budget-keeper/specs/budget_network.yaml– Beschreibung des 10M-Token-Plans.book2/examples/budget-keeper/specs/budget_network_5m.yaml– fertige Kalibriervariante für 5M Tokens mit denselben Proportionen.book2/examples/budget-keeper/scenarios/fail_local_45m.jsonundfail_local_15m.json– zwei Ausfallszenarien.book2/examples/budget-keeper/outputs/budget_plan.example.json,outputs/fail_result.example.json– Referenzen für den Vergleich.book2/examples/budget-keeper/scripts/compile.py,simulate.py,inspect.py.
Schritte
cd book2/examples/budget-keeper. Erwartung: Sie befinden sich im Beispielverzeichnis, keine zusätzlichen Abhängigkeiten.
python3 scripts/compile.py --budget-spec specs/budget_network.yaml --out out/budget_plan.json. *Erwartung: inout/budget_plan.jsonist das Felddaily_budget_tokens: 10000000, die Summe der local-Stufe beträgt 9 000 000, frontier 1 000 000 (90/10).*- Vergleichen Sie
out/budget_plan.jsonmitoutputs/budget_plan.example.jsonüberdiff. Erwartung: keine Abweichungen oder Abweichungen nur in Kommentaren. python3 scripts/simulate.py --plan out/budget_plan.json --scenario scenarios/fail_local_45m.json --out out/fail_result.json. *Erwartung:failover_to_frontier == 5,degraded_queue == 15,token_health_min >= 0.5.*python3 scripts/inspect.py --result out/fail_result.json --query "failover_to_frontier==5 && degraded_queue==15 && manual_queue_after_120s==15 && token_health_min>=0.5". Erwartung: Rückgabecode 0, alle vier Bedingungen sind gleichzeitig erfüllt.
Schlecht: eine Metrik nach der anderen prüfen – in frontier sind 5 Aufgaben gelandet, der Rest ist „wohl ok", token_health wurde vergessen. Gut: ein inspect-Lauf mit vier Bedingungen in && – Scheitern auch nur einer Metrik bricht den Lauf.
- Kurzer Ausfall.
python3 scripts/simulate.py --plan out/budget_plan.json --scenario scenarios/fail_local_15m.json --out out/fail_15m_result.json && python3 scripts/inspect.py --result out/fail_15m_result.json --query "token_health_min>=0.7". *Erwartung: Rückgabecode 0,token_health_min >= 0.7(ein kurzer Ausfall verbrennt frontier weniger aggressiv).* - Halten Sie den Lauf als kurze Budget-Aussage fest:
local-coderist nicht verfügbar, die obere Stufe erhält nur 5 Aufgaben, der Rest geht in degraded/manual,token_health_minbleibt über der Schwelle. *Erwartung: Bei der nächsten Regression bezüglichtoken_healthwird nicht „grün gegen alte Baseline" verglichen, sondern gegen beide Simulationen.*
Wenn Qwen Code installiert ist und Sie eine Erklärung für das Review benötigen, führen Sie einen optionalen Zusatzschritt aus:
qwen -p "Lies @out/fail_result.json und @out/fail_15m_result.json. Erkläre, warum ein 45-Minuten-Ausfall token_health stärker senkt als ein 15-Minuten-Ausfall. Dateien nicht ändern." --approval-mode plan
Eine solche Ausgabe ist als Kommentar nützlich, ersetzt aber nicht inspect.py und gilt nicht als runnable-Tatsache.
Kontrolltatsache
Die vier Bedingungen aus Schritt 5 sind gleichzeitig erfüllt. token_health_min fällt bei einem 45-Minuten-Ausfall nicht unter 0,5 und bei einem 15-Minuten-Ausfall nicht unter 0,7. Ohne beide Simulationen gilt das Szenario als unvollständig: Ein einzelner Punkt zeigt die Sensitivität des Budgets gegenüber der Ausfalldauer nicht.
Wie gelangt dies in capstone/
Übertragen Sie in capstone/budget-note.md nicht die Tabelle des gesamten Budgets, sondern ein Risiko und eine Begrenzung: was passiert beim Ausfall von local-coder, wie viele Aufgaben gehen in frontier-reviewer, welche token_health-Schwelle blockiert die weitere Umschaltung. Wenn der Hauptbewertungsfall high_memory_usage ist, notieren Sie diesen Lauf als Budgetrisiko für denselben Kreis: nicht den gesamten autoscale_200pct, sondern das Prinzip „die teure Stufe übernimmt nicht die gesamte Warteschlange bei Ausfall der günstigen". Das vollständige budget_plan.json wird nur im vollen Track benötigt.
Mindestfragment:
risk: "local-coder nicht verfügbar 45m"
effect: "5 Aufgaben gehen in frontier-reviewer, 15 bleiben degraded/manual"
simulated_floor: "token_health_min == 0.5 (Einbruch bei 45m)"
alert_threshold: "token_health_min < 0.60 (Wächter aus der Anti-Goodhart-Tabelle)"
decision: "die gesamte Warteschlange nicht auf die teure Stufe umschalten"
Zwei verschiedene Schwellen dürfen nicht verwechselt werden. 0.5 ist der beobachtete Boden der Simulation; 0.60 ist die Linie, unterhalb derer der Wächter die automatische Umschaltung in der Produktion blockiert. Das Lernszenario zeigt, dass ein 45-Minuten-Ausfall den Wächter durchbricht und daher eine manuelle Entscheidung erfordert.
Reviewbare Spur
Das Verzeichnis out/ ist ein lokales Simulationsergebnis und darf nicht in das Repository gelangen. Für den Lerndurchlauf genügt eine Zeile in capstone/budget-note.md mit Risiko, Effekt, Guard-Schwelle und Entscheidung.
In Ihrem eigenen Produktions-Repository können Sie zusätzlich einen kurzen Bericht über den Drill-Lauf speichern: Links auf die 45m- und 15m-Szenarien, die Invariante token_health_min und die Entscheidung, die gesamte Warteschlange nicht auf die teure Stufe umzuschalten. Ein solcher Bericht ist nur nützlich, wenn ihn ein Reviewer oder die CI liest; der Commit selbst ist keine SDD-Tatsache.
Schlüsselideen
Modell-Routing beginnt mit der Aufteilung des Incidents in Phasen: triage (Erstaufnahme), Klassifizierung, Diagnose, Plan, Behebung, Post-Analyse. Für jede Phase legen Sie drei Parameter fest: welches Modell sie bedient, welche erwarteten Kosten in Tokens anfallen und bei welchem Risiko eine Eskalation auf die obere Stufe erfolgt.
Triage und Klassifizierung sind ein dichter, schablonenhafter Strom, der empfindlich auf Latenz reagiert. Deshalb übernimmt local-coder ihn als Hauptroutine-Konsument: normalisiert Benachrichtigungen schnell, gruppiert ähnliche Symptome, extrahiert Dienst, Severity, letzte Ereignisse und den anfänglichen Blast Radius (Schadensbereich).
frontier-reviewer belegt die obere Ebene des Netzes für strittige Diagnosen, konfliktierende Pläne, kritische Behebungen und Post-Mortems. Dies sind Fälle, in denen ein Fehler mehr kosten kann als der gesamte Modellaufruf.
Ziehen Sie die Grenze zwischen den Stufen nicht nach dem Prestige des Modells, sondern nach der Rückrollbarkeit der Entscheidung. Wenn die Aktion leicht zurückzurollen und lokal validierbar ist, bleibt sie im günstigen Kreis. Wenn der Rollback teuer ist oder die Folgen mehrere Dienste betreffen, ist der teure Kreis nötig.
flowchart TD IN[Incident-Strom] S[SDD-Phase S Erfassung und Normalisierung des Signals] D1[SDD-Phase D1 Anomalieerkennung] D2[SDD-Phase D2 Diagnose und Bewertung] Q[Länge der Verarbeitungswarteschlange] R[Risikoniveau] B[Token-Budget als Energie] P[Stromverteiler] A[local-coder Grundebene] G[frontier-reviewer obere Ebene] O[Incident-Lösung und Feedback] IN --> S --> D1 --> D2 --> O D1 --> Q D2 --> R Q --> P R --> P B --> P P -->|stabiler Modus| A P -->|Warteschlangen- und Risikowachstum| G A --> O G --> O A -->|Eskalation eines komplexen Falls| G O -->|Korrektur der Limits und Warteschlangen| B
Das obige Diagramm zeigt nur die Eingangs- und Entscheidungsphasen des SDD-Zyklus (Signalerfassung, Erkennung, Diagnose); der vollständige Incident-Zyklus wird durch die Phasen plan, remediation, postmortem fortgesetzt, die eigene SLAs und Kontingente haben – sie erscheinen weiter unten in YAML. Die drei abstrakten Phasen des Diagramms (S, D1, D2) entfalten sich also zu sechs konkreten Kontingenten (triage, classification, diagnosis, plan, remediation, postmortem) plus control_reserve als Puffer.
Bauen Sie die Token-Kontingente nach der Belastungsform auf, nicht nur nach der gewünschten Einsparung. Für 10M Tokens pro Tag kann eine Basisverteilung 9M für local-coder und 1M für frontier-reviewer festlegen. Die günstige Stufe deckt Triage, Klassifizierung, grobe Diagnose und vorläufigen Plan ab. Die teure Stufe erhält eine Reserve für Validierung, strittige Behebungsmaßnahmen und Post-Analyse.
Legen Sie SLA-Schwellen für jede Phase separat fest. Beispiel: Triage muss in Zehn-Sekunden-Bereichen bleiben, Diagnose darf mehr Kontext verbrauchen, und das Post-Mortem darf einen längeren Durchlauf für die Vollständigkeit der Beweiskette zulassen.
Machen Sie die Reserve nicht zu einem „Rest für alles Mögliche". Die Reserve ist eine Sicherungsschicht, die nur bei wachsendem Risiko, wachsender Warteschlange oder wachsender Unsicherheit aktiviert wird.
Vorlage für die Projektdatei: .specify/memory/budget_network.yaml.
daily_budget_tokens: 10000000
phases:
triage:
local-coder: 3000000
frontier-reviewer: 120000
sla_p95: "30s"
classification:
local-coder: 2000000
frontier-reviewer: 140000
sla_p95: "45s"
diagnosis:
local-coder: 1500000
frontier-reviewer: 180000
sla_p95: "90s"
plan:
local-coder: 800000
frontier-reviewer: 120000
sla_p95: "120s"
remediation:
local-coder: 700000
frontier-reviewer: 200000
sla_p95: "180s"
postmortem:
local-coder: 300000
frontier-reviewer: 240000
sla_p95: "10m"
control_reserve:
local-coder: 700000
frontier-reviewer: 0
In Ihrem Projekt werden dieselben Schritte als tools/budget_keeper.py compile|assert|simulate|inspect auf Basis der Anbieter- und CI-Integration umgesetzt. Im Lehrbuch wird ein runnable-Analogon gestartet:
> [runnable] – ein lauffähiges Beispiel für einen Budgetverwalter liegt in [examples/budget-keeper/](examples/budget-keeper/) (siehe [examples/budget-keeper/README.md](examples/budget-keeper/README.md)): dort ein Muster budget_network.yaml, Skripte compile.py, simulate.py, inspect.py und Failover-Szenarien.
cd book2/examples/budget-keeper
python3 scripts/compile.py \
--budget-spec specs/budget_network.yaml \
--out out/budget_plan.json
Modellieren Sie Ausfallkaskaden als ranggestaffeltes Failover, nicht als einfachen Ersatz eines Modells durch ein anderes. Failover ist hier der Plan zur Lastumschaltung bei Ausfall einer Stufe. Betrachten wir den Unterschied der Ansätze.
Schlecht: > Beim Ausfall von local-coder geht der gesamte Verkehr zu frontier-reviewer.
Problem: Die teure Stufe frisst das Tageskontingent in Minuten auf und kann echte P0/P1 nicht mehr bedienen, wenn sie eintreffen.
Gut:
> Beim Ausfall von local-coder gehen in frontier-reviewer nur Aufgaben mit severity in [P0, P1] und age > 90s, die übrigen in die Degradationswarteschlange (degraded queue).
Wenn local-coder ausfällt, leiten Sie den gesamten Eingangsstrom nicht automatisch an frontier-reviewer weiter. Sonst erschöpft die teure Stufe schnell ihr Kontingent und verliert die Fähigkeit, tatsächlich kritische Fälle zu bedienen.
Stattdessen berechnet der Budgetverwalter (budget-keeper) jede Minute mehrere Parameter: spent[p] und queue[p] (verbraucht und Warteschlangenlänge in Phase p), quota[p] (verbleibendes Kontingent), das Alter des Incidents, den Blast Radius und die Konfidenzlücke des Modells (confidence-gap). Auf dieser Grundlage wählt er nur die Aufgaben aus, bei denen die Verzögerung gefährlicher ist als der Verbrauch. Ein solch ranggestaffeltes Failover verändert die Eskalationszeit: Ein Teil der Incidents geht sofort zu frontier-reviewer, ein Teil bleibt im Degradationsmodus, und ein Teil wird nach dem festgelegten Timeout in den manuellen Kanal überführt.
Der Notfallmodus, der „Rote-Knopf" (red button), ist der Schalter in den geschützten Modus. Die bildliche Bezeichnung ist zulässig, aber in den Artefakten halten Sie die konkreten Bedingungen des Notfallmodus fest. Er ist als eigener Steuerungsmodus nötig, weil das automatische Failover selbst zur Quelle eines Notfalls werden kann. Die Auslösebedingungen sind formal: zwei aufeinanderfolgende Fenster mit steigendem Risiko token_health (Gesamtkennzahl für die Gesundheit des Token-Budgets), Warteschlange über dem Limit, SLA-Überschreitung bei kritischen Severities oder Ausfall des lokalen Endpunkts, der local-coder bedient.
Nach dem Auslösen begrenzt das System die neue Warteschlange, verbietet Massen-Automatik-Behebungen, behält frontier-reviewer für P0/P1 vor und überführt die übrigen Entscheidungen in den manuellen oder quasi-manuellen Modus. Der manuelle Modus ist kein Rückfall ins Chaos. Er soll dasselbe Dateiprotokoll, dieselbe Beweiskette und dieselben PostToolUse-Prüfungen erben, damit nach der Stabilisierung die Gründe jeder Entscheidung rekonstruiert werden können.
Die Anti-Goodhart-Logik in validation.md schließt das Hauptrisiko der Budgetoptimierung: die Verbesserung der Berichtsmetriken auf Kosten einer versteckten Verschlechterung des tatsächlichen Incident-Managements. Die Anti-Goodhart-Regel ist das Verbot, ein Release als erfolgreich zu werten, wenn eine Metrik auf Kosten der Degradation anderer gewachsen ist.
Wenn Sie nur MTTR kontrollieren, kann das System komplexe Incidents schneller als unkritisch schließen, den Eskalationsanteil senken oder unbequeme P0 in manuelle Kanäle ohne vollständiges Post-Mortem verdrängen. Validieren Sie MTTR daher zusammen mit vier Wachmetriken und einer Aktivierungsbedingung der Prüfung. Es ist praktisch, ihre Rolle in einer einzigen Tabelle zu führen.
| Metrik | Was sie misst | Was sie blockiert |
|---|---|---|
escalation_share | Anteil der Eskalationen am Gesamtstrom | Aktivierungsbedingung der Prüfung – Abfall unter das historische Korridor gleichzeitig mit schneller MTTR |
silent_p0 | Anteil geschlossener P0 ohne Eskalation | Anstieg über 2% |
unresolved_manual_ratio | Anteil ungeschlossener manueller Aufgaben | Anstieg über 5% |
postmortem_gap | Lücken in der Post-Analyse | Lücken über 10% |
token_health_min | Mindestniveau der Budgetgesundheit | Abfall unter 0,6 |
Werten Sie eine MTTR-Verbesserung als ungültig, wenn auch nur eine Wachmetrik ihre Grenze überschritten hat. Genau dafür dient die gepaarte Prüfung: Eine schöne Berichtskennzahl darf nicht die Degradation der Belastbarkeit, stille P0-Ausfälle oder den Bruch der Beweiskette verdecken.
Fragment für validation.md mit den Regeln des Budget-Gateways.
checks:
- id: anti_goodhart_budget
if:
all:
- mttr_p95 < "5m"
- escalation_ratio < 0.08
then:
fail_if:
- silent_p0 > 0.02
- unresolved_manual_ratio > 0.05
- postmortem_gap > 0.10
- token_health_min < 0.60
- id: ecology_warn
if:
any:
- token_health_trend_5m < -0.12
- queue_pressure > 0.80
- degraded_mode_duration > "120s"
then:
require:
- red_button_review == true
- manual_channel_open == true
- frontier_reserved_for_p0_p1 == true
In Ihrem Projekt wird diese Prüfung als python3 tools/validation_runner.py run --spec validation.md --out .specify/artifacts/validation_health.json mit anschließender jq-Prüfung von anti_goodhart_budget und ecology_warn umgesetzt. Ein nahes lauffähiges Analogon der Anti-Goodhart-Prüfungen selbst ist examples/goodhart-validator/scripts/run_validation.py (siehe Kapitel 10).
Voller Track: Schwellenwertkalibrierung
Die Tabelle „Niedrig / Standard / Hoch" für die Budgetgröße, die local/frontier-Proportionen und manual_timeout_sec, die Übung mit der komprimierten 5M-Variante und Signale für die Überarbeitung – in Anhang D, Abschnitt D.3. Beim ersten Durchlauf genügen zwei Ausfallsimulationen und eine Zeile token_health in budget-note.md.
Beispiele und Anwendung
Die praktische Simulation von Szenario B prüft, dass der Ausfall von local-coder frontier-reviewer nicht zur Notreserve für die gesamte Warteschlange macht. Um 11:00 ist der lokale Endpunkt des günstigen Modells 45 Minuten lang nicht verfügbar. Die Warteschlange enthält 20 Incidents. Das manuelle Timeout beträgt 120 Sekunden.
Die Richtlinie wählt drei Richtungen: 5 Aufgaben mit dem größten Blast Radius und dem höchsten Alter gehen zu frontier-reviewer, 15 Aufgaben bleiben in der Degradationswarteschlange, nach zwei Minuten öffnet sich der manuelle Kanal. Die Prüfung gilt nicht als erfolgreich, weil alle Aufgaben automatisch verarbeitet wurden. Der Erfolg liegt anderswo: Das System hat die teure Stufe bewahrt, die Warteschlange begrenzt und ein Absinken von token_health_min unter die sichere Schwelle verhindert.
In Ihrem Projekt wird dieses Szenario als tools/budget_keeper.py simulate ... --failure "11:00,local-coder,down,45m" --queue 20 --manual-timeout-sec 120 mit anschließendem inspect nach der Bedingung failover_to_frontier==5 && degraded_queue==15 && manual_queue_after_120s==15 && token_health_min>=0.5 gestartet. Das lauffähige Analogon ist dasselbe:
> [runnable] – Szenario examples/budget-keeper/scenarios/fail_local_45m.json.
cd book2/examples/budget-keeper
python3 scripts/simulate.py \
--plan out/budget_plan.json \
--scenario scenarios/fail_local_45m.json \
--out out/fail_result.json
python3 scripts/inspect.py \
--result out/fail_result.json \
--query "failover_to_frontier==5 && degraded_queue==15 && manual_queue_after_120s==15 && token_health_min>=0.5"
Führen Sie den Rollback nach der Stabilisierung stufenweise durch: Sonst erzeugt die Wiederherstellung der günstigen Stufe eine zweite Kaskade. Geben Sie zunächst 30% des Kontingents von local-coder und nur für Triage/Classification frei (diese Phasen lassen sich leichter anhand formaler Merkmale prüfen und entlasten den Eingangsstrom schneller); weitere 30% für Diagnosis/Plan erst nach drei stabilen Fenstern von token_health, ohne Anstieg von silent_p0_ratio und nach Normalisierung der Warteschlange; die vollständige Rückgabe erlauben Sie erst nach Audit der PostToolUse. Grund: Eine vorzeitige Aufhebung des manuellen Modus kann Fehler verbergen, die während der Degradation angefallen sind.
Im Betrieb lässt sich dieses Modell als täglicher Budget-Drill prüfen. Das Team nimmt den gestrigen Benachrichtigungsstrom, spielt ihn durch die aktuelle budget_network.yaml und schaltet local-coder künstlich für 15, 30 und 45 Minuten ab. Dann werden vier Kennzahlen verglichen: MTTR, Eskalationsanteil, Volumen der manuellen Warteschlange und das minimale token_health.
Signale für die Analyse:
- wenn bei einem kurzen Ausfall
frontier-reviewerbeginnt, unkritische Aufgaben zu bedienen – das Failover ist zu breit; - wenn der manuelle Kanal schon bei mäßiger Warteschlange öffnet – die SLA-Schwellen sind zu nervös.
Ziel des Laufs ist es, ein Profil zu finden, in dem die Degradation vorhersagbar ist, nicht unsichtbar bis zur Erschöpfung des Kontingents.
Zusammenfassung
Das Token-Budget wird erst dann zu einer steuerbaren Ressource, wenn fünf Elemente in einen einzigen Steuerkreis verbunden sind: SDD-Phasen, Modell-Stufung (model tiering), SLA-Schwellen, Failover und Validierung. In diesem Kreis liefert local-coder den Durchsatz für Massenroutine; frontier-reviewer schützt strittige und hochriskante Entscheidungen; der Notfallmodus begrenzt die Automatisierung bei steigendem Risiko; validation.md verhindert, dass MTTR auf Kosten versteckter P0 und zerstörter Post-Analyse verbessert wird. Ein solches Schema zeigt nicht nur den aktuellen Verbrauch, sondern auch die Reihenfolge der Degradation: welche Phasen zuerst hungern, welche Aufgaben in die teure Stufe wechseln müssen und wann der manuelle Modus sicherer ist als die Fortsetzung der Automatisierung. Im Folgenden geht dieser Kreis zu Goodhart-Metriken und gepaarten Wachmetriken über.
Artefakte und Fertigkeitskriterien
| Artefakt | Bereit, wenn |
|---|---|
Lokaler Lauf book2/examples/budget-keeper | die Summe der Kontingente entspricht 10M Tokens und der vorgegebenen local/frontier-Aufteilung |
| out/budget_plan.json, out/fail_result.json, out/fail_15m_result.json | das 45-Minuten-Szenario liefert failover_to_frontier==5, degraded_queue==15, manual_queue_after_120s==15, token_health_min>=0.5; das 15-Minuten-Szenario erhält token_health_min>=0.7; out/ wird nicht committet | | Eintrag in precedents.md oder capstone/budget-note.md | erklärt, was beim Ausfall von local-coder passiert, welche Aufgaben zu frontier-reviewer gehen und welche Schwelle von token_health_min das Budget schützt |
Der volle Track ergänzt .specify/memory/budget_network.yaml mit Phasen und SLAs, budget_plan.json nach compile, fail_scenario_B.json, validation.md mit dem Anti-Goodhart-Budget-Gateway und validation_health.json. Betrachten Sie ihn als fertig, wenn der Notfallmodus frontier für P0/P1 bewahrt und den manuellen Kanal öffnet, das Anti-Goodhart-Gateway Einsparungen auf Kosten von silent_p0 oder Audit-Bruch blockiert und die Budgetsimulation in den regelmäßigen Drill oder die CI eingebunden ist.
Praxis
cd book2/examples/budget-keeper && python3 scripts/compile.py --budget-spec specs/budget_network.yaml --out out/budget_plan.json– *Erwartung:daily_budget_tokens == 10_000_000, Summe der local-Stufe 9M, frontier 1M (90/10).*
python3 scripts/simulate.py --plan out/budget_plan.json --scenario scenarios/fail_local_45m.json --out out/fail_result.json && python3 scripts/inspect.py --result out/fail_result.json --query "failover_to_frontier==5 && degraded_queue==15 && manual_queue_after_120s==15 && token_health_min>=0.5"– Erwartung: Code 0, vier Bedingungen gleichzeitig erfüllt.- Übertragen Sie in
capstone/budget-note.mdfünf Zeilen:risk,effect,simulated_floor,alert_threshold,decision. *Erwartung: Format stimmt mit der Vorlage aus dem Abschnitt „Wie gelangt dies incapstone/" überein; das vollständigebudget_plan.jsongelangt nicht incapstone/.*
Kontrollfragen
- Warum darf Failover nicht die gesamte Warteschlange in die teure Stufe lassen?
- Welche Metriken zeigen die Degradation des Budget-Routings an?
- Wann ist der manuelle Modus sicherer als die Fortsetzung der Automatisierung?
- Das lokale Modell fällt in der Spitzenzeit 45 Minuten lang aus. Sie haben 60% des Tagesbudgets, aber MTTR kriecht nach oben. Was schalten Sie um – das Modell, die Routing-Richtlinie oder den Triage-Modus?