Architektur der sich entwickelnden Intelligenz
Phase 21.5–40.12 — Selbstverbesserndes Skill-System für Arc OS. Status: Produktionsbereit. Sage Worker (autonome Verbesserung) + Benchmarks (A/B-Testing) + Marketplace Discovery + NotebookLM semantische Suche.
Überblick
Arc OS betreibt eine föderierte Bot-Architektur, bei der Child Bots Benutzernachrichten an das Claude CLI weiterleiten. Phase 21.1 führte Qualitätsverfolgung ein (Ausführungs-Logs, Feedback-Buttons). Phase 21.5 schließt den Kreis: Das System validiert seine eigene Ausgabe, merkt sich Korrekturen, fokussiert den Kontext und schlägt Verbesserungen autonom vor.
Sieben Säulen bilden die Intelligenzebene:
Benutzernachricht
│
├─► Context Router ──► SKILLS_HINT (Top-5 relevante Skills)
│
├─► Learnings ──► LEARNINGS-Block (vergangene Korrekturen)
│
▼
buildGsdPrompt() ──► Claude CLI ──► Antwort
│
├─► Binary Evals ──► Warnungs-Fußnoten
│
└─► Quality Tracker ──► Metriken
│
Karpathy Loop ──► CEO-Genehmigung
Säule 1: Binary Eval Engine
Modul: shared/evals.ts
Spec-Dateien: skills/<name>/<name>.evals.json
Was es tut
Jeder Skill kann Validierungsregeln in einer JSON-Datei deklarieren. Nachdem Claude eine Antwort generiert hat, prüft die Eval-Engine sie gegen alle anwendbaren Regeln. Fehler erzeugen nicht-blockierende Warnungs-Fußnoten, die an die Telegram-Nachricht angehängt werden.
Regeltypen
| Typ | Prüft | Anwendungsbeispiel |
|---|---|---|
string_contains |
Antwort enthält eine literale Zeichenkette | Verifiziert, dass JSON-Ausgabe "verdict"-Feld hat |
string_not_contains |
Antwort enthält eine Zeichenkette NICHT | Blockiert --force in Git-Anweisungen |
regex_match |
Antwort passt zu einem Regex-Muster | Stellt sicher, dass System-Audit Disk/RAM/CPU erwähnt |
regex_not_match |
Antwort passt zu einem Regex NICHT | Verhindert Credential-Leck-Muster |
max_length |
Antwortlänge <= N Zeichen | Hält Ausgabe kompakt |
min_length |
Antwortlänge >= N Zeichen | Stellt substanzielle Antworten sicher |
Schweregrade
- warning: Wird als
⚠️in der Fußnote angezeigt. Zeigt ein Qualitätsproblem an. - info: Wird als
ℹ️in der Fußnote angezeigt. Hinweisend, nicht kritisch.
Wie Evals Metriken beeinflussen
Eval-Ergebnisse werden zusammen mit Qualitätsereignissen protokolliert. Wenn die nächtliche Verbesserungsschleife einen Skill mit niedriger Erfolgsrate erkennt, helfen Eval-Fehlermuster dabei, die Ursache zu identifizieren, ohne KI-Analyse zu benötigen.
Beispiel-Eval-Datei
{
"version": 1,
"skill": "code-review",
"rules": [
{ "id": "cr-001", "name": "Must return JSON verdict", "type": "string_contains", "value": "\"verdict\"", "severity": "warning" },
{ "id": "cr-002", "name": "No console.log debug", "type": "regex_not_match", "pattern": "console\\.log\\(", "severity": "warning" }
]
}
Designprinzip
Inspiriert vom Anthropic's Skill Creator Eval-Framework: deklarative Assertions über Ausgaben, kein KI-in-the-loop für die Validierung. Binäres Bestehen/Versagen eliminiert Mehrdeutigkeit.
Säule 2: Context Router
Modul: shared/context-router.ts
Datenquelle: skills/_registry.json (triggers + keywords-Felder)
Was es tut
Bevor der GSD-Prompt aufgebaut wird, bewertet der Router jeden registrierten Skill gegen die Benutzernachricht. Die Top-5-Treffer werden als SKILLS_HINT-Block eingespritzt und primen Claude, sich auf relevante Fähigkeiten zu fokussieren.
Scoring-Algorithmus
Für jeden Skill:
score = 0
für jeden trigger: wenn Nachricht trigger enthält → score += 2
für jedes keyword: wenn Nachricht keyword enthält → score += 1
Sortieren nach score DESC → Top-5 nehmen
Trigger-Treffer erhalten höhere Punktzahl, da Trigger explizite Aufruf-Signale sind (z. B. "review", "deploy"). Keywords bieten breiteres semantisches Matching (z. B. "OWASP", "Docker").
Warum beratend, nicht filternd
Der Router ist nur beratend. Das Claude CLI lädt weiterhin alle Skills via CLAUDE.md. Gründe:
- Sicherheit: Hartes Filtern via
--allowedToolsoder Symlink-Mutationen riskiert Unterbrechungen mitten in der Sitzung, wenn der Router eine Nachricht falsch klassifiziert. - Stabilität: Keine Dateisystem-Mutationen bei einem laufenden Prozess.
- Graceful Degradation: Wenn der Router versagt, hat Claude immer noch vollen Skill-Zugriff.
Kontextfenster-Ökonomie
Ohne den Router konkurrieren alle 23 Skills um Aufmerksamkeit im Prompt. Der SKILLS_HINT-Block teilt Claude mit "fokussiere auf diese 3–5" — reduziert irrelevante Skill-Aktivierung und hält Antworten thematisch. Das ist Context Priming, keine Context-Reduktion.
Säule 3: Reflect Loop (Persistente Learnings)
Modul: shared/learnings.ts
Speicher: {PROJECT_CWD}/learnings.md
Was es tut
Wenn der CEO "Fix It" oder "👎" drückt, erfasst das System eine Lernregel und persistiert sie in einer Markdown-Datei. Bei jeder nachfolgenden Nachricht werden akkumulierte Learnings als LEARNINGS-Block in den GSD-Prompt eingespritzt.
Event → Learning-Pipeline
CEO drückt 🛠️ Fix It
│
├─► addLearning(source: "fixit", rule: "Fix requested for: <context>")
│
└─► projectLearnings vom Disk neu geladen
CEO drückt 👎
│
├─► addLearning(source: "negative", rule: "Negative feedback on: <context>")
│
└─► qualityTracker.logFeedback(positive: false)
Learnings-Dateiformat
# Learnings
> Auto-generiert. Beim Sitzungsstart in den GSD-Prompt eingespritzt.
## Regeln
- [2026-04-03T14:22:00Z] [fixit] Always use t-call for translations in Odoo QWeb
- [2026-04-03T15:10:00Z] [negative] Avoid sudo in deployment scripts
Prompt-Injektion
Die formatForPrompt()-Funktion nimmt die neuesten Learnings (bis zu 2000 Zeichen), kehrt sie um (neueste zuerst) und formatiert als:
LEARNINGS (past corrections — follow these rules):
- Avoid sudo in deployment scripts
- Always use t-call for translations in Odoo QWeb
Designprinzip
Inspiriert vom Claude Reflect System: Korrekturen beheben nicht nur die aktuelle Antwort — sie werden zu persistenten Regeln, die Regression verhindern. Das System baut über die Zeit ein "Immungedächtnis" auf.
Säule 4: Karpathy Loop (Nächtliche Selbstverbesserung)
Modul: scripts/nightly-improve.ts
Zeitplan: Täglich um 03:00 UTC via Cron
State: mcp-server/state/improvement-proposals.json
Was es tut
- Liest
config/bot_registry.jsonum alle Child Bots aufzuzählen - Für jedes Child: liest
quality-metrics.jsonaus seinem State-Verzeichnis - Ruft
findUnderperformingSkills()auf — filtert Skills, bei denen:applied_count >= 3(minimale Stichprobengröße)- UND entweder
success_rate < 80%ODERfeedback_negative > feedback_positive
- Liest
learnings.mdfür verwandte Korrekturmuster - Generiert vorlagenbasierte Vorschläge (deterministisch, kein KI beteiligt)
- Sendet Zusammenfassungsbericht an CEO-Telegram
- Sendet individuelle Vorschlagskarten mit Genehmigen/Ablehnen-Inline-Buttons
CEO-Genehmigungsfluss
Nächtliches Skript ──► Telegram: Vorschlagskarte
│
┌────────────┼────────────┐
▼ ▼
✅ Genehmigen ❌ Ablehnen
│ │
skill.md sichern Als abgelehnt markieren
als skill.v1.md in proposals.json
(max. 3 Versionen)
│
Als genehmigt markieren
in proposals.json
Skill-Versionierung
Bei Genehmigung erstellt der Master Bot versionierte Backups:
skill.md→skill.v1.md(aktuell → Backup)skill.v1.md→skill.v2.md(rotieren)- Maximal 3 Backup-Versionen pro Skill
Designprinzip
Inspiriert von Karpathys AutoResearch Loop: modifizieren → verifizieren → behalten/verwerfen → wiederholen. Der entscheidende Unterschied: Vorschläge sind vorlagenbasiert und erfordern menschliche Genehmigung. Keine autonome Skill-Überarbeitung — der CEO bleibt die finale Autorität.
Phase 36+ — NotebookLM Semantische Ebene
Phase 36.3 fügte einen fünften Feedback-Kanal hinzu: Google NotebookLM als Langzeit-Semantikgedächtnis.
CRM-Events (Issue schließen, Wiki-Update)
│
└─► Fire-and-forget POST an Bridge /sync
│
▼
NotebookLM Bridge (:19213)
├── SyncWorker (asyncio.Queue, 3 Versuche)
└── notebooklm-py → Google NotebookLM
│
▼
Notebook mit neuer Quelle aktualisiert
│
┌─────────────────────┤
▼ ▼
ask_notebooklm Tool Neural Skill Generator
(Cloud PM-Chat, 15s) (POST /skills/generate, 30s)
│ │
▼ ▼
Semantische Antwort im Markdown-Skill zur
Projekt-Kontext Überprüfung + Speichern (Phase 36.6)
Phase 36.6 fügte den Neural Skill Generator hinzu: CEO definiert ein Extraktionsziel, Bridge fragt NotebookLM mit einem strukturierten KI-Architekt-Prompt ab und gibt ein striktes Markdown-Regelbuch zurück, das als Skill gespeichert werden kann.
Phase 36.7 exponierte Notebooks in der Sidebar-UI (grüner/roter Status-Dot, Quellanzahl, externer Link).
Säule 6: Sage Worker (Phase 40.11c)
Modul: shared/sage.ts
Auslöser: POST /api/crm/sage/analyze oder scripts/nightly-improve.ts
Was es tut
Sage ist eine autonome Skill-Verbesserungs-Engine. Sie analysiert Skills anhand von Qualitätsmetriken + Benutzer-Feedback (Learnings) und generiert dann konkrete verbesserte Inhalte via Anthropic API (Haiku-Modell für Kosteneffizienz). Ergebnisse werden als skill_update_requests (PRs) in der Datenbank für CEO-Review gespeichert.
Ablauf
Sage-Analyse-Anfrage
│
├─► Aktive Skills aus DB laden (skillQueries)
├─► Mit Qualitätsmetriken abgleichen (readMetrics)
├─► Underperformer priorisieren (findUnderperformingSkills)
│
▼ Für jeden Ziel-Skill (max. 5):
├─► Skill-Inhalt + Fork laden (wenn projekt-gebunden)
├─► Qualitätsmetriken laden (Erfolgsrate, Feedback-Zähler)
├─► Verwandte Learnings laden (Benutzerkorrekturen)
├─► Überspringen wenn ausstehender PR bereits existiert
├─► Prompt aufbauen (Inhalt + Metriken + Learnings)
├─► Anthropic API aufrufen (Haiku, 30s Timeout)
├─► Antwort parsen (NO_CHANGE = überspringen)
├─► skill_update_request einfügen (proposed_by: 'sage')
└─► Benchmark automatisch ausführen (Säule 7) für neuen PR
Warum CRM-Endpunkt, kein Worker
Sage benötigt direkten DB-Zugriff (skillQueries, benchmarkQueries) — Worker laufen als Subprozesse ohne DB-Verbindung. Sage empfängt keine Benutzernachrichten; es ist ein Hintergrund-Analyzer, dessen Ausgabe = DB-Zeilen, nicht Chat-Text.
Säule 7: Datengesteuerte Genehmigungen — Benchmarks (Phase 40.11d)
Modul: shared/sage.ts (runBenchmark())
DB: shared/migrations/005_skill_benchmarks.ts
API: POST /api/crm/sage/benchmark, GET /api/crm/skill-updates/:id/benchmarks
Was es tut
Bevor der CEO einen Sage-PR genehmigt, beweist das System, dass die Änderung funktioniert. Es generiert 3 Test-Szenarien, führt sowohl alten als auch neuen Skill-Inhalt durch (Blind-A/B-Test) und verwendet einen LLM-Judge, um zu bestimmen, welcher besser ist. Kombiniertes Scoring: deterministische eval_rules (60 %) + LLM-Judge (40 %).
Benchmark-Ablauf
Benchmark ausführen (requestId)
│
├─► skill_update_request laden (current_content + proposed_content)
├─► eval_rules aus DB laden
│
▼ 3 Test-Szenarien generieren (Haiku)
│
▼ Für jedes Szenario:
├─► Alten Skill-Inhalt ausführen → old_output
├─► Neuen Skill-Inhalt ausführen → new_output
├─► A/B-Reihenfolge randomisieren (Position-Bias-Verhinderung)
├─► LLM-Judge bewertet beide (1–10) + Begründung
├─► Deterministisches eval_rules-Scoring (falls verfügbar)
├─► Kombiniertes Score: Eval 60 % + LLM 40 %
└─► In skill_benchmarks-Tabelle speichern
│
▼ PR-Metadaten aktualisieren
├─► verdict: PASSED / FAILED / TIE
├─► improvement_pct: ((new_avg - old_avg) / old_avg * 100)
└─► BenchmarkBadge im Frontend-PR-Header sichtbar
Frontend: Battle Mode
SkillEvolution.jsx → BenchmarkReport-Komponente:
- Lazy-geladen pro PR (lädt beim Aufklappen)
- Zusammenfassung: Siege/Niederlagen/Unentschieden/Verdict/improvement_pct
- Pro Szenario: Alt vs. Neu nebeneinander, Gewinner-Stern, Score/10, Urteilsbegründung
- "Run Benchmark"-Button im Content-Tab (Himmelblau)
- Anker-Button pro PR für erneutes Ausführen von Benchmarks
Dateiübersicht
shared/
├── evals.ts ← Säule 1: Binary Eval Engine
├── context-router.ts ← Säule 2: Context Router (routeContextFromDb)
├── learnings.ts ← Säule 3: Reflect Loop
├── quality.ts ← Erweitert: findUnderperformingSkills()
├── sage.ts ← Säule 6+7: Sage Worker + Benchmarks (runSageAnalysis, runBenchmark)
├── db.ts ← SQLite SSOT: skillQueries, benchmarkQueries, chatQueries
├── migrations/
│ ├── 004_skill_system.ts ← skills_global, forks, evolution_logs, update_requests
│ └── 005_skill_benchmarks.ts ← skill_benchmarks (A/B-Testergebnisse)
├── crm-routes.ts ← CRM API: 55+ Endpunkte (Sage + Benchmarks + Skill Evolution)
└── ui_templates.ts ← Erweitert: improvementProposal()
scripts/
├── nightly-improve.ts ← Säule 4: Karpathy Loop (verwendet jetzt Sage + DB)
└── migrate-skills-to-db.ts ← Kern-Migration: Dateien → DB
clients/
├── arc-cli.ts ← ARC CLI (Phase 31.5): login, start, projects
└── knowledge-mcp.ts ← Veraltet (Phase 38 → CLI-Unterbefehle)
services/
└── notebooklm-bridge/ ← Säule 5: NotebookLM semantische Suche (Phase 36.3)
├── main.py ← FastAPI (:19213), /query, /sync, /notebooks/init, /health
└── seed_knowledge.py ← Massenimport bestehenden Wissens
frontend/src/crm/pages/
└── SkillEvolution.jsx ← Zwei-Panel-UI: Explorer + Detail (Inhalt/Evals/Evolution/PRs)
BenchmarkBadge, BenchmarkReport, Battle Mode, Sage-Analyse-Button
child-bot/bot.ts ← Integration: Start + GSD-Prompt + Eval-Fußnoten + /learnings
child-bot/ingest-watcher.ts ← Auto-Ingest: fs.watch auf raw/ → CRM-Inbox (Phase 28)
master-bot/bot.ts ← Integration: Sage nächtlicher Cron-Auslöser