amplifier-foundation Examples¶
Progressive examples demonstrating how to use amplifier-foundation, from basic concepts to production applications.
Learning Paths¶
-
For Beginners
- Hello World - See it work (2 min)
- Custom Configuration - Composition (5 min)
- Custom Tool - Build capabilities (10 min)
-
For Builders
- CLI Application - Best practices (15 min)
- Multi-Agent System - Complex systems (30 min)
Examples Catalog¶
| Example | Time | Complexity | Key Concepts |
|---|---|---|---|
| Hello World | 2 min | ⭐ Beginner | Bundle loading, composition, execution |
| Custom Configuration | 5 min | ⭐ Beginner | Composition patterns, adding tools |
| Custom Tool | 10 min | ⭐⭐ Intermediate | Tool protocol, registration |
| CLI Application | 15 min | ⭐⭐ Intermediate | App architecture, error handling |
| Multi-Agent System | 30 min | ⭐⭐⭐ Advanced | Agent workflows, orchestration |
Running Examples¶
All examples are in the amplifier-foundation repository:
# Clone the repo
git clone https://github.com/microsoft/amplifier-foundation
cd amplifier-foundation
# Set API key
export ANTHROPIC_API_KEY='your-key-here'
# Run any example
uv run python examples/01_hello_world.py
uv run python examples/02_custom_configuration.py
uv run python examples/03_custom_tool.py
uv run python examples/08_cli_application.py
uv run python examples/09_multi_agent_system.py
Example Summaries¶
Hello World¶
Your first Amplifier agent in ~15 lines of code.
What you learn: - Load and compose bundles - Prepare modules for execution - Create and execute sessions
Key code:
foundation = await load_bundle(foundation_path)
provider = await load_bundle(provider_path)
composed = foundation.compose(provider)
prepared = await composed.prepare()
session = await prepared.create_session()
response = await session.execute("Your prompt")
Custom Configuration¶
Tailor agents via composition.
What you learn: - Add tools to your agent - Use streaming orchestrators - Customize behavior through composition
Key concept: Composition over configuration - swap capabilities, not flags.
Custom Tool¶
Build domain-specific capabilities.
What you learn: - Tool protocol (name, description, input_schema, execute()) - Integrating custom capabilities - Protocol-based design (no inheritance required)
Key code:
class WeatherTool:
@property
def name(self) -> str:
return "get_weather"
async def execute(self, input: dict) -> ToolResult:
return ToolResult(success=True, output="weather data")
CLI Application¶
Production-quality CLI application architecture.
What you learn: - Configuration management - Logging and error handling - Session lifecycle management - Application patterns
Key patterns: - Load-Prepare-Execute flow - Graceful error handling - Configuration resolution - Reusable application classes
Multi-Agent System¶
Coordinate specialized agents for complex workflows.
What you learn: - Define agents with different tools and instructions - Sequential workflows (design → implement → review) - Parallel execution patterns - Context passing between agents
Key architecture:
# Agent 1: Architect - designs system
architect = Bundle(name="architect", tools=[...], instruction="...")
# Agent 2: Implementer - writes code
implementer = Bundle(name="implementer", tools=[...], instruction="...")
# Agent 3: Reviewer - checks quality
reviewer = Bundle(name="reviewer", tools=[...], instruction="...")
Additional Examples¶
Tier 2: Foundation Concepts (04-07)¶
Goal: Understand how Amplifier works internally
- 04_load_and_inspect.py - Learn how
load_bundle()works and what a bundle contains - 05_composition.py - Understand how
compose()merges configuration - 06_sources_and_registry.py - Learn source formats and BundleRegistry
- 07_full_workflow.py - See the complete preparation and execution flow
Tier 4: Real-World Applications (10-21)¶
Goal: Practical use cases and advanced patterns
- 10_meeting_notes_to_actions.py - Text processing workflow
- 11_provider_comparison.py - Compare LLM providers
- 12_approval_gates.py - Human-in-the-loop patterns
- 13_event_debugging.py - Session observability
- 14_session_persistence.py - Save and restore sessions
- 17_multi_model_ensemble.py - Ensemble patterns
- 18_custom_hooks.py - Build custom hooks
- 19_github_actions_ci.py - CI/CD integration
- 20_calendar_assistant.py - External API integration
- 21_bundle_updates.py - Bundle update detection
Troubleshooting¶
"Module not found" Error¶
Modules need source fields so prepare() can download them:
First Run Takes 30+ Seconds¶
This is normal - modules are downloaded from GitHub and cached in ~/.amplifier/cache/. Subsequent runs are fast.
"API key error"¶
Set your provider's API key:
Path Issues¶
Examples assume you're running from the amplifier-foundation directory:
If path errors occur, check that Path(__file__).parent.parent resolves to the amplifier-foundation directory.
Key Concepts¶
Bundles¶
Composable configuration units that produce mount plans for AmplifierSession. A bundle specifies which modules to load, how to configure them, and what instructions to provide.
bundle = Bundle(
name="my-agent",
providers=[...], # LLM backends
tools=[...], # Capabilities
hooks=[...], # Observability
instruction="..." # System prompt
)
Composition¶
Combine bundles to create customized agents. Later bundles override earlier ones, allowing progressive refinement.
foundation = await load_bundle("foundation")
custom = Bundle(name="custom", tools=[...])
composed = foundation.compose(custom) # custom overrides foundation
Preparation¶
Download and activate all modules before execution. The prepare() method resolves module sources (git URLs, local paths) and makes them importable.
prepared = await composed.prepare() # Downloads modules if needed
session = await prepared.create_session()
Module Sources¶
Specify where to download modules from. Every module needs a source field for prepare() to resolve it.
tools=[
{
"module": "tool-filesystem",
"source": "git+https://github.com/microsoft/amplifier-module-tool-filesystem@main"
}
]
Tool Protocol¶
Custom tools implement a simple protocol - no inheritance required:
class MyTool:
@property
def name(self) -> str:
return "my-tool"
@property
def description(self) -> str:
return "What this tool does..."
@property
def input_schema(self) -> dict:
return {
"type": "object",
"properties": {
"param": {"type": "string"}
},
"required": ["param"]
}
async def execute(self, input: dict) -> ToolResult:
return ToolResult(success=True, output="result")
Architecture Principles¶
Composition Over Configuration¶
Amplifier favors swapping modules over toggling flags. Want streaming? Use orchestrator: loop-streaming. Want different tools? Compose a different tool bundle. No complex configuration matrices.
Protocol-Based¶
Tools, providers, hooks, and orchestrators implement protocols (duck typing), not base classes. No framework inheritance required - just implement the interface.
Explicit Sources¶
Module sources are explicit in configuration. No implicit discovery or magic imports. If you need a module, specify where it comes from: git repository, local path, or package name.
Preparation Phase¶
Modules are resolved and downloaded before execution (prepare()), not during runtime. This ensures deterministic behavior and clear error messages.
Next Steps¶
- Core Concepts - Mental model for bundles
- Bundle System Deep Dive - Complete bundle authoring guide
- Common Patterns - Practical usage patterns
- API Reference - Complete API documentation