diff options
Diffstat (limited to 'Omni/Agent/Subagent/DESIGN.md')
| -rw-r--r-- | Omni/Agent/Subagent/DESIGN.md | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/Omni/Agent/Subagent/DESIGN.md b/Omni/Agent/Subagent/DESIGN.md new file mode 100644 index 0000000..9fd20d1 --- /dev/null +++ b/Omni/Agent/Subagent/DESIGN.md @@ -0,0 +1,352 @@ +# Subagent System Design + +**Status:** Draft +**Goal:** Enable Ava (orchestrator) to spawn specialized subagents for parallel, token-intensive tasks. + +## 1. Architecture Overview + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Ava (Orchestrator) │ +│ Model: claude-sonnet-4.5 (via OpenRouter) │ +│ Role: Task decomposition, delegation, synthesis │ +│ Memory: Read/Write access │ +├─────────────────────────────────────────────────────────────┤ +│ Tools: spawn_subagent, all existing Ava tools │ +└───────────────┬───────────────────────────────────────┬─────┘ + │ │ + ▼ ▼ +┌───────────────────────────┐ ┌───────────────────────────┐ +│ Subagent: WebCrawler │ │ Subagent: CodeReviewer │ +│ Model: claude-haiku │ │ Model: claude-opus │ +│ Tools: web_search, │ │ Tools: read_file, │ +│ http_get, │ │ search_codebase, │ +│ python_exec │ │ run_bash │ +│ Memory: Read-only │ │ Memory: Read-only │ +│ Limits: 600s, $0.50 │ │ Limits: 300s, $1.00 │ +└───────────────────────────┘ └───────────────────────────┘ +``` + +## 2. Key Design Decisions + +### 2.1 Hierarchical (No Sub-Subagents) +- Subagents cannot spawn their own subagents +- Prevents runaway token consumption +- Keeps orchestrator in control + +### 2.2 Memory Access +- **Orchestrator (Ava):** Full read/write to Memory system +- **Subagents:** Read-only access to memories +- Prevents conflicting memory writes from parallel agents + +### 2.3 Model Selection by Role +| Role | Model | Rationale | +|------|-------|-----------| +| Orchestrator | claude-sonnet-4.5 | Balance of capability/cost | +| Deep reasoning | claude-opus | Complex analysis, architecture | +| Quick tasks | claude-haiku | Fast, cheap for simple lookups | +| Code tasks | claude-sonnet | Good code understanding | + +### 2.4 Resource Limits (Guardrails) +Each subagent has strict limits: +- **Timeout:** Max wall-clock time (default: 600s) +- **Cost cap:** Max spend in cents (default: 50c) +- **Token cap:** Max total tokens (default: 100k) +- **Iteration cap:** Max agent loop iterations (default: 20) + +### 2.5 Extended Thinking +- Configurable per-subagent +- Enabled for deep research tasks +- Disabled for quick lookups + +## 3. Data Types + +```haskell +-- | Subagent role determines toolset and model +data SubagentRole + = WebCrawler -- Deep web research + | CodeReviewer -- Code analysis, PR review + | DataExtractor -- Structured data extraction + | Researcher -- General research with web+docs + | CustomRole Text -- User-defined role + deriving (Show, Eq, Generic) + +-- | Configuration for spawning a subagent +data SubagentConfig = SubagentConfig + { subagentRole :: SubagentRole + , subagentTask :: Text -- What to accomplish + , subagentModel :: Maybe Text -- Override default model + , subagentTimeout :: Int -- Seconds (default: 600) + , subagentMaxCost :: Double -- Cents (default: 50.0) + , subagentMaxTokens :: Int -- Default: 100000 + , subagentMaxIterations :: Int -- Default: 20 + , subagentExtendedThinking :: Bool + , subagentContext :: Maybe Text -- Additional context from orchestrator + } deriving (Show, Eq, Generic) + +-- | Result returned by subagent to orchestrator +data SubagentResult = SubagentResult + { subagentOutput :: Aeson.Value -- Structured result + , subagentSummary :: Text -- Human-readable summary + , subagentConfidence :: Double -- 0.0-1.0 confidence score + , subagentTokensUsed :: Int + , subagentCostCents :: Double + , subagentDuration :: Int -- Seconds + , subagentIterations :: Int + , subagentStatus :: SubagentStatus + } deriving (Show, Eq, Generic) + +data SubagentStatus + = SubagentSuccess + | SubagentTimeout + | SubagentCostExceeded + | SubagentError Text + deriving (Show, Eq, Generic) +``` + +## 4. Tool: spawn_subagent + +This is the main interface for the orchestrator to spawn subagents. + +```haskell +spawnSubagentTool :: Engine.Tool +spawnSubagentTool = Engine.Tool + { toolName = "spawn_subagent" + , toolDescription = + "Spawn a specialized subagent for a focused task. " + <> "Use for tasks that benefit from deep exploration, parallel execution, " + <> "or specialized tools. The subagent will iterate until task completion " + <> "or resource limits are reached." + , toolJsonSchema = ... + , toolExecute = executeSpawnSubagent + } +``` + +**Parameters:** +```json +{ + "role": "web_crawler | code_reviewer | data_extractor | researcher | custom", + "task": "Research competitor pricing for podcast transcription services", + "context": "We're building a pricing page and need market data", + "model": "claude-haiku", + "timeout": 600, + "max_cost_cents": 50, + "extended_thinking": false +} +``` + +**Response:** +```json +{ + "status": "success", + "summary": "Found 5 competitors with pricing ranging from $0.10-$0.25/min", + "output": { + "competitors": [ + {"name": "Otter.ai", "pricing": "$0.12/min", "features": ["..."]}, + ... + ] + }, + "confidence": 0.85, + "tokens_used": 45000, + "cost_cents": 23.5, + "duration_seconds": 180, + "iterations": 8 +} +``` + +## 5. Role-Specific Tool Sets + +### 5.1 WebCrawler +```haskell +webCrawlerTools :: [Engine.Tool] +webCrawlerTools = + [ webSearchTool -- Search the web + , webReaderTool -- Fetch and parse web pages + , pythonExecTool -- Execute Python for data processing + ] +``` +**Use case:** Deep market research, competitive analysis, documentation gathering + +### 5.2 CodeReviewer +```haskell +codeReviewerTools :: [Engine.Tool] +codeReviewerTools = + [ readFileTool + , searchCodebaseTool + , searchAndReadTool + , runBashTool -- For running tests, linters + ] +``` +**Use case:** PR review, architecture analysis, test verification + +### 5.3 DataExtractor +```haskell +dataExtractorTools :: [Engine.Tool] +dataExtractorTools = + [ webReaderTool + , pythonExecTool + ] +``` +**Use case:** Scraping structured data, parsing PDFs, extracting metrics + +### 5.4 Researcher +```haskell +researcherTools :: [Engine.Tool] +researcherTools = + [ webSearchTool + , webReaderTool + , readFileTool + , searchCodebaseTool + ] +``` +**Use case:** General research combining web and local codebase + +## 6. Subagent System Prompt Template + +``` +You are a specialized {ROLE} subagent working on a focused task. + +## Your Task +{TASK} + +## Context from Orchestrator +{CONTEXT} + +## Your Capabilities +{TOOL_DESCRIPTIONS} + +## Guidelines +1. Work iteratively: search → evaluate → refine → verify +2. Return structured data when possible (JSON objects) +3. Include confidence scores for your findings +4. If stuck, explain what you tried and what didn't work +5. Stop when you have sufficient information OR hit resource limits + +## Output Format +When complete, provide: +1. A structured result (JSON) with the requested data +2. A brief summary of findings +3. Confidence score (0.0-1.0) indicating reliability +4. Any caveats or limitations +``` + +## 7. Orchestrator Delegation Logic + +The orchestrator (Ava) should spawn subagents when: + +1. **Deep research needed:** "Research all competitors in X market" +2. **Parallel tasks:** Multiple independent subtasks that can run concurrently +3. **Specialized tools:** Task requires tools the orchestrator shouldn't use directly +4. **Token-intensive:** Task would consume excessive tokens in main context + +The orchestrator should NOT spawn subagents for: + +1. **Simple queries:** Quick lookups, single tool calls +2. **Conversation continuation:** Multi-turn dialogue with user +3. **Memory writes:** Tasks that need to update Ava's memory + +## 8. Execution Flow + +``` +1. Orchestrator calls spawn_subagent tool +2. Subagent module: + a. Creates fresh agent config from SubagentConfig + b. Selects model based on role (or override) + c. Builds tool list for role + d. Constructs system prompt + e. Calls Engine.runAgentWithProvider + f. Monitors resource usage + g. Returns SubagentResult +3. Orchestrator receives structured result +4. Orchestrator synthesizes into response +``` + +## 9. Concurrency Model + +Initial implementation: **Sequential** (one subagent at a time) + +Future enhancement: **Parallel** spawning with: +- `async` library for concurrent execution +- Aggregate cost tracking across all subagents +- Combined timeout for parallel group + +```haskell +-- Future: Parallel spawning +spawnParallel :: [SubagentConfig] -> IO [SubagentResult] +spawnParallel configs = mapConcurrently runSubagent configs +``` + +## 10. Status Reporting + +Subagents report status back to the orchestrator via callbacks: + +```haskell +data SubagentCallbacks = SubagentCallbacks + { onSubagentStart :: Text -> IO () -- "Starting web research..." + , onSubagentActivity :: Text -> IO () -- "Searching for X..." + , onSubagentToolCall :: Text -> Text -> IO () -- Tool name, args + , onSubagentComplete :: SubagentResult -> IO () + } +``` + +For Telegram, this appears as: +``` +🔍 Subagent [WebCrawler]: Starting research... +🔍 Subagent [WebCrawler]: Searching "podcast transcription pricing"... +🔍 Subagent [WebCrawler]: Reading otter.ai/pricing... +✅ Subagent [WebCrawler]: Complete (180s, $0.24) +``` + +## 11. Implementation Plan + +### Phase 1: Core Infrastructure +1. Create `Omni/Agent/Subagent.hs` with data types +2. Implement `runSubagent` function using existing Engine +3. Add `spawn_subagent` tool +4. Basic WebCrawler role with existing web tools + +### Phase 2: Role Expansion +1. Add CodeReviewer role +2. Add DataExtractor role +3. Add Researcher role +4. Custom role support + +### Phase 3: Advanced Features +1. Parallel subagent execution +2. Extended thinking integration +3. Cross-subagent context sharing +4. Cost aggregation and budgeting + +## 12. Testing Strategy + +```haskell +test :: Test.Tree +test = Test.group "Omni.Agent.Subagent" + [ Test.unit "SubagentConfig JSON roundtrip" <| ... + , Test.unit "role selects correct tools" <| ... + , Test.unit "timeout terminates subagent" <| ... + , Test.unit "cost limit stops execution" <| ... + , Test.unit "WebCrawler role has web tools" <| ... + ] +``` + +## 13. Cost Analysis + +Based on Anthropic's research findings: +- Subagents use ~15× more tokens than single-agent +- But provide better results for complex tasks +- 80% of performance variance from token budget + +**Budget recommendations:** +| Task Type | Subagent Budget | Expected Tokens | +|-----------|-----------------|-----------------| +| Quick lookup | $0.10 | ~10k | +| Standard research | $0.50 | ~50k | +| Deep analysis | $2.00 | ~200k | + +## 14. References + +- [Claude Agent SDK - Subagents](https://platform.claude.com/docs/en/agent-sdk/subagents) +- [Multi-Agent Research System](https://www.anthropic.com/engineering/multi-agent-research-system) +- [OpenAI Agents Python](https://openai.github.io/openai-agents-python/agents/) +- Existing: `Omni/Agent/Engine.hs`, `Omni/Agent/Provider.hs`, `Omni/Agent/Tools.hs` |
