Architektura Ewoluującej Inteligencji
Phase 21.5–40.12 — System samodoskonalących się skilli dla Arc OS. Status: Gotowy produkcyjnie. Sage Worker (autonomiczne doskonalenie) + benchmarki (testowanie A/B) + odkrywanie marketplace + wyszukiwanie semantyczne NotebookLM.
Ogólny opis
Arc OS operuje federowaną architekturą botów, gdzie child boty pośredniczą między wiadomościami użytkownika a Claude CLI. Phase 21.1 wprowadziła śledzenie jakości (logi wykonania, przyciski feedbacku). Phase 21.5 zamyka pętlę: system teraz waliduje własne wyniki, zapamiętuje korekty, skupia kontekst i autonomicznie proponuje ulepszenia.
Siedem filarów tworzy warstwę inteligencji:
Wiadomość użytkownika
│
├─► Context Router ──► SKILLS_HINT (top 5 trafnych skilli)
│
├─► Learnings ──► blok LEARNINGS (przeszłe korekty)
│
▼
buildGsdPrompt() ──► Claude CLI ──► Odpowiedź
│
├─► Binary Evals ──► Przypisy z ostrzeżeniami
│
└─► Quality Tracker ──► Metryki
│
Nightly Improve ──► Zatwierdzenie CEO
Filar 1: Silnik Binary Evals
Moduł: shared/evals.ts
Pliki spec: skills/<nazwa>/<nazwa>.evals.json
Co robi
Każdy skill może deklarować reguły walidacji w pliku JSON. Po wygenerowaniu odpowiedzi przez Claude, silnik evals sprawdza ją względem wszystkich obowiązujących reguł. Niepowodzenia generują nieblokujące przypisy z ostrzeżeniami dołączane do wiadomości Telegram.
Typy reguł
| Typ | Sprawdza | Przykładowe zastosowanie |
|---|---|---|
string_contains |
Odpowiedź zawiera dosłowny ciąg | Weryfikacja że wyjście JSON ma pole "verdict" |
string_not_contains |
Odpowiedź NIE zawiera ciągu | Blokuj --force w instrukcjach git |
regex_match |
Odpowiedź pasuje do wzorca regex | Upewnij się, że audyt systemu wspomina o dysku/RAM/CPU |
regex_not_match |
Odpowiedź NIE pasuje do regex | Zapobiegaj wzorcom wycieku danych uwierzytelniających |
max_length |
Długość odpowiedzi <= N znaków | Zachowaj zwięzłość wyjścia |
min_length |
Długość odpowiedzi >= N znaków | Zapewnij merytoryczne odpowiedzi |
Poziomy ważności
- warning: Wyświetlane jako
⚠️w przypisie. Wskazuje problem z jakością. - info: Wyświetlane jako
ℹ️w przypisie. Informacyjne, niekrytyczne.
Jak evals wpływają na metryki
Wyniki evals logowane są obok zdarzeń jakościowych. Gdy nocna pętla doskonalenia wykryje skill z niskim wskaźnikiem sukcesu, wzorce niepowodzeń evals pomagają zidentyfikować przyczynę bez potrzeby analizy AI.
Przykładowy plik eval
{
"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" }
]
}
Zasada projektowania
Inspirowane frameworkiem evals Anthropic Skill Creator: deklaratywne asercje nad wyjściami, bez AI w pętli walidacyjnej. Binarne pass/fail eliminuje niejednoznaczność.
Filar 2: Context Router
Moduł: shared/context-router.ts
Źródło danych: skills/_registry.json (pola triggers + keywords)
Co robi
Przed zbudowaniem promptu GSD, router ocenia każdy zarejestrowany skill względem wiadomości użytkownika. Top 5 dopasowań wstrzykiwanych jest jako blok SKILLS_HINT, nakierowując Claude na odpowiednie możliwości.
Algorytm oceniania
Dla każdego skilla:
score = 0
dla każdego triggera: jeśli wiadomość zawiera trigger → score += 2
dla każdego słowa kluczowego: jeśli wiadomość zawiera słowo kluczowe → score += 1
Sortuj po score MALEJĄCO → weź top 5
Dopasowania triggerów punktują wyżej, bo triggery są jawnymi sygnałami wywołania (np. "review", "deploy"). Słowa kluczowe zapewniają szersze dopasowanie semantyczne (np. "OWASP", "Docker").
Dlaczego doradczy, nie filtrujący
Router jest wyłącznie doradczy. Claude CLI nadal ładuje wszystkie skille przez CLAUDE.md. Powody:
- Bezpieczeństwo: Twarde filtrowanie przez
--allowedToolslub mutacje symlinków ryzykuje zepsuciem mid-sesji przy błędnej klasyfikacji wiadomości. - Stabilność: Brak mutacji systemu plików na działającym procesie.
- Graceful degradation: Jeśli router zawiedzie, Claude nadal ma pełny dostęp do skilli.
Ekonomia okna kontekstu
Bez routera, wszystkie 23 skille konkurują o uwagę w prompcie. Blok SKILLS_HINT mówi Claude „skupi się na tych 3–5" — zmniejsza aktywację nieistotnych skilli i utrzymuje trafność odpowiedzi. To priming kontekstu, nie redukcja kontekstu.
Filar 3: Reflect Loop (Trwałe learnings)
Moduł: shared/learnings.ts
Przechowywanie: {PROJECT_CWD}/learnings.md
Co robi
Gdy CEO naciska „Fix It" lub „👎", system przechwytuje regułę uczenia się i zapisuje ją do pliku markdown. Przy każdej kolejnej wiadomości, skumulowane learnings wstrzykiwane są do promptu GSD jako blok LEARNINGS.
Potok zdarzenie → learning
CEO naciska 🛠️ Fix It
│
├─► addLearning(source: "fixit", rule: "Fix requested for: <kontekst>")
│
└─► projectLearnings przeładowane z dysku
CEO naciska 👎
│
├─► addLearning(source: "negative", rule: "Negative feedback on: <kontekst>")
│
└─► qualityTracker.logFeedback(positive: false)
Format pliku learnings
# Learnings
> Auto-generowane. Wstrzykiwane do promptu GSD na początku sesji.
## Rules
- [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
Wstrzykiwanie do promptu
Funkcja formatForPrompt() pobiera najnowsze learnings (do 2000 znaków), odwraca je (najnowsze pierwsze) i formatuje jako:
LEARNINGS (past corrections — follow these rules):
- Avoid sudo in deployment scripts
- Always use t-call for translations in Odoo QWeb
Zasada projektowania
Inspirowane systemem Claude Reflect: korekty nie naprawiają tylko bieżącej odpowiedzi — stają się trwałymi regułami zapobiegającymi regresji. System buduje „pamięć immunologiczną" z czasem.
Filar 4: Karpathy Loop (Nocne samodoskonalenie)
Moduł: scripts/nightly-improve.ts
Harmonogram: Codziennie o 03:00 UTC przez cron
Stan: mcp-server/state/improvement-proposals.json
Co robi
- Odczytuje
config/bot_registry.jsonaby wyliczyć wszystkie child boty - Dla każdego child bota: odczytuje
quality-metrics.jsonz katalogu stanu - Wywołuje
findUnderperformingSkills()— filtruje skille gdzie:applied_count >= 3(minimalna próbka)- ORAZ
success_rate < 80%LUBfeedback_negative > feedback_positive
- Odczytuje
learnings.mdw poszukiwaniu powiązanych wzorców korekt - Generuje propozycje oparte na szablonach (deterministyczne, bez AI)
- Wysyła raport podsumowujący do CEO na Telegram
- Wysyła indywidualne karty propozycji z przyciskami inline Zatwierdź/Odrzuć
Przepływ zatwierdzania przez CEO
Skrypt nocny ──► Telegram: Karta propozycji
│
┌────────────┼────────────┐
▼ ▼
✅ Zatwierdź ❌ Odrzuć
│ │
Backup skill.md Oznacz jako odrzuconą
jako skill.v1.md w proposals.json
(maks. 3 wersje)
│
Oznacz jako zatwierdzoną
w proposals.json
Wersjonowanie skilli
Przy zatwierdzeniu, master bot tworzy kopie zapasowe z wersjami:
skill.md→skill.v1.md(bieżący → backup)skill.v1.md→skill.v2.md(rotacja)- Maksymalnie 3 wersje backup per skill
Zasada projektowania
Inspirowane AutoResearch Loop Karpathy'ego: modyfikuj → weryfikuj → zachowaj/odrzuć → powtarzaj. Kluczowa różnica: propozycje oparte są na szablonach i wymagają zatwierdzenia człowieka. Brak autonomicznego przepisywania skilli — CEO pozostaje ostatecznym autorytetem.
Phase 36+ — Warstwa semantyczna NotebookLM
Phase 36.3 dodała piąty kanał feedbacku: Google NotebookLM jako długoterminową pamięć semantyczną.
Zdarzenia CRM (zamknięcie zgłoszenia, aktualizacja wiki)
│
└─► fire-and-forget POST do bridge /sync
│
▼
NotebookLM Bridge (:19213)
├── SyncWorker (asyncio.Queue, 3 próby)
└── notebooklm-py → Google NotebookLM
│
▼
Notatnik zaktualizowany nowym źródłem
│
┌─────────────────────┤
▼ ▼
narzędzie ask_notebooklm Neural Skill Generator
(chat Cloud PM, 15s) (POST /skills/generate, 30s)
│ │
▼ ▼
Semantyczna odpowiedź Skill w Markdown do
w kontekście projektu przeglądu + zapisu (Phase 36.6)
Phase 36.6 dodała Neural Skill Generator: CEO definiuje cel ekstrakcji, bridge odpytuje NotebookLM ze strukturowanym promptem AI Architect, zwraca ścisły Markdown Rulebook, który można zapisać jako skill.
Phase 36.7 udostępniła notatniki w UI sidebara (zielona/czerwona kropka statusu, liczba źródeł, link zewnętrzny).
Filar 6: Sage Worker (Phase 40.11c)
Moduł: shared/sage.ts
Wyzwalacz: POST /api/crm/sage/analyze lub scripts/nightly-improve.ts
Co robi
Sage to autonomiczny silnik doskonalenia skilli. Analizuje skille używając metryk jakości + feedbacku użytkownika (learnings), następnie generuje konkretną ulepszoną treść przez Anthropic API (model Haiku dla opłacalności). Wyniki przechowywane są jako skill_update_requests (PR-y) w bazie danych do przeglądu przez CEO.
Przepływ
Żądanie analizy Sage
│
├─► Załaduj aktywne skille z DB (skillQueries)
├─► Skrzyżuj z metrykami jakości (readMetrics)
├─► Priorytetyzuj słabsze (findUnderperformingSkills)
│
▼ Dla każdego docelowego skilla (maks. 5):
├─► Załaduj treść skilla + fork (jeśli scoped do projektu)
├─► Załaduj metryki jakości (wskaźnik sukcesu, liczniki feedbacku)
├─► Załaduj powiązane learnings (korekty użytkownika)
├─► Pomiń jeśli istnieje oczekujący PR
├─► Zbuduj prompt (treść + metryki + learnings)
├─► Wywołaj Anthropic API (Haiku, timeout 30s)
├─► Parsuj odpowiedź (NO_CHANGE = pomiń)
├─► Wstaw skill_update_request (proposed_by: 'sage')
└─► Auto-uruchom benchmark (Filar 7) dla nowego PR
Dlaczego endpoint CRM, nie worker
Sage potrzebuje bezpośredniego dostępu do DB (skillQueries, benchmarkQueries) — workerzy działają jako podprocesy bez połączenia z DB. Sage nie otrzymuje wiadomości użytkownika; to analizator działający w tle, którego wynik = wiersze DB, nie tekst czatu.
Filar 7: Zatwierdzenia oparte na danych — Benchmarki (Phase 40.11d)
Moduł: shared/sage.ts (runBenchmark())
DB: shared/migrations/005_skill_benchmarks.ts
API: POST /api/crm/sage/benchmark, GET /api/crm/skill-updates/:id/benchmarks
Co robi
Zanim CEO zatwierdzi PR Sage, system udowadnia, że zmiana działa. Generuje 3 scenariusze testowe, uruchamia stare i nowe treści skilla przez nie (ślepy test A/B) i używa sędziego LLM do oceny. Łączone punktowanie: deterministyczne eval_rules (60%) + sędzia LLM (40%).
Przepływ benchmarku
Uruchom Benchmark (requestId)
│
├─► Załaduj skill_update_request (current_content + proposed_content)
├─► Załaduj eval_rules z DB
│
▼ Generuj 3 scenariusze testowe (Haiku)
│
▼ Dla każdego scenariusza:
├─► Uruchom starą treść skilla → old_output
├─► Uruchom nową treść skilla → new_output
├─► Randomizuj kolejność A/B (zapobieganie biasowi pozycji)
├─► Sędzia LLM ocenia oba (1-10) + uzasadnienie
├─► Deterministyczne eval_rules scoring (jeśli dostępne)
├─► Łączone punktowanie: eval 60% + LLM 40%
└─► Zapisz do tabeli skill_benchmarks
│
▼ Aktualizuj metadane PR
├─► verdict: PASSED / FAILED / TIE
├─► improvement_pct: ((new_avg - old_avg) / old_avg * 100)
└─► BenchmarkBadge widoczny w nagłówku PR na froncie
Frontend: Tryb Battle
SkillEvolution.jsx → komponent BenchmarkReport:
- Lazy-load per PR (pobiera przy rozwinięciu)
- Podsumowanie: wins/losses/ties/verdict/improvement_pct
- Per scenariusz: Stare vs Nowe obok siebie, gwiazdka zwycięzcy, wynik/10, uzasadnienie oceny
- Przycisk „Run Benchmark" na zakładce Content (niebieski)
- Przycisk kotwicy per PR do ponownego uruchomienia benchmarków
Mapa plików
shared/
├── evals.ts ← Filar 1: Silnik Binary Evals
├── context-router.ts ← Filar 2: Context Router (routeContextFromDb)
├── learnings.ts ← Filar 3: Reflect Loop
├── quality.ts ← Rozszerzone: findUnderperformingSkills()
├── sage.ts ← Filar 6+7: Sage Worker + Benchmarki (runSageAnalysis, runBenchmark)
├── db.ts ← SQLite jako SSOT: skillQueries, benchmarkQueries, chatQueries
├── migrations/
│ ├── 004_skill_system.ts ← skills_global, forki, evolution_logs, update_requests
│ └── 005_skill_benchmarks.ts ← skill_benchmarks (wyniki testów A/B)
├── crm-routes.ts ← CRM API: 55+ endpointów (Sage + benchmarki + ewolucja skilli)
└── ui_templates.ts ← Rozszerzone: improvementProposal()
scripts/
├── nightly-improve.ts ← Filar 4: Karpathy Loop (używa teraz Sage + DB)
└── migrate-skills-to-db.ts ← Migracja nuklearna: pliki → DB
clients/
├── arc-cli.ts ← ARC CLI (Phase 31.5): login, start, projekty
└── knowledge-mcp.ts ← Przestarzały (Phase 38 → podkomendy CLI)
services/
└── notebooklm-bridge/ ← Filar 5: wyszukiwanie semantyczne NotebookLM (Phase 36.3)
├── main.py ← FastAPI (:19213), /query, /sync, /notebooks/init, /health
└── seed_knowledge.py ← Masowy import istniejącej wiedzy
frontend/src/crm/pages/
└── SkillEvolution.jsx ← Dwupanelowy UI: eksplorator + szczegóły (Content/Evals/Evolution/PRs)
BenchmarkBadge, BenchmarkReport, tryb Battle, przycisk analizy Sage
child-bot/bot.ts ← Integracja: startup + prompt GSD + przypisy evals + /learnings
child-bot/ingest-watcher.ts ← Auto-ingest: fs.watch na raw/ → inbox CRM (Phase 28)
master-bot/bot.ts ← Integracja: nocny trigger cron Sage