Files
2026-07-29 10:59:18 +07:00

523 lines
13 KiB
Markdown

# Learning Path and Study Guide
## Overview
This guide helps you learn the Pi Agent architecture **top-down**, starting from high-level concepts to implementation details.
---
## Phase 1: Big Picture (1-2 hours)
### Goal: Understand how components fit together
### Resources
1. **01-ARCHITECTURE-OVERVIEW.md** - Read this first
2. **Diagrams** - Study the architecture diagrams
### Key Questions to Answer
✅ What are the two main layers?
✅ What does each layer do?
✅ How do messages flow through the system?
✅ What is the relationship between Agent and AgentHarness?
✅ What are the main event types?
✅ How do tools integrate with the agent?
✅ What is the purpose of hooks?
### Exercises
1. Draw the architecture diagram from memory
2. List 3 use cases for each hook type
3. Trace a message from input to LLM to output
---
## Phase 2: Core Agent (2-3 hours)
### Goal: Understand the low-level agent loop
### Resources
1. **02-AGENT-LOOP-DETAILED.md** - Study the agent loop
2. Read `src/agent-loop.ts` (skim, focus on comments)
3. Read `src/types.ts` - Understand AgentEvent, AgentMessage, AgentTool
### Key Concepts
- **runAgentLoop()** - Starts a new conversation
- **runAgentLoopContinue()** - Continues existing conversation
- **runLoop()** - Main iteration (outer and inner loops)
- **streamAssistantResponse()** - Streams LLM response
- **executeToolCalls()** - Executes tool calls
- **prepareToolCall()** - Validates and prepares tools
- **executePreparedToolCall()** - Executes tool with updates
- **finalizeExecutedToolCall()** - Finalizes with hooks
### Key Questions to Answer
✅ What's the difference between outer and inner loop?
✅ How does streaming work?
✅ How are tool calls executed (sequential vs parallel)?
✅ What happens when a tool is blocked?
✅ How are errors handled?
✅ What are the four phases of tool execution?
✅ How does the loop know when to stop?
### Exercises
1. Trace through a conversation with 1 prompt + 2 tool calls
2. Draw the outer/inner loop flow
3. Explain how abort signals propagate
4. Explain queue draining (steering/follow-up)
---
## Phase 3: Hooks System (2-3 hours)
### Goal: Understand how to customize agent behavior
### Resources
1. **03-HOOK-SYSTEM.md** - Study all hooks
2. Read `src/types.ts` - Hook types and contexts
### Hook Categories
**Message Transformation**:
- `convertToLlm` - Convert messages to LLM format
- `transformContext` - Manipulate context before LLM
**Lifecycle Hooks**:
- `beforeToolCall` - Block or modify tool execution
- `afterToolCall` - Override tool results
- `shouldStopAfterTurn` - Request early termination
- `prepareNextTurn` - Update context/model/thinking
**Queue Draining**:
- `getSteeringMessages` - Interrupt agent mid-work
- `getFollowUpMessages` - Queue messages for later
### Key Questions to Answer
✅ What hooks receive abort signals?
✅ What hooks can block execution?
✅ What is the execution order of hooks?
✅ What's the difference between beforeToolCall and afterToolCall?
✅ How do you implement context window management?
✅ How do you implement permission checks?
✅ What's the difference between steering and follow-up?
### Exercises
1. Implement a hook that logs all tool calls
2. Implement a hook that blocks dangerous commands
3. Implement a hook that summarizes conversation every 5 turns
4. Implement a hook that switches to high thinking for complex tasks
---
## Phase 4: AgentHarness (3-4 hours)
### Goal: Understand high-level API and session management
### Resources
1. **06-AGENTHARNESS-REFERENCE.md** - Study the harness API
2. Read `src/harness/agent-harness.ts` (focus on public methods)
### Key Concepts
- **Session** - Persistent conversation history
- **SessionTreeEntry** - Individual entries in conversation
- **Context Building** - Derive LLM context from session
- **Branching** - Create new conversation paths
- **Compaction** - Summarize old history
### API Methods
**Core**:
- `prompt()` - Run new conversation
- `skill()` - Execute skill
- `promptFromTemplate()` - Run template
**Queues**:
- `steer()` - Interrupt agent
- `followUp()` - Queue message
- `nextTurn()` - Queue for next turn
**Session**:
- `compact()` - Compress context
- `navigateTree()` - Branch conversation
**State**:
- `setModel()` - Change model
- `setThinkingLevel()` - Change reasoning level
- `setTools()` / `setActiveTools()` - Manage tools
### Key Questions to Answer
✅ What's the difference between steer() and followUp()?
✅ How does branching work?
✅ How does compaction work?
✅ What's the relationship between Session and SessionStorage?
✅ What's the difference between MessageEntry and CustomEntry?
✅ How are pending writes handled during active turns?
✅ What hooks does AgentHarness provide?
### Exercises
1. Create a session, add messages, and build context
2. Implement branching and navigate between branches
3. Implement compaction and verify it works
4. Set up hooks for tool call logging
---
## Phase 5: Session Architecture (2-3 hours)
### Goal: Understand persistence and tree structure
### Resources
1. **04-SESSION-ARCHITECTURE.md** - Study session system
2. Read `src/harness/session/session.ts`
### Key Concepts
- **SessionTreeEntry** - Tree nodes
- **Path Tracing** - From leaf to root
- **Context Building** - Projection to messages
- **Default Transform** - Compaction logic
- **Forking** - Create branches
### Key Questions to Answer
✅ How is conversation history stored?
✅ What's the difference between ID and parentId?
✅ How does the session know the current head?
✅ What entries appear in the LLM context?
✅ How does compaction work at the session level?
✅ What's the difference between fork and navigateTree()?
✅ How are custom entries different from messages?
### Exercises
1. Create a session and trace its tree
2. Add custom entries and verify they don't appear in context
3. Fork a session and compare contexts
4. Compact a session and verify size reduction
---
## Phase 6: Tool Execution (2-3 hours)
### Goal: Understand how tools work
### Resources
1. **05-TOOL-EXECUTION.md** - Study tool system
2. Read `src/harness/tools/` - Built-in tools
### Key Concepts
- **AgentTool** - Tool definition
- **Tool Execution Flow** - Prepare → Execute → Finalize
- **Sequential vs Parallel** - Execution modes
- **Streaming Updates** - Progress updates
- **Error Handling** - Throw vs return error
### Tool Execution Flow
```
prepareToolCall()
├─ Find tool
├─ Validate args
└─ beforeToolCall()
executePreparedToolCall()
└─ tool.execute()
finalizeExecutedToolCall()
└─ afterToolCall()
emitToolResult()
```
### Key Questions to Answer
✅ What's the difference between prepareArguments and execute?
✅ How do streaming updates work?
✅ When do you throw vs return an error?
✅ How are sequential vs parallel tools different?
✅ What's in the ToolContext passed to execute()?
✅ How do you handle long-running operations?
✅ What's the terminate flag for?
### Exercises
1. Implement a custom tool (e.g., weather API)
2. Implement streaming updates for long operation
3. Implement tool with error handling
4. Test sequential vs parallel execution
---
## Phase 7: Data Flow (2-3 hours)
### Goal: Understand how data flows through the system
### Resources
1. **07-DATA-FLOW-STATE.md** - Study data flow
2. Read `src/agent.ts` - State management
### Key Concepts
- **AgentMessage** - Unified message type
- **AgentEvent** - Event stream
- **AgentContext** - Snapshot for LLM
- **State Mutation** - How state changes on events
- **Queue Flow** - Steering and follow-up
### Key Questions to Answer
✅ How do messages flow from input to LLM?
✅ How is state mutated on events?
✅ What's the difference between AgentContext and AgentState?
✅ How do hooks transform data?
✅ How are abort signals propagated?
✅ What's the relationship between queue mode and draining?
✅ How are pending writes handled?
### Exercises
1. Trace a message through the entire flow
2. Trace a tool call through all hooks
3. Trace an abort through the system
4. Draw the complete data flow diagram
---
## Phase 8: Implementation (4-6 hours)
### Goal: Implement your own version
### Steps
1. **Design your data structures** (in Julia)
- AgentMessage equivalent
- AgentEvent equivalent
- AgentTool equivalent
2. **Implement core agent loop**
- Message streaming
- Tool execution
- Event emission
3. **Add hooks system**
- Hook registration
- Hook execution
- Return value handling
4. **Implement session persistence**
- Tree structure
- Entry types
- Context building
5. **Add harness layer**
- High-level API
- Queue management
- Branching
### Recommended Order
```
1. Data Types (2h)
├─ AgentMessage
├─ AgentEvent
└─ AgentTool
2. Core Loop (4h)
├─ streamAssistantResponse
├─ executeToolCalls
└─ runLoop
3. State Management (2h)
├─ AgentState
└─ Event handlers
4. Hooks (3h)
├─ Hook system
└─ Implement hooks
5. Session (4h)
├─ Tree structure
├─ Persistence
└─ Context building
6. Harness (4h)
├─ Public API
├─ Queue management
└─ Branching
```
### Tips
- Start simple, iterate
- Test each component
- Follow TypeScript patterns
- Use your language's idioms
---
## Quick Reference
### Agent Layer
| Function | Purpose |
|----------|---------|
| `runAgentLoop()` | Start new conversation |
| `runAgentLoopContinue()` | Continue existing |
| `runLoop()` | Main iteration |
| `streamAssistantResponse()` | Stream LLM |
| `executeToolCalls()` | Execute tools |
### AgentHarness Layer
| Method | Purpose |
|--------|---------|
| `prompt()` | Run conversation |
| `steer()` | Interrupt agent |
| `followUp()` | Queue message |
| `compact()` | Compress context |
| `navigateTree()` | Branch conversation |
### Hooks
| Hook | Purpose |
|------|---------|
| `convertToLlm` | Convert messages |
| `transformContext` | Manipulate context |
| `beforeToolCall` | Block tools |
| `afterToolCall` | Override results |
| `shouldStopAfterTurn` | Request stop |
| `prepareNextTurn` | Update config |
| `getSteeringMessages` | Interrupt |
| `getFollowUpMessages` | Queue for later |
### Entry Types
| Type | Purpose |
|------|---------|
| `message` | User/assistant/toolResult |
| `model_change` | Model switch |
| `thinking_level_change` | Reasoning level |
| `active_tools_change` | Tools change |
| `compaction` | History summary |
| `branch_summary` | Branch marker |
| `custom` | App data |
| `custom_message` | Custom message |
| `label` | User label |
| `leaf` | Current head |
---
## Common Patterns
### 1. Context Window Management
```typescript
transformContext: async (messages, signal) => {
if (estimateTokens(messages) > MAX_TOKENS) {
return pruneOldMessages(messages);
}
return messages;
}
```
### 2. Tool Permission Checks
```typescript
beforeToolCall: async ({ toolCall, args }, signal) => {
if (toolCall.name === "bash" && !await canExecute(args)) {
return { block: true, reason: "Permission denied" };
}
return undefined;
}
```
### 3. Streaming Updates
```typescript
execute: async (id, params, signal, onUpdate) => {
for await (const chunk of process()) {
onUpdate({ content: [{ type: "text", text: `Progress: ${chunk}%` }] });
}
return finalResult;
}
```
### 4. Branching
```typescript
const branchSession = await session.fork(leafId);
const branchHarness = new AgentHarness({ session: branchSession });
```
---
## Study Schedule
| Week | Focus | Hours |
|------|-------|-------|
| 1 | Phases 1-2 | 6-8 |
| 2 | Phases 3-4 | 8-10 |
| 3 | Phases 5-6 | 6-8 |
| 4 | Phase 7-8 | 8-10 |
**Total**: 28-36 hours
---
## Next Steps
After understanding the architecture:
1. **Implement in Julia**
- Start with data types
- Implement core loop
- Add hooks
- Implement session
2. **Extend Functionality**
- Add new tool types
- Implement custom hooks
- Add new entry types
3. **Optimize**
- Improve token estimation
- Optimize context pruning
- Parallelize operations
4. **Production**
- Error handling
- Logging
- Monitoring
---
## Questions to Test Understanding
1. How would you implement a tool that requires user approval?
2. How would you implement conversation summarization every 10 turns?
3. How would you implement context pruning based on importance?
4. How would you implement branching with automatic summaries?
5. How would you implement tool execution rate limiting?
---
## Summary
**Top-down learning**:
1. Big picture (layers, components)
2. Core agent (loop, streaming)
3. Hooks (customization)
4. Harness (session, persistence)
5. Data flow (how everything connects)
**Key insight**: The system is built on **messages** and **events** with hooks for customization.