Skip to content

# Module 2: Agent Architecture ​

## Lesson 2.1: The Four Pillars ​

Every agent system is built on four pillars:

    ┌─────────────────────────────────────────────────────────────┐
    │                      AGENT SYSTEM                           │
    ├──────────────┬──────────────┬──────────────┬────────────────┤
    │   TOOLS      │    LOOP      │   CONTEXT    │    MEMORY      │
    │ Capabilities │  Autonomy    │  Awareness   │  Persistence   │
    │              │              │              │                │
    │ • Read/Write │ • Think→Act  │ • System     │ • Mental       │
    │ • Bash       │ →Obs→Repeat  │   prompt     │   models       │
    │ • Search     │ • Iteration  │ • Messages   │ • Expertise    │
    │ • API calls  │   limits     │ • Tool       │   files        │
    │ • MCP        │ • Terminate  │   results    │ • Scratch      │
    │              │   conditions │ • Window     │   pads         │
    │              │              │   mgmt       │ • Session logs │
    └──────────────┴──────────────┴──────────────┴────────────────┘

- Tools define what the agent CAN do
- Loop defines WHEN the agent does it
- Context defines WHAT the agent knows right now
- Memory defines WHAT the agent remembers across sessions

## Lesson 2.2: Tool Design Patterns ​

### Tool Distribution Channels (from Beyond MCP research) ​

Channel | Context Cost | Portability | Auto-Discovery | Best For
--- | --- | --- | --- | ---
MCP Server | High (full context per call) | High | Yes (MCP protocol) | Multi-client, standardized tools
CLI | Medium | High | No | 80% of new tools, direct control
File System Scripts | Low (progressive disclosure) | Medium | No | Context-sensitive, portable
Skills | Low | Medium | Yes (skill dir) | Agent-native, behavior rules

### Tool Design Rules ​

1. Single responsibility: One tool = one capability. Don't make a Swiss Army knife tool.
2. Descriptive names: `search_web` not `sw`. `execute_sql_query` not `run`.
3. Rich descriptions: Tell the LLM WHEN to use each tool and WHAT it returns.
4. Parameter validation: Schema-enforce types, required fields, and constraints.
5. Output limits: Cap returns (2KB for logs, 10 results for search) to avoid context overflow.

### Advanced: Resource Mirror Pattern ​

Some MCP clients don't support Resources. The fix: every Resource gets a mirror Tool that returns identical data:

python

    # Resource: datasets://loaded  →  may not work in all clients
    # Mirror tool:
    @tool
    def list_loaded_datasets() -> str:
        """List all currently loaded datasets. Returns names and row counts."""
        return json.dumps(registry.list_datasets())

## Lesson 2.3: Agent Loop Variants ​

### Level 1: Simple Prompt → Execute ​

    LLM call → command string → execute → output

No loop. Single API call generates a command, you run it. Good for: code generation, translation, summarization.

### Level 2: Tool-Use Agent Loop ​

    while not terminal_tool_called:
        LLM(invoke with tools) → tool call → execute → feed result back

Core pattern. 5+ tools, forced tool choice. Terminal tool (e.g., `run_final_query`) exits. Good for: data analysis, file editing, web research.

### Level 3: Task-Completion Loop ​

    while not complete_task_tool_called:
        LLM → tool call → execute → observe → continue or complete

Adds explicit `complete_task` terminal action. Clear success/failure conditions. Good for: multi-step workflows with defined finish criteria.

### Level 4: Sub-Agent Orchestration ​

    main_agent → spawns sub_agents → collects results → synthesizes

Main agent calls LLM sub-calls for parallel work (e.g., check 10 files for relevance in parallel batches). Good for: codebase analysis, parallel research, batch operations.

### Level 5: Full Multi-Agent ​

    orchestrator → team_lead → worker_agents → results bubble up

Depth-2+ delegation hierarchy. Each agent has domain, tools, memory. Good for: production systems, complex workflows.

## Lesson 2.3b: Skills System Deep Dive ​

Skills are the building blocks of agent behavior. A skill is a self-contained instruction file that an agent loads and follows.

### Path-Scoped Skills ​

Skills can be scoped to specific directories. The agent only loads skills relevant to the files it's working on:

    repo/
    ├── .claude/skills/
    │   ├── global/
    │   │   ├── conversational-response.md
    │   │   └── security-policy.md
    │   ├── frontend/
    │   │   ├── react-patterns.md
    │   │   └── css-guidelines.md
    │   └── backend/
    │       ├── api-design.md
    │       └── database-migrations.md

