Update SQLMesh for R2 data access & Convert psd data to gzip
This commit is contained in:
537
MULTIAGENT_SYSTEM_README.md
Normal file
537
MULTIAGENT_SYSTEM_README.md
Normal file
@@ -0,0 +1,537 @@
|
||||
# Multi-Agent System for Claude Code
|
||||
|
||||
A lean, pragmatic multi-agent system for software and data engineering tasks. Designed for small teams (1-2 people) building data products.
|
||||
|
||||
---
|
||||
|
||||
## Philosophy
|
||||
|
||||
**Simple, Direct, Procedural Code**
|
||||
- Functions over classes
|
||||
- Data-oriented design
|
||||
- Explicit over clever
|
||||
- Solve actual problems, not general cases
|
||||
|
||||
Inspired by Casey Muratori and Jonathan Blow's approach to software development.
|
||||
|
||||
---
|
||||
|
||||
## System Structure
|
||||
|
||||
```
|
||||
agent_system/
|
||||
├── README.md # This file
|
||||
├── coding_philosophy.md # Core principles (reference for all agents)
|
||||
├── orchestrator.md # Lead Engineer Agent
|
||||
├── code_analysis_agent.md # Code exploration agent
|
||||
├── implementation_agent.md # Code writing agent
|
||||
└── testing_agent.md # Testing agent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Agents
|
||||
|
||||
### 1. Orchestrator (Lead Engineer Agent)
|
||||
**File:** `orchestrator.md`
|
||||
|
||||
**Role:** Coordinates all work, decides when to use workers
|
||||
|
||||
**Responsibilities:**
|
||||
- Analyze task complexity
|
||||
- Decide: handle directly or spawn workers
|
||||
- Create worker specifications
|
||||
- Synthesize worker outputs
|
||||
- Make architectural decisions
|
||||
|
||||
**Use:** This is your main agent for Claude Code
|
||||
|
||||
### 2. Code Analysis Agent
|
||||
**File:** `code_analysis_agent.md`
|
||||
|
||||
**Role:** Explore and understand code (read-only)
|
||||
|
||||
**Responsibilities:**
|
||||
- Map code structure
|
||||
- Trace data flow
|
||||
- Identify patterns and issues
|
||||
- Answer specific questions about codebase
|
||||
|
||||
**Use:** When you need to understand existing code before making changes
|
||||
|
||||
### 3. Implementation Agent
|
||||
**File:** `implementation_agent.md`
|
||||
|
||||
**Role:** Write simple, direct code
|
||||
|
||||
**Responsibilities:**
|
||||
- Implement features
|
||||
- Modify existing code
|
||||
- Write SQLMesh models
|
||||
- Create Robyn routes
|
||||
- Build evidence.dev dashboards
|
||||
|
||||
**Use:** For building and modifying code
|
||||
|
||||
### 4. Testing Agent
|
||||
**File:** `testing_agent.md`
|
||||
|
||||
**Role:** Verify code works correctly
|
||||
|
||||
**Responsibilities:**
|
||||
- Write pytest tests
|
||||
- Create SQL test queries
|
||||
- Test data transformations
|
||||
- Validate edge cases
|
||||
|
||||
**Use:** For creating test suites
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
Task received
|
||||
↓
|
||||
Can I do this directly in <30 tool calls?
|
||||
↓
|
||||
YES → Handle directly (90% of tasks)
|
||||
NO → ↓
|
||||
↓
|
||||
Is this truly parallelizable?
|
||||
↓
|
||||
YES → Spawn 2-3 workers (10% of tasks)
|
||||
NO → Handle directly anyway
|
||||
```
|
||||
|
||||
**Golden Rule:** Most tasks should be handled directly by the orchestrator. Only use multiple agents when parallelization provides clear benefit.
|
||||
|
||||
### Example: Simple Task (Direct)
|
||||
|
||||
```
|
||||
User: "Add an API endpoint to get user activity"
|
||||
|
||||
Orchestrator: This is straightforward, <20 tool calls
|
||||
↓
|
||||
Handles directly:
|
||||
- Creates route in src/routes/activity.py
|
||||
- Queries data lake
|
||||
- Returns JSON
|
||||
- Tests manually
|
||||
- Done
|
||||
```
|
||||
|
||||
**No workers needed.** Fast and simple.
|
||||
|
||||
### Example: Complex Task (Multi-Agent)
|
||||
|
||||
```
|
||||
User: "Migrate ETL pipeline to SQLMesh"
|
||||
|
||||
Orchestrator: This is complex, will benefit from parallel work
|
||||
↓
|
||||
Phase 1 - Analysis:
|
||||
Spawns Code Analysis Agent
|
||||
- Maps existing pipeline
|
||||
- Identifies transformations
|
||||
- Documents dependencies
|
||||
→ Writes to .agent_work/analysis/
|
||||
↓
|
||||
Phase 2 - Implementation:
|
||||
Spawns 2 Implementation Agents in parallel
|
||||
- Agent A: Extract models
|
||||
- Agent B: Transform models
|
||||
→ Both write to .agent_work/implementation/
|
||||
↓
|
||||
Phase 3 - Testing:
|
||||
Spawns Testing Agent
|
||||
- Validates output correctness
|
||||
→ Writes to .agent_work/testing/
|
||||
↓
|
||||
Orchestrator synthesizes:
|
||||
- Reviews all outputs
|
||||
- Resolves conflicts
|
||||
- Creates migration plan
|
||||
- Done
|
||||
```
|
||||
|
||||
**Parallelization saves time** on truly complex work.
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
### Data Engineering
|
||||
- **SQLMesh** - Data transformation framework (SQL models)
|
||||
- **DuckDB** - Analytics database (OLAP queries)
|
||||
- **Iceberg** - Data lake table format (on R2 storage)
|
||||
- **ELT** - Extract → Load → Transform (in warehouse)
|
||||
|
||||
### SaaS Application
|
||||
- **Robyn** - Python web framework
|
||||
- Hosts landing page, auth, payment
|
||||
- Serves evidence.dev build at `/dashboard/`
|
||||
- **evidence.dev** - BI dashboards (SQL + Markdown → static site)
|
||||
|
||||
### Architecture
|
||||
```
|
||||
User → Robyn
|
||||
├── / (landing, auth, payment)
|
||||
├── /api/* (API endpoints)
|
||||
└── /dashboard/* (evidence.dev build)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Working Directory
|
||||
|
||||
All agent work goes into `.agent_work/` with feature-specific subdirectories:
|
||||
|
||||
```
|
||||
project_root/
|
||||
├── README.md # Architecture, setup, tech stack
|
||||
├── CLAUDE.md # Memory: decisions, patterns, conventions
|
||||
├── .agent_work/ # Agent work (add to .gitignore)
|
||||
│ ├── feature-user-dashboard/ # Feature-specific directory
|
||||
│ │ ├── project_state.md # Track this feature's progress
|
||||
│ │ ├── analysis/
|
||||
│ │ │ └── findings.md
|
||||
│ │ ├── implementation/
|
||||
│ │ │ ├── feature.py
|
||||
│ │ │ └── notes.md
|
||||
│ │ └── testing/
|
||||
│ │ ├── test_feature.py
|
||||
│ │ └── results.md
|
||||
│ └── feature-payment-integration/ # Another feature
|
||||
│ ├── project_state.md
|
||||
│ ├── analysis/
|
||||
│ ├── implementation/
|
||||
│ └── testing/
|
||||
├── models/ # SQLMesh models
|
||||
├── src/ # Application code
|
||||
└── tests/ # Final test suite
|
||||
```
|
||||
|
||||
**Workflow:**
|
||||
1. New feature → Create branch: `git checkout -b feature-name`
|
||||
2. Create `.agent_work/feature-name/` directory
|
||||
3. Track progress in `.agent_work/feature-name/project_state.md`
|
||||
4. Update global context in `README.md` and `CLAUDE.md` as needed
|
||||
|
||||
**Global vs Feature Context:**
|
||||
- **README.md**: Current architecture, tech stack, how to run
|
||||
- **CLAUDE.md**: Memory file - decisions, patterns, conventions to follow
|
||||
- **project_state.md**: Feature-specific progress (in `.agent_work/feature-name/`)
|
||||
|
||||
**Why `.agent_work/` instead of `/tmp/`:**
|
||||
- Persists across sessions
|
||||
- Easy to review agent work
|
||||
- Can reference with normal paths
|
||||
- Keep or discard as needed
|
||||
- Feature-scoped organization
|
||||
|
||||
**Add to `.gitignore`:**
|
||||
```
|
||||
.agent_work/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage in Claude Code
|
||||
|
||||
### Setting Up
|
||||
|
||||
1. Copy agent system files to your project:
|
||||
```
|
||||
mkdir -p .claude/agents/
|
||||
cp agent_system/* .claude/agents/
|
||||
```
|
||||
|
||||
2. Add to `.gitignore`:
|
||||
```
|
||||
.agent_work/
|
||||
```
|
||||
|
||||
3. Create `.agent_work/` directory:
|
||||
```
|
||||
mkdir -p .agent_work/{analysis,implementation,testing}
|
||||
```
|
||||
|
||||
### Using the Orchestrator
|
||||
|
||||
In Claude Code, load the orchestrator:
|
||||
|
||||
```
|
||||
@orchestrator.md
|
||||
|
||||
[Your request here]
|
||||
```
|
||||
|
||||
The orchestrator will:
|
||||
1. Analyze the task
|
||||
2. Decide if workers are needed
|
||||
3. Spawn workers if beneficial
|
||||
4. Handle directly if simple
|
||||
5. Synthesize results
|
||||
6. Deliver solution
|
||||
|
||||
### When Workers Are Spawned
|
||||
|
||||
The orchestrator automatically reads the appropriate agent file when spawning:
|
||||
|
||||
```
|
||||
Orchestrator reads: code_analysis_agent.md
|
||||
↓
|
||||
Creates specific task spec
|
||||
↓
|
||||
Spawns Code Analysis Agent with:
|
||||
- Agent instructions (from file)
|
||||
- Task specification
|
||||
- Output location
|
||||
↓
|
||||
Worker executes independently
|
||||
↓
|
||||
Writes to .agent_work/analysis/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Coding Philosophy
|
||||
|
||||
All agents follow these principles (from `coding_philosophy.md`):
|
||||
|
||||
### Core Principles
|
||||
1. **Functions over classes** - Use functions unless you truly need classes
|
||||
2. **Data is data** - Simple structures (dicts, lists), not objects hiding behavior
|
||||
3. **Explicit over implicit** - No magic, no hiding
|
||||
4. **Simple control flow** - Straightforward if/else, early returns
|
||||
5. **Build minimum that works** - Solve actual problem, not general case
|
||||
|
||||
### What to Avoid
|
||||
❌ Classes wrapping single functions
|
||||
❌ Inheritance hierarchies
|
||||
❌ Framework magic
|
||||
❌ Over-abstraction "for future flexibility"
|
||||
❌ Configuration as code pyramids
|
||||
|
||||
### What to Do
|
||||
✅ Write simple, direct functions
|
||||
✅ Make data transformations obvious
|
||||
✅ Handle errors explicitly
|
||||
✅ Keep business logic in SQL when possible
|
||||
✅ Think about performance
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Build Dashboard
|
||||
|
||||
**Request:** "Create dashboard showing user activity trends"
|
||||
|
||||
**Orchestrator Decision:** Moderate complexity, 2 independent tasks
|
||||
|
||||
**Execution:**
|
||||
1. Setup:
|
||||
- Create branch: `git checkout -b feature-user-dashboard`
|
||||
- Create `.agent_work/feature-user-dashboard/`
|
||||
- Read `README.md` and `CLAUDE.md` for context
|
||||
|
||||
2. Spawns Implementation Agent A
|
||||
- Creates SQLMesh model (user_activity_daily.sql)
|
||||
- Writes to `.agent_work/feature-user-dashboard/implementation-data/`
|
||||
|
||||
3. Spawns Implementation Agent B (parallel)
|
||||
- Creates evidence.dev dashboard
|
||||
- Writes to `.agent_work/feature-user-dashboard/implementation-viz/`
|
||||
|
||||
4. Orchestrator synthesizes
|
||||
- Reviews both outputs
|
||||
- Tests evidence build
|
||||
- Deploys together
|
||||
- Updates `.agent_work/feature-user-dashboard/project_state.md`
|
||||
|
||||
**Result:** Working dashboard with data model
|
||||
|
||||
### Example 2: Fix Bug
|
||||
|
||||
**Request:** "This query is timing out, fix it"
|
||||
|
||||
**Orchestrator Decision:** Simple, direct handling
|
||||
|
||||
**Execution:**
|
||||
1. Setup:
|
||||
- Create branch: `git checkout -b fix-query-timeout`
|
||||
- Create `.agent_work/fix-query-timeout/`
|
||||
|
||||
2. Orchestrator handles directly
|
||||
- Runs EXPLAIN ANALYZE
|
||||
- Identifies missing index
|
||||
- Creates index
|
||||
- Tests performance
|
||||
- Documents in `.agent_work/fix-query-timeout/project_state.md`
|
||||
|
||||
**Result:** Query now fast, documented
|
||||
|
||||
### Example 3: Large Refactor
|
||||
|
||||
**Request:** "Migrate 50 Python files from sync to async"
|
||||
|
||||
**Orchestrator Decision:** Complex, phased approach
|
||||
|
||||
**Execution:**
|
||||
1. Phase 1: Analysis
|
||||
- Code Analysis Agent maps dependencies
|
||||
- Identifies blocking calls
|
||||
- Writes to `.agent_work/analysis/`
|
||||
|
||||
2. Phase 2: Implementation (parallel)
|
||||
- Implementation Agent A: Core modules (20 files)
|
||||
- Implementation Agent B: API routes (15 files)
|
||||
- Implementation Agent C: Utils (15 files)
|
||||
- All write to `.agent_work/implementation/`
|
||||
|
||||
3. Phase 3: Testing
|
||||
- Testing Agent validates async behavior
|
||||
- Writes to `.agent_work/testing/`
|
||||
|
||||
4. Orchestrator synthesizes
|
||||
- Resolves conflicts
|
||||
- Integration testing
|
||||
- Migration plan
|
||||
|
||||
**Result:** Migrated codebase with tests
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For Orchestrator
|
||||
- Default to handling directly
|
||||
- Spawn workers only for truly parallel work
|
||||
- Give workers focused, non-overlapping tasks
|
||||
- Use extended thinking for planning
|
||||
- Document decisions in `project_state.md`
|
||||
|
||||
### For Worker Specs
|
||||
**Good:**
|
||||
```
|
||||
AGENT: implementation
|
||||
OBJECTIVE: Create SQLMesh model for user_activity_daily
|
||||
SCOPE: Create models/user_activity_daily.sql
|
||||
CONSTRAINTS: DuckDB SQL, incremental by date, partition by event_date
|
||||
OUTPUT: .agent_work/implementation/models/
|
||||
BUDGET: 20 tool calls
|
||||
```
|
||||
|
||||
**Bad:**
|
||||
```
|
||||
AGENT: implementation
|
||||
OBJECTIVE: Help with the data stuff
|
||||
```
|
||||
|
||||
### For Long Tasks
|
||||
- Maintain `.agent_work/project_state.md`
|
||||
- Update after each major phase
|
||||
- Use compaction if approaching context limits
|
||||
- Load files just-in-time (not entire codebase)
|
||||
|
||||
---
|
||||
|
||||
## Context Management
|
||||
|
||||
### Just-in-Time Loading
|
||||
|
||||
Don't load entire codebases:
|
||||
```bash
|
||||
# Good: Survey, then target
|
||||
find models/ -name "*.sql" | head -10
|
||||
rg "SELECT.*FROM" models/
|
||||
cat models/specific_model.sql
|
||||
|
||||
# Bad: Load everything
|
||||
cat models/*.sql
|
||||
```
|
||||
|
||||
### Project State Tracking
|
||||
|
||||
For long tasks (>50 turns), maintain state:
|
||||
|
||||
```markdown
|
||||
## Project: [Name]
|
||||
## Phase: [Current]
|
||||
|
||||
### Completed
|
||||
- [x] Task 1 - Agent - Outcome
|
||||
|
||||
### Current
|
||||
- [ ] Task 2 - Agent - Status
|
||||
|
||||
### Decisions
|
||||
1. Decision - Rationale
|
||||
|
||||
### Next Steps
|
||||
1. Step 1
|
||||
2. Step 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Workers are duplicating work"
|
||||
**Cause:** Vague task boundaries
|
||||
**Fix:** Be more specific, assign non-overlapping files
|
||||
|
||||
### "Coordination overhead too high"
|
||||
**Cause:** Task not parallelizable
|
||||
**Fix:** Handle directly, don't use workers
|
||||
|
||||
### "Context window exceeded"
|
||||
**Cause:** Loading too much data
|
||||
**Fix:** Use JIT loading, summarize outputs
|
||||
|
||||
### "Workers stepping on each other"
|
||||
**Cause:** Overlapping responsibilities
|
||||
**Fix:** Separate by file/module, clear boundaries
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**System:**
|
||||
- 4 agents: Orchestrator + 3 workers
|
||||
- Orchestrator handles most tasks directly (90%)
|
||||
- Workers used for truly complex, parallelizable work (10%)
|
||||
|
||||
**Philosophy:**
|
||||
- Simple, direct, procedural code
|
||||
- Data-oriented design
|
||||
- Functions over classes
|
||||
- Build minimum that works
|
||||
|
||||
**Tech Stack:**
|
||||
- Data: SQLMesh, DuckDB, Iceberg, ELT
|
||||
- SaaS: Robyn, evidence.dev
|
||||
- Testing: pytest, DuckDB SQL tests
|
||||
|
||||
**Working Directory:**
|
||||
- `.agent_work/` for all agent outputs
|
||||
- Add to `.gitignore`
|
||||
- Review, then move to final locations
|
||||
|
||||
**Golden Rule:** When in doubt, go simpler. Most tasks don't need multiple agents.
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Read `coding_philosophy.md` to understand principles
|
||||
2. Use `orchestrator.md` as your main agent in Claude Code
|
||||
3. Let orchestrator decide when to spawn workers
|
||||
4. Review outputs in `.agent_work/`
|
||||
5. Iterate based on results
|
||||
|
||||
Start simple. Add complexity only when needed.
|
||||
Reference in New Issue
Block a user