3.0 KiB
SPEC-lifecycle: Kandidaten, Graduierung, Training
Pakete: knaster.lifecycle, knaster.graduation.
1. Kandidat
id, kind: base_model | adapter | quantization | embedding_model | engine
slot: str # betroffener Slot (bei adapter: Slot, dessen Basis passt)
target: {...} # z. B. {base_model: "qwen3-14b-awq"} oder {cluster: "rechnungen"}
baseline: {pass_rate?} # Messwert der aktuellen Version
state, metrics{}, history[{ts, from, to, note}]
2. Zustände
proposed ──(Freigabe)──▶ building ──report(build_ok)──▶ evaluating
evaluating ──report(eval: pass_rate ≥ baseline − tolerance)──▶ shadow (sonst ▶ rejected)
shadow ──report(shadow: agreement ≥ min_agreement, n ≥ min_n)──▶ canary (sonst ▶ rejected)
canary ──report(canary: pass_rate ≥ baseline − tolerance, n ≥ min_n)──▶ awaiting_promotion (sonst ▶ rejected)
awaiting_promotion ──(Freigabe)──▶ promoted
promoted ──rollback──▶ rolled_back
jeder Zustand ──report(error)──▶ failed
Grenzwerte stehen in config/lifecycle.yaml: tolerance 0,02, min_agreement 0,85, min_n 50, canary_share 0,1.
Die Freigaben laufen über die Policy (create_candidate, promote_candidate). Promote schreibt in den Registry-Laufzeitzustand bzw. in die Adapterliste:
base_model: Slotbase_modelwird umgestellt, alle Adapter der alten Basis werdenretired, und für jeden Cluster mit Adapter entsteht ein Kandidatadapter(Neutraining).adapter: Der neue Adapter wirdactive, der bisher aktive für denselben Cluster und dieselbe Basis wirdretired(bleibt als Rollback-Ziel erhalten).- Rollback stellt den Zustand vor dem Promote wieder her (gespeichert in
history).
Die Jobs selbst (Download, Quantisierung, Training, Eval) laufen extern, als Job-Runner auf gpu-flex. Sie melden ihr Ergebnis per POST /v1/lifecycle/candidates/{id}/report. Der JobRunner im Service stößt den Job an: Im Dry-Run wird nur protokolliert, sonst geht ein Webhook an n8n bzw. den Runner.
3. Graduierung (knaster.graduation)
graduate(skill, variants[], run_fn, verify_fn, threshold=0.9, min_variants=10) -> GraduationReport
- Jede Variante wird mit
stage = 1auf dem Skill-Slot ausgeführt (run_fn) und geprüft (verify_fn). passed = pass_rate ≥ thresholdundn ≥ min_variants.- Bei Erfolg entsteht ein Vorschlag
promote_skill{skill, stage: 1}(Policy: approve), bei Misserfolg ein Bericht mit den fehlgeschlagenen Varianten. Diese gehen an das starke Modell, das den Skill überarbeitet. - Die Varianten erzeugt das starke Modell (Hermes) und schickt sie an
POST /v1/skills/{name}/graduate.
4. Adapter-Training (extern, Vertrag)
Eingang für den Trainingsjob: Export cases (split = train, passed = true, skill.cluster = X) plus optional preference_pairs. Ausgang: Adapter-Verzeichnis und report(build_ok, adapter_name). Die Eval nutzt die Fälle mit split = eval desselben Clusters.