Understanding Agents

Agents are one of Amplifier's most powerful features for handling complex, multi-step tasks. They enable delegation, parallel execution, and specialized expertise—all while maintaining the simplicity of the bundle format you already know.

What is an Agent?

Key Insight: Agents ARE bundles. Same file format.

An agent is simply a bundle that gets spawned as a sub-session to handle a specific task. There's no special "agent format" to learn. If you can write a bundle, you can write an agent. The only difference is how it's used:

  • Bundle: Loaded into your current session, adds capabilities
  • Agent: Spawned as a separate sub-session, works independently
# Agent file -- uses meta: frontmatter
---
meta:
  name: code-reviewer
  description: |
    Expert code review agent that identifies quality issues, security
    vulnerabilities, and best practice violations...
---

You are a code review specialist. Analyze code for:
- Security vulnerabilities
- Performance issues
- Best practice violations
- Maintainability concerns

Note the meta: frontmatter block with name and description. This distinguishes agent files from bundle files, which use bundle: frontmatter with name and version. When you load this as a bundle, its instructions enhance your session. When you spawn it as an agent, it runs independently and reports back.

How Agents Work

Agents operate as isolated sub-sessions with their own context and tools:

┌─────────────────┐         ┌─────────────────┐
│  Main Session   │         │   Sub-Session   │
│     (you)       │         │    (agent)      │
│                 │         │                 │
│  ┌───────────┐  │  task   │  ┌───────────┐  │
│  │ Your      │──┼────────▶│  │ Agent     │  │
│  │ Context   │  │         │  │ Context   │  │
│  └───────────┘  │         │  └───────────┘  │
│                 │         │                 │
│  Continues...   │◀────────┼─ Final Report   │
│                 │  result │                 │
└─────────────────┘         └─────────────────┘

Key characteristics:

  1. Stateless: Each agent invocation starts fresh with no memory of previous calls
  2. Isolated: Agents have their own context window, separate from yours
  3. One-shot: You send instructions, they work, they report back once
  4. Autonomous: Agents decide how to accomplish the task you give them

The agent receives: - Your instruction (the task to perform) - Its own bundle configuration (instructions, tools, context) - Access to the filesystem and configured tools

The agent returns: - A single final report with results - No intermediate communication (they work autonomously)

Using Agents

Agents are invoked through the delegate tool with an instruction and agent identifier:

Use the delegate tool:
  agent: "foundation:code-reviewer"
  instruction: "Review the authentication module in src/auth/ for security issues"

Writing Effective Instructions

Since agents work autonomously with a single instruction, clarity is essential:

Good instruction:

Analyze src/api/handlers.py for security vulnerabilities.
Focus on: input validation, SQL injection, XSS risks.
Return: A list of issues with severity, line numbers, and fix suggestions.

Poor instruction:

Check the code.

Parallel Execution

One of the most powerful patterns is running multiple agents simultaneously:

# These run in parallel when called in the same message
delegate(agent="foundation:test-coverage", instruction="Analyze test coverage for src/auth/")
delegate(agent="foundation:security-guardian", instruction="Security audit of src/auth/")
delegate(agent="foundation:zen-architect", instruction="Review architecture of src/auth/")

All three agents work concurrently, dramatically reducing total time.

Context Control in Delegation

When delegating to an agent, you control what context it receives through two independent parameters:

context_depth -- HOW MUCH context to pass:

Value Meaning
"none" Clean slate. The agent starts with zero history.
"recent" Last N turns of conversation (configurable via context_turns).
"all" Full conversation history from the current session.

context_scope -- WHICH content to include:

Value Meaning
"conversation" User/assistant text only.
"agents" Conversation text plus results from previous delegate calls.
"full" Everything: conversation, delegate results, and all other tool results.

These parameters are independent. You can combine any depth with any scope:

delegate(
  agent="foundation:explorer",
  instruction="Map the authentication module structure",
  context_depth="recent",    # only last few turns
  context_scope="agents"     # include prior agent results
)

Choose the combination that gives the agent enough context to do its job without flooding it with irrelevant history. In most cases, "none" or "recent" with "conversation" is sufficient -- the instruction itself should carry the key details.

Session Resumption

By default, each delegation is stateless. But the delegate call returns a session_id that you can pass back to resume the same agent session with its accumulated context intact:

# First call -- agent explores the codebase
result = delegate(
  agent="foundation:explorer",
  instruction="Map the database module structure"
)
# result includes session_id

# Second call -- resume with follow-up question
delegate(
  session_id=result.session_id,
  instruction="Now trace how connection pooling works in that module"
)