### Subdirectory CLAUDE.md ​

One CLAUDE.md doesn't scale for large projects. Modern agents walk the directory tree and load the closest rules file:

    repo/
    ├── CLAUDE.md                    # Root rules (all agents)
    ├── frontend/CLAUDE.md           # Frontend overrides
    ├── backend/CLAUDE.md            # Backend overrides
    └── deploy/CLAUDE.md             # Deployment rules

### Plugin Distribution Model ​

Skills and agent configs can be packaged as shareable plugins:

    my-agent-kit/
    ├── agent.yaml                   # Agent definition
    ├── skills/                      # Skill files
    ├── tools/                       # Custom tools
    ├── hooks/                       # Lifecycle hooks
    └── README.md                    # Usage instructions

This is how ClaudeFAST distributes their 280 skills and 16 agents as commercial kits.

### LSP MCP Server Pattern ​

For large codebases, grep is too slow. An LSP (Language Server Protocol) MCP server gives agents symbol-level search:

    Agent → MCP Client → LSP MCP Server → Language Server → Codebase

Tools exposed: `find_definition`, `find_references`, `find_symbols`, `get_hover_info`

## Lesson 2.3c: Agent-Readable Workspace Design ​

An agent-readable workspace is organized so an agent can discover everything it needs without being told.

### The Discovery Pattern ​

    repo/
    ├── CLAUDE.md           ← Agent reads this FIRST
    ├── init.sh             ← Run this to set up environment
    ├── feature_list.json   ← What features exist, what's done
    ├── Makefile            ← Common commands (test, build, lint)
    ├── tests/              ← Expected outcomes (evidence)
    └── docs/               ← Architecture decisions (ADRs)

### Initialization as Its Own Phase ​

The first thing an agent should do is NOT start coding. It should initialize:

1. Read all instruction files (CLAUDE.md, AGENTS.md, skills)
2. Discover project structure (list files, read key configs)
3. Verify environment (check tool versions, API keys, dependencies)
4. Load state (mental models, session history, feature progress)
5. Plan before coding

### Feature Lists as Harness Primitives ​

A `feature_list.json` gives agents a structured inventory of what to build and what evidence proves completion:

json

    {
      "features": [
        {
          "id": "auth-login",
          "status": "done",
          "evidence": ["tests/test_auth.py::test_login", "src/auth/login.tsx"]
        },
        {
          "id": "auth-register",
          "status": "in_progress",
          "evidence": []
        }
      ]
    }

### Clean State Between Sessions ​

Every session must leave the workspace in a clean state:

- No half-finished files
- No dangling processes
- No uncommitted changes
- Session logs archived
- Temporary files cleaned

The next agent (or the same agent on the next session) should find the workspace as if no one touched it.

## Lesson 2.4: Context Window Management ​

### The Problem ​

Context windows grow unbounded. Every tool result, every LLM response, every intermediate step gets appended. After 20 turns of file editing, your context contains thousands of lines of file contents and logs.

### Solutions (from worst to best) ​

Approach | How | Trade-off
--- | --- | ---
Sliding window | Keep last N messages | Lose early context
Summarization | Compress old messages into summary | Information loss
Structured outputs | Agents output structured data, not free text | Requires schema design
Multi-agent isolation | Each agent has focused context window | Complexity, coordination cost

### Best Practice: Hybrid ​

    [System prompt (always)] + [Recent N turns (full)] + [Summary of earlier turns] + [Current tool results]

## Lesson 2.5: Memory Patterns ​

### Mental Models (from multi-team system) ​

Every agent maintains a personal expertise file:

yaml

    # .pi/multi-team/expertise/backend-dev-mental-model.yaml
    expertise:
      - topic: "API patterns used in this project"
        notes: "We use tRPC for type-safe API calls. All endpoints follow /api/trpc/{router}.{procedure}"
        last_updated: "2026-04-20"
      - topic: "Database conventions"
        notes: "SQLite with Drizzle ORM. Migrations in packages/db/src/migrations/"
        last_updated: "2026-04-22"

Rules:

- Agents own their mental models (they write them, not you)
- Read-only expertise for critical domain knowledge (billing, deployment, security)
- Self-improve commands validate expertise against actual codebase
- Mental models compound across sessions

### Scratch Pads ​

Ephemeral memory for a single session. Good for tracking:

- What's been tried and failed
- Current working state
- Decisions made this session

## Lesson 2.6: The Reasoning Parameter ​

Forcing the LLM to explain every tool call is the highest-ROI prompt engineering technique:

python

    def search_documentation(query: str, reasoning: str) -> str:
        """
        Search documentation.

        Args:
            query: The search terms
            reasoning: WHY you are searching for this (required for audit)
        """
        ...

Why it works:

1. Forces the LLM to articulate intent before acting
2. Creates an audit trail of every decision
3. Catches hallucinated tool calls (if the reasoning is nonsense, the call is suspect)
4. Gives the LLM an extra "thinking step" without using chain-of-thought

## Lesson 2.7: Codebase Architectures for Agents ​

From single-file-agents research, 4 patterns for scaling agent codebases:

Architecture | Structure | Best For
--- | --- | ---
Atomic/Composable | atom/ → molecule/ → organism/ | Reusable tool primitives across many agents
Layered | api/ → services/ → models/ → data/ | Clear separation of concerns within one agent
Pipeline | steps/ → pipeline_manager/ → shared/ | Data transformation flows
Vertical Slice | features/{feature}/{api,service,model}/ | Multiple independent agent capabilities

### Choosing the Right Architecture ​

There's no single right answer. The choice depends on your agent's role:

Agent Type | Recommended Arch | Why
--- | --- | ---
Single-purpose tool agent | Atomic | Simple, composable, testable
Multi-step workflow agent | Pipeline | Clear stage boundaries
Complex reasoning agent | Layered | Separation of concerns
Multi-capability platform | Vertical Slice | Independent feature teams

Rule of thumb: Start with Atomic (single file per tool). Only add architecture when the agent has 5+ tools or 3+ agents share tools.

## Module 2 Quiz ​

Quiz1 / 5

#### What are the four pillars of every agent system?

## Lesson 2.7b: Configuration Architecture ​

Where does agent configuration live? Three patterns:

### Pattern A: Flat Config (Single File) ​

yaml

    # agent-config.yaml — everything in one place
    agent:
      name: "code-reviewer"
      model: claude-sonnet-4
      tools: [read_file, grep_search, list_files]
      max_turns: 15
      hooks:
        - pre-tool/l3-blacklist
        - post-tool/logger

Best for: Single-agent projects, prototyping, small teams

### Pattern B: Layered Config (Directory Structure) ​

    agents/
    ├── base.yaml          ← shared defaults (model, security)
    ├── reviewer.yaml      ← extends base.yaml
    ├── builder.yaml       ← extends base.yaml
    └── orchestrator.yaml  ← extends base.yaml

Best for: Multi-agent systems, team environments

### Pattern C: Discoverable Config (Agent-Readable) ​

    repo/
    ├── AGENTS.md         ← agent instructions
    ├── skills/           ← skill definitions
    ├── .mcp.json         ← MCP server config
    ├── .claude/hooks/    ← lifecycle hooks
    └── teams.yaml        ← multi-team config

Best for: Production systems where agents need to self-configure

## Lesson 2.7c: Error Handling Architecture ​

Every agent needs four error-handling layers:

1. Tool-level: Tool returns error string instead of crashing (all labs teach this)
2. Loop-level: MAX_ITERATIONS prevents infinite loops (every lab has this)
3. Agent-level: Retry with backoff on API failures
4. System-level: Supervisor agent or human handoff for unrecoverable errors

python

    # System-level error handling pattern
    MAX_RETRIES = 3
    for attempt in range(MAX_RETRIES):
        try:
            response = client.messages.create(...)
            return process_response(response)
        except APIError as e:
            if attempt == MAX_RETRIES - 1:
                return {"error": "API unavailable after 3 retries", "fallback": "use cached result"}
            time.sleep(2 ** attempt)  # exponential backoff

## Lab 2.8: Multi-Tool Agent ​

Objective: Add file operations + web search tools to the agent from Lab 1.

Starter: `course/labs/L2-multi-tool/starter.py`
Solution: `course/labs/L2-multi-tool/solution.py`

## Lab 2.9: Context-Aware Agent ​

Objective: Implement sliding window + summarization for long sessions.

Starter: `course/labs/L2-context/starter.py`
Solution: `course/labs/L2-context/solution.py`