Phase 11 Ausbau: AUTO-Heuristik + Custom Sub-Agents + Delegations-Badge

Bridge (scripts/claude-bridge.js):
- chooseAutoMode(): Keyword-Heuristik wählt solo/handlanger/experten
  basierend auf Aufgabenkomplexität und Nachrichtenlänge
- auto-mode-chosen Event fuer Frontend-Feedback
- effectiveMode statt agentMode durchs ganze sendMessage-Flow

Custom Sub-Agents via SDK agents-Option:
- HANDLANGER_AGENTS.worker: Haiku, exakte Ausfuehrung, max 500 Tokens
- EXPERTEN_AGENTS: research/implement/test/review mit eigenen Tools+Prompts
- Orchestrator-Prompts verweisen auf subagent_type Namen
- Kostenersparnis im Handlanger-Modus durch Haiku-Delegation

UI (AgentView.svelte):
- Delegations-Badge bei Sub-Agent-Knoten (farbcodiert nach Modus)
- Nur sichtbar bei depth > 0 und Modus != solo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Eddy 2026-04-14 18:50:30 +02:00
parent 314042a01f
commit de90c2da19
3 changed files with 227 additions and 41 deletions

View file

@ -35,6 +35,7 @@ Stand: 14.04.2026
| **Context-Management (Phase 9)** | ✅ | eb91e54 |
| **Sprach-Interface (Phase 10)** | ✅ | 14.04.2026 |
| **Multi-Agent-Modi (Phase 11 — Basis)** | ✅ | 14.04.2026 |
| **Multi-Agent-Ausbau (Phase 11 — Vollendung)** | ✅ | 14.04.2026 |
---
@ -348,7 +349,7 @@ Benötigt `OPENAI_API_KEY` Umgebungsvariable für Whisper + TTS.
---
## Phase 11: Multi-Agent-Architektur (Context-Einsparung) 🚧 TEIL-ERLEDIGT
## Phase 11: Multi-Agent-Architektur (Context-Einsparung) ERLEDIGT
> **Basis-Implementierung:** 14.04.2026 (Tool-Filterung + Persistenz + UI-Badge)
@ -369,7 +370,30 @@ Benötigt `OPENAI_API_KEY` Umgebungsvariable für Whisper + TTS.
- ✅ **Frontend: mode-changed Listener** (`events.ts`)
- Badge aktualisiert sich bei Modus-Wechsel live
### Noch offen (Ausbau)
### Ausbau-Implementierung (14.04.2026)
- ✅ **AUTO-Modus Keyword-Heuristik** (`chooseAutoMode()` in Bridge)
- < 80 Zeichen solo
- "implementiere/refactor/baue…" → experten
- "lies/suche/finde/analysiere…" + > 120 Zeichen → handlanger
- > 300 Zeichen ohne klare Keywords → handlanger (safer default)
- Sendet `auto-mode-chosen` Event ans Frontend
- ✅ **Custom Sub-Agent-Definitionen via SDK `agents` Option**
- **Handlanger**: Sub-Agent "worker" auf **Haiku** — nur Ausführung, max 500 Tokens Rückmeldung
- **Experten**: 4 autonome Agents
- `research` — Code/Docs durchsuchen (Read, Grep, Glob, Bash)
- `implement` — Code schreiben nach Best-Practices (volle Tools)
- `test` — Testfälle wählen und ausführen (volle Tools)
- `review` — Code prüfen auf Qualität/Sicherheit (read-only)
- Experten erben Modell (`model: 'inherit'`), Handlanger nutzt explizit Haiku
- ✅ **AgentView: Delegations-Badge**
- Bei Sub-Agent-Knoten wird der aktuelle Delegations-Modus farbcodiert angezeigt
- 👷 Handlanger (orange), 🎓 Experten (lila), 🤖 Auto (cyan)
- ✅ **Orchestrator-Prompts angepasst**
- Verweisen explizit auf `subagent_type` der verfügbaren Custom Agents
- Anweisung: Formuliere WAS (Experten) oder EXAKT WIE (Handlanger)
### Alle Phase 11 Features implementiert!
### Die drei Agent-Modi (einstellbar!)

View file

@ -33,43 +33,46 @@ Du bist der HAUPT-AGENT und arbeitest im HANDLANGER-MODUS.
WICHTIG: Du denkst und planst, aber Sub-Agents führen aus!
Wenn du eine Aufgabe bekommst:
1. ANALYSIERE was nötig ist
2. DELEGIERE an passende Sub-Agents mit EXAKTEN Anweisungen
3. Sub-Agents führen GENAU aus, was du sagst sie denken NICHT selbst
4. Du erhältst ZUSAMMENFASSUNGEN zurück (keine Rohdaten)
5. Du entscheidest den nächsten Schritt
Dir steht das Task-Tool zur Verfügung mit dem Sub-Agent-Typ "worker".
Der Worker läuft auf Haiku (günstig) und führt genau aus was du sagst.
Arbeitsweise:
1. ANALYSIERE die Aufgabe
2. Zerlege in EXAKTE Ausführungsschritte
3. Delegiere jeden Schritt per Task(subagent_type: "worker", prompt: "...")
4. Formuliere den Task-Prompt als exakte Anweisung, nicht als Frage
5. Sammle die Zusammenfassungen, entscheide den nächsten Schritt
Beispiel-Delegationen:
- "Lies Datei X, gib mir Zeilen 10-50 zurück"
- "Suche nach 'handleError' in src/, liste die Dateien"
- "Führe 'npm test' aus, berichte nur ob passed/failed"
- Task(subagent_type:"worker", prompt:"Lies src/lib.rs, gib mir Zeilen 10-50 zurück")
- Task(subagent_type:"worker", prompt:"Suche 'handleError' in src/ via Grep, liste die Dateien")
- Task(subagent_type:"worker", prompt:"Führe 'npm test' aus, berichte nur passed/failed + Fehlerzeile")
Halte deinen Context klein lass Sub-Agents die Details bearbeiten!
Halte deinen Context klein lass den Worker die Rohdaten bearbeiten!
`,
experten: `
Du bist der HAUPT-AGENT und arbeitest im EXPERTEN-MODUS.
WICHTIG: Du koordinierst autonome Experten-Agents!
WICHTIG: Du koordinierst vier autonome Experten-Agents!
Deine Experten:
- **Research**: Durchsucht Code, findet Informationen, PLANT SELBST wie er sucht
- **Implement**: Schreibt Code, ENTSCHEIDET SELBST wie er es macht (Best Practices)
- **Test**: Schreibt und führt Tests aus, WÄHLT SELBST passende Testfälle
- **Review**: Prüft Code, FINDET SELBST Probleme
Task-Tool Sub-Agent-Typen (autonome Experten):
- **research**: Durchsucht Code/Docs, findet Infos. Wähle diesen für "Finde heraus…", "Wo ist…"
- **implement**: Schreibt Code nach Best-Practices. Wähle diesen für "Implementiere…", "Baue…"
- **test**: Schreibt und führt Tests. Wähle diesen für "Teste…"
- **review**: Prüft Code auf Qualität/Sicherheit. Wähle diesen für "Prüfe…"
Wenn du eine Aufgabe bekommst:
1. TEILE sie in Experten-Bereiche auf
2. DELEGIERE an den passenden Experten mit dem WAS, nicht dem WIE
3. Der Experte arbeitet AUTONOM und liefert eine Zusammenfassung
4. Du INTEGRIERST die Ergebnisse
Arbeitsweise:
1. ZERLEGE die Aufgabe in Experten-Bereiche
2. DELEGIERE via Task(subagent_type: "research"|"implement"|"test"|"review", prompt: "...")
3. Formuliere das WAS, nicht das WIE die Experten planen selbst
4. Integriere die Zusammenfassungen, orchestriere weitere Schritte
Beispiel-Delegationen:
- Research: "Finde heraus wie Authentication in diesem Projekt implementiert ist"
- Implement: "Füge OAuth2-Support hinzu" (ohne exakte Code-Vorgabe)
- Test: "Teste die neue Auth-Funktionalität"
- Review: "Prüfe die OAuth-Implementierung auf Sicherheitsprobleme"
- Task(subagent_type:"research", prompt:"Finde heraus wie Authentication implementiert ist")
- Task(subagent_type:"implement", prompt:"Füge OAuth2-Support hinzu mit Token-Refresh")
- Task(subagent_type:"test", prompt:"Teste die neue Auth-Funktionalität")
- Task(subagent_type:"review", prompt:"Prüfe die OAuth-Implementierung auf Sicherheitsprobleme")
`,
auto: `
@ -84,6 +87,82 @@ Teile deine Wahl am Anfang mit: "[Modus: X] Begründung"
`,
};
// ============ Custom Sub-Agent Definitionen ============
// Werden je nach Modus an query() übergeben
const HANDLANGER_AGENTS = {
worker: {
description: 'Führt exakte Anweisungen des Haupt-Agents aus (lesen, suchen, triviale Edits). Denkt NICHT selbst, berichtet komprimiert zurück.',
// Günstiges Modell — Handlanger muss nicht planen
model: 'haiku',
tools: ['Read', 'Grep', 'Glob', 'Bash', 'Edit', 'Write'],
prompt: `Du bist ein HANDLANGER-Agent.
WICHTIG:
1. Führe GENAU aus was der Haupt-Agent verlangt denke NICHT selbst
2. Plane keine eigene Herangehensweise
3. Berichte KOMPRIMIERT zurück (max. 500 Tokens):
- Bei Read: Relevante Zeilen/Passagen, keine Volltext-Dumps
- Bei Grep: Liste der Treffer mit Zeilennummern
- Bei Bash: Exit-Code + wichtigste Ausgabe-Zeilen
- Bei Edit/Write: Bestätigung was geändert wurde
4. Keine Erklärungen, keine Vorschläge nur das verlangte Ergebnis`,
},
};
const EXPERTEN_AGENTS = {
research: {
description: 'Durchsucht Code und Dokumentation autonom. Findet selbst heraus was relevant ist.',
model: 'inherit',
tools: ['Read', 'Grep', 'Glob', 'Bash'],
prompt: `Du bist ein RESEARCH-Experte.
Du bekommst eine Frage plane selbst wie du sie beantwortest:
- Wähle selbst welche Dateien/Patterns zu suchen sind
- Priorisiere wichtige Infos
- Berichte strukturiert: Was gefunden, wo (Pfade/Zeilen), warum relevant
- Max 1000 Tokens Zusammenfassung`,
},
implement: {
description: 'Schreibt Code-Änderungen nach Best-Practices. Entscheidet selbst über Architektur und Details.',
model: 'inherit',
tools: ['Read', 'Grep', 'Glob', 'Edit', 'Write', 'Bash'],
prompt: `Du bist ein IMPLEMENT-Experte.
Du bekommst das WAS entscheide selbst das WIE:
- Lies relevanten Code zum Verständnis
- Implementiere nach Best-Practices (Codierrichtlinien des Projekts beachten)
- Berichte: welche Dateien geändert, was war der Kern, was beibehalten
- Max 800 Tokens Zusammenfassung`,
},
test: {
description: 'Schreibt und führt Tests aus. Wählt selbst sinnvolle Testfälle.',
model: 'inherit',
tools: ['Read', 'Grep', 'Glob', 'Edit', 'Write', 'Bash'],
prompt: `Du bist ein TEST-Experte.
Du bekommst ein Feature wähle selbst passende Testfälle:
- Happy Path + sinnvolle Edge Cases
- Nutze vorhandene Test-Infrastruktur
- Berichte: Tests geschrieben (Anzahl), was ist abgedeckt, passed/failed
- Max 500 Tokens Zusammenfassung`,
},
review: {
description: 'Prüft Code auf Qualität, Sicherheit und Stil. Findet selbst Probleme.',
model: 'inherit',
tools: ['Read', 'Grep', 'Glob', 'Bash'],
prompt: `Du bist ein REVIEW-Experte.
Du bekommst Code zum Prüfen finde selbst Probleme:
- Sicherheit (Injections, Secrets, Auth)
- Performance (N+1, unnötige Loops)
- Fehlerbehandlung (Boundary-Cases)
- Stil (Konsistenz mit Projekt)
- Berichte strukturiert nach Schwere (kritisch/warnung/info)
- Max 800 Tokens`,
},
};
// Subagent-Tracking
// Map: toolUseId → { agentId, parentId, type, task, depth }
const activeSubagents = new Map();
@ -147,6 +226,38 @@ function sendMonitorEvent(type, summary, details = {}, options = {}) {
});
}
// AUTO-Modus: Heuristik wählt passenden Modus basierend auf Aufgabe
// Rückgabe: 'solo' | 'handlanger' | 'experten'
function chooseAutoMode(message) {
const text = (message || '').toLowerCase();
const charCount = text.length;
// Keywords die klar auf Experten-Aufgaben hinweisen (komplexe, parallelisierbare Arbeit)
const expertKeywords = [
'implementiere', 'implementier ', 'refactor', 'architektur', 'entwickle',
'erstelle feature', 'feature ', 'design', 'baue ', 'optimiere',
'migration', 'umbau', 'umstruktur',
];
// Keywords die auf Handlanger-Aufgaben hinweisen (viel koordinieren/sammeln)
const handlangerKeywords = [
'lies ', 'suche ', 'finde ', 'zeig mir ', 'untersuche',
'analysiere', 'durchsuche', 'alle dateien', 'sammle',
'liste alle', 'vergleiche',
];
// Klar triviale Aufgaben → solo
if (charCount < 80) return 'solo';
if (expertKeywords.some(kw => text.includes(kw))) return 'experten';
if (handlangerKeywords.some(kw => text.includes(kw)) && charCount > 120) return 'handlanger';
// Längere Nachrichten ohne klare Keywords → handlanger (safer default)
if (charCount > 300) return 'handlanger';
return 'solo';
}
// Tool-Input für Logging kürzen (sensitive Daten maskieren)
function summarizeToolInput(tool, input) {
if (!input) return '';
@ -221,13 +332,24 @@ async function sendMessage(message, requestId, model = null, contextOverride = n
resumeSessionId: resumeSessionId || null,
});
sendResponse(requestId, { agentId: currentAgentId, status: 'gestartet', model: useModel, resuming: isResuming, mode: agentMode });
// AUTO-Modus: Effektiven Modus aus der Nachricht ableiten
let effectiveMode = agentMode;
if (agentMode === 'auto') {
effectiveMode = chooseAutoMode(message);
sendEvent('auto-mode-chosen', { chosen: effectiveMode, messageLength: message.length });
sendMonitorEvent('agent', `Auto-Modus gewählt: ${effectiveMode}`, {
chosen: effectiveMode,
messageLength: message.length,
});
}
// Orchestrator-Prompt für nicht-Solo Modi
sendResponse(requestId, { agentId: currentAgentId, status: 'gestartet', model: useModel, resuming: isResuming, mode: agentMode, effectiveMode });
// Orchestrator-Prompt für nicht-Solo Modi (nutzt effektiven Modus)
let orchestratorPrompt = '';
if (agentMode !== 'solo' && ORCHESTRATOR_PROMPTS[agentMode]) {
orchestratorPrompt = ORCHESTRATOR_PROMPTS[agentMode];
sendMonitorEvent('agent', `Orchestrator-Modus: ${agentMode}`, { mode: agentMode });
if (effectiveMode !== 'solo' && ORCHESTRATOR_PROMPTS[effectiveMode]) {
orchestratorPrompt = ORCHESTRATOR_PROMPTS[effectiveMode];
sendMonitorEvent('agent', `Orchestrator-Modus: ${effectiveMode}`, { mode: effectiveMode });
}
// Nachricht mit Context und Orchestrator kombinieren
@ -256,23 +378,29 @@ async function sendMessage(message, requestId, model = null, contextOverride = n
queryOptions.sessionId = resumeSessionId;
}
// Tool-Filterung je nach Agent-Modus — erzwingt Delegation
// Tool-Filterung + Custom Sub-Agents je nach effektivem Modus
// Handlanger: Main darf NUR delegieren (Task) und planen (TodoWrite)
// Sub-Agents laufen auf Haiku (siehe HANDLANGER_AGENTS)
// Experten: Main darf zusätzlich lesen/suchen, aber nicht schreiben
if (agentMode === 'handlanger') {
// Sub-Agents sind autonome Research/Implement/Test/Review
if (effectiveMode === 'handlanger') {
queryOptions.allowedTools = ['Task', 'TodoWrite'];
sendMonitorEvent('agent', 'Handlanger-Modus: Main darf nur Task+TodoWrite', {
mode: agentMode,
queryOptions.agents = HANDLANGER_AGENTS;
sendMonitorEvent('agent', 'Handlanger-Modus: Main → Task+TodoWrite, Worker auf Haiku', {
mode: effectiveMode,
allowedTools: queryOptions.allowedTools,
agents: Object.keys(HANDLANGER_AGENTS),
});
} else if (agentMode === 'experten') {
} else if (effectiveMode === 'experten') {
queryOptions.allowedTools = ['Task', 'TodoWrite', 'Read', 'Grep', 'Glob'];
sendMonitorEvent('agent', 'Experten-Modus: Main darf lesen+delegieren', {
mode: agentMode,
queryOptions.agents = EXPERTEN_AGENTS;
sendMonitorEvent('agent', 'Experten-Modus: 4 autonome Experten verfügbar', {
mode: effectiveMode,
allowedTools: queryOptions.allowedTools,
agents: Object.keys(EXPERTEN_AGENTS),
});
}
// solo + auto: keine Einschränkung
// solo: keine Einschränkung
const conversation = query({
prompt: fullPrompt,

View file

@ -1,7 +1,14 @@
<script lang="ts">
import { agents, selectedAgentId, agentCount, agentTree, type AgentTreeNode } from '$lib/stores/app';
import { agents, selectedAgentId, agentCount, agentTree, agentMode, type AgentTreeNode } from '$lib/stores/app';
import type { Agent } from '$lib/stores/app';
// Delegations-Badge-Text je nach Agent-Modus
const delegationBadges: Record<string, { label: string; cssClass: string }> = {
handlanger: { label: '👷 Handlanger-Auftrag', cssClass: 'badge-handlanger' },
experten: { label: '🎓 Experten-Auftrag', cssClass: 'badge-experten' },
auto: { label: '🤖 Auto', cssClass: 'badge-auto' },
};
// Status-Icons
const statusIcons: Record<Agent['status'], string> = {
active: '🟢',
@ -111,6 +118,12 @@
<span class="agent-tools">🔧 {agent.toolCalls.length}</span>
{#if depth > 0}
<span class="agent-depth">Ebene {depth}</span>
{#if $agentMode && $agentMode !== 'solo' && delegationBadges[$agentMode]}
<span class="delegation-badge {delegationBadges[$agentMode].cssClass}"
title="Delegiert im Modus: {$agentMode}">
{delegationBadges[$agentMode].label}
</span>
{/if}
{/if}
</div>
</div>
@ -383,6 +396,27 @@
border-radius: var(--radius-sm);
}
.delegation-badge {
padding: 1px 6px;
border-radius: var(--radius-sm);
font-weight: 600;
}
.delegation-badge.badge-handlanger {
color: #f59e0b;
background: rgba(245, 158, 11, 0.15);
}
.delegation-badge.badge-experten {
color: #a855f7;
background: rgba(168, 85, 247, 0.15);
}
.delegation-badge.badge-auto {
color: #06b6d4;
background: rgba(6, 182, 212, 0.15);
}
.agent-children {
margin-top: var(--spacing-xs);
}