This is useful for iterative refinement where each step builds on the previous agent's findings. The resumed session retains its full conversation history, so the agent remembers everything from prior exchanges.

Built-in Agents

Amplifier Foundation provides specialized agents for common development tasks:

Agent Purpose When to Use
foundation:zen-architect Architecture design and code planning Starting new features, system design
foundation:modular-builder Implementation from specifications Building code from architect specs
foundation:bug-hunter Systematic debugging Tracking down errors and failures
foundation:explorer Deep codebase reconnaissance Understanding unfamiliar code
foundation:test-coverage Test analysis and gap identification Ensuring adequate test coverage
foundation:security-guardian Security audits and vulnerability detection Pre-deployment security checks
foundation:git-ops Git and GitHub operations Commits, PRs, branch management
foundation:web-research Internet research and documentation lookup Finding external information
foundation:file-ops Precise file operations Batch file changes, targeted edits
foundation:integration-specialist External service integration API connections, MCP setup

Agent Selection Guidelines

Choose agents based on the task type:

  • Analysis tasksexplorer, test-coverage, security-guardian
  • Implementation tasksmodular-builder, file-ops
  • Design taskszen-architect
  • Debugging tasksbug-hunter
  • External tasksweb-research, integration-specialist

Creating Your Own Agents

Since agents are bundles, creating one follows the same file format. However, agents have formalized authoring requirements that ensure they are discoverable, self-describing, and effective when the system selects them for delegation.

Agent File vs Bundle File

Agent files use meta: frontmatter, while bundle files use bundle: frontmatter. This is the structural distinction:

# Agent file (.amplifier/agents/my-agent.md)
---
meta:
  name: my-custom-agent
  description: |
    (must be >100 words -- see requirements below)
---

Markdown body with instructions...
# Bundle file (.amplifier/bundles/my-bundle.md)
---
bundle:
  name: my-custom-bundle
  version: "1.0.0"
---

Markdown body with instructions...

The Description Requirement

The meta.description field is the most important part of an agent definition. It must be at least 100 words and follow the WHY/WHEN/WHAT/HOW structure:

  • WHY: What problem does this agent solve? What value does it provide?
  • WHEN: Activation triggers -- explicit conditions that should cause the parent agent to delegate to this agent. Use keywords like MUST, REQUIRED, ALWAYS, PROACTIVELY, "Use when...".
  • WHAT: Domain/Taxonomy Terms -- keywords and concepts the agent is authoritative on. Use the pattern: **Authoritative on:** term1, term2, term3, "multi-word concept". This serves as the agent's taxonomy -- terms that should trigger delegation.
  • HOW: Usage Examples -- concrete <example> blocks with <commentary> tags showing user request to delegation rationale.

The description must include all four elements. The Authoritative on: line is critical for discoverability -- it lists the domain terms that help the system match tasks to agents:

meta:
  name: bug-hunter
  description: |
    Specialized debugging expert focused on finding and fixing bugs
    systematically. Use PROACTIVELY when the user has reported or you
    are encountering errors, unexpected behavior, or test failures.

    **Authoritative on:** debugging, stack traces, error reproduction,
    root cause analysis, hypothesis-driven debugging, test failures

    <example>
    Context: User reports an error
    user: 'The synthesis pipeline is throwing a KeyError somewhere'
    assistant: 'I will use the bug-hunter agent to systematically
    track down and fix this KeyError.'
    <commentary>
    The bug-hunter uses hypothesis-driven debugging to efficiently
    locate and resolve issues.
    </commentary>
    </example>

    <example>
    Context: Tests are failing
    user: 'Tests are failing after the recent changes'
    assistant: 'Let me use the bug-hunter agent to investigate and
    fix the test failures.'
    <commentary>
    Perfect for methodical debugging without adding unnecessary
    complexity.
    </commentary>
    </example>

A description that is too short, lacks trigger conditions, or omits examples will make the agent invisible to the delegation system. The description is what the parent agent reads when deciding whether to delegate -- it must sell the agent's relevance to the task at hand.

Agents as Context Sinks

A key architectural benefit of agents is that they act as context sinks. When an agent's instructions reference heavy documentation via @mentions, those files load into the agent's context window -- not the parent session's. This is the primary mechanism for keeping the parent session lean:

  • The parent sees only the agent's description (a few hundred tokens).
  • The agent absorbs all the heavy context it needs (potentially tens of thousands of tokens) in its own isolated session.
  • The agent returns a concise summary (~500 tokens) back to the parent.

This means you should not hesitate to @mention large reference documents in agent instructions. The cost is borne by the agent's context, not yours.

Adding Tools and Context

Tools and context files are added in the frontmatter or via includes, the same way as bundles:

---
meta:
  name: my-custom-agent
  description: |
    ...

tools:
  - tool-bash
  - tool-files
  - tool-grep

context:
  include:
    - ./domain-knowledge.md
    - ./coding-standards.md
---

Agent Design Best Practices

  1. Write the description first: The >100-word WHY/WHEN/WHAT/HOW description with examples is the most important artifact. Write it before anything else.
  2. Single responsibility: Each agent should excel at one thing.
  3. Clear output contract: Define what the agent should return.
  4. Appropriate tools: Only include tools the agent actually needs.
  5. Use @mentions for heavy context: Let the agent absorb reference material in its own context window rather than inlining it.
  6. Include concrete examples: The <example> tags in the description are not optional decoration -- they are how the system learns when to delegate.

Agents vs Bundles

Understanding when to use each:

Aspect Bundle Agent
Loading Into current session As separate sub-session
Context Shares your context Has its own context
Interaction Continuous, conversational One-shot task/report
Best for Adding capabilities Delegating tasks
Memory Persists in session Stateless per invocation
Parallelism N/A Can run multiple simultaneously

When to Use Bundles

  • Adding tools and capabilities to your session
  • Loading persistent context (coding standards, domain knowledge)
  • Enhancing the main agent's abilities
  • When you need conversational back-and-forth

When to Use Agents

  • Delegating specific, well-defined tasks
  • Running multiple analyses in parallel
  • Isolating complex work from your main context
  • When the task can be described in a single instruction

The Same File, Two Uses

The same markdown file can serve both purposes depending on how it is loaded. An agent file uses meta: frontmatter, a bundle file uses bundle: frontmatter, but a single file can function as either:

# code-quality.md
---
meta:
  name: code-quality
  description: |
    Code quality analysis agent. Use PROACTIVELY when reviewing code
    for quality issues, style violations, and maintainability concerns.

    **Authoritative on:** code quality, linting, style, maintainability

    <example>
    user: 'Review src/api/ for code quality'
    assistant: 'I will delegate to code-quality for analysis.'
    <commentary>Quality review triggers this agent.</commentary>
    </example>
---

You are a code quality specialist. Analyze code for:
- Style violations
- Maintainability concerns
- Complexity issues
  • As bundle: amplifier run --bundle ./code-quality.md "prompt" -- Adds quality analysis to your session
  • As agent: delegate(agent="code-quality", ...) -- Spawns quality analyzer

Advanced Patterns

Chained Agents

Use one agent's output as input for another:

1. zen-architect analyzes and creates spec
2. modular-builder implements from spec  
3. test-coverage verifies implementation
4. security-guardian audits result

Specialist Teams

Create domain-specific agent teams:

# Your collection could include:
agents:
  - api-designer      # Designs REST APIs
  - schema-validator  # Validates data schemas
  - docs-generator    # Generates documentation

Context Handoff

Pass relevant context in your instruction, and use context_depth / context_scope to control how much session history the agent inherits:

delegate(
  agent="foundation:security-guardian",
  instruction: |
    Review the following code changes:

    Files modified: src/auth.py, src/session.py
    PR description: Adds JWT token refresh
    Related issue: #142

    Focus on security implications of the token handling.
  context_depth="none",        # agent does not need our history
  context_scope="conversation"
)

For iterative workflows, use session resumption to build on prior results:

# Round 1: broad analysis
r1 = delegate(agent="foundation:zen-architect", instruction="Analyze src/api/")

# Round 2: drill into findings (resumes the same agent session)
r2 = delegate(session_id=r1.session_id, instruction="Expand on the coupling issue you found")

Key Takeaways

  1. Agents ARE bundles -- Same file format, different execution model. Agent files use meta: frontmatter; bundle files use bundle: frontmatter.

  2. The description is the contract -- meta.description must be >100 words and follow WHY/WHEN/WHAT/HOW with concrete <example> tags. This is how the system decides when to delegate.

  3. Agents are context sinks -- Heavy @mentioned docs load in the agent's context, not the parent's. This keeps the parent session lean.

  4. Two knobs for context -- context_depth (how much) and context_scope (which content) are independent parameters that control what the agent inherits.

  5. Session resumption enables iteration -- Pass session_id back to delegate to continue where a previous agent left off.

  6. Delegation, not conversation -- Send clear instructions, get back reports.

  7. Parallelism is powerful -- Run multiple agents simultaneously for speed.

  8. Single responsibility -- Best agents do one thing exceptionally well.

  9. Built-in agents cover common needs -- Use Foundation agents before building custom.


Next Steps