Skip to content

Commit 305dbda

Browse files
committed
agent patterns docs
1 parent ea2728d commit 305dbda

File tree

10 files changed

+776
-1688
lines changed

10 files changed

+776
-1688
lines changed

docs/mcp-agent-sdk/core-components/workflows.mdx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,34 @@ async def analyze_document_async(
7474
7575
## The Workflow Class
7676

77-
The `Workflow` class is the foundation for building complex agent behaviors. It provides:
78-
- Type-safe input/output handling
79-
- Automatic MCP tool registration
80-
- Support for both asyncio and Temporal execution
81-
- Built-in error handling and retries
82-
- Workflow state management
83-
84-
### Basic Workflow Definition
77+
The `Workflow[T]` base class lets you model multi-step or stateful logic while still exposing an MCP tool. Workflows are most useful when you need retries, shared state, or tight integration with the execution engine (asyncio or Temporal).
78+
79+
### Basic workflow definition
80+
81+
```python
82+
from mcp_agent.executor.workflow import Workflow, WorkflowResult
83+
84+
# Assume `read_file` / `summarise` are helper functions you provide.
85+
86+
@app.workflow
87+
class SummariseFile(Workflow[str]):
88+
@app.workflow_run
89+
async def run(self, path: str) -> WorkflowResult[str]:
90+
content = await read_file(path)
91+
summary = await summarise(content)
92+
return WorkflowResult(value=summary)
93+
```
94+
95+
Decorate the class with `@app.workflow` and the entry point with `@app.workflow_run`. Whatever you return from the method becomes the MCP tool result.
96+
97+
### Useful workflow features
98+
99+
- Access `self.context` for logging, MCP connections, and configuration.
100+
- Store reusable helpers or caches on `self` inside `__init__`.
101+
- Raise exceptions to trigger retries (Temporal) or propagate errors to the caller.
102+
- Combine with `@app.workflow_task` / `@app.workflow_signal` when you need durable activities or signal handlers.
103+
104+
See the sections below for more elaborate compositions.
85105

86106
## Workflow patterns (examples/workflows)
87107

Lines changed: 136 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,147 @@
11
---
2-
title: Build Your Own Pattern
3-
sidebarTitle: "Build Your Own"
4-
description: "Create custom agent workflow patterns"
2+
title: "Build Your Own Pattern"
3+
description: "Compose custom agent workflows from the core building blocks"
54
icon: wand-magic-sparkles
65
---
76

8-
<Info>
9-
Content to be added showing how to compose custom patterns from existing workflows.
10-
</Info>
7+
mcp-agent patterns are deliberately composable. You can mix routers, parallel fan-outs, evaluators, orchestrators, and plain Python callables to create flows that match your product requirements—without authoring new workflow classes.
118

12-
## Overview
9+
## Building blocks recap
1310

14-
All workflow patterns in mcp-agent are composable. You can combine them to create custom patterns tailored to your use case.
11+
- [`create_llm(...)`](https://github.com/lastmile-ai/mcp-agent/blob/main/src/mcp_agent/workflows/factory.py#L63) – wrap an `AgentSpec` in an AugmentedLLM tied to a provider (OpenAI, Anthropic, Azure, Google, Bedrock, Ollama).
12+
- [`create_router_llm(...)`](/mcp-agent-sdk/effective-patterns/router) / `create_router_embedding(...)` – dispatch requests to the best specialist.
13+
- [`create_intent_classifier_llm(...)`](/mcp-agent-sdk/effective-patterns/intent-classifier) – bucket requests before routing.
14+
- [`create_parallel_llm(...)`](/mcp-agent-sdk/effective-patterns/map-reduce) – run multiple workers in parallel and aggregate their outputs.
15+
- [`create_evaluator_optimizer_llm(...)`](/mcp-agent-sdk/effective-patterns/evaluator-optimizer) – iterate until a reviewer approves the response.
16+
- [`create_orchestrator(...)`](/mcp-agent-sdk/effective-patterns/planner) – break complex objectives into sequenced steps.
17+
- [`create_deep_orchestrator(...)`](/mcp-agent-sdk/effective-patterns/deep-research) – add knowledge extraction, policy engines, and budgets.
18+
- [`create_swarm(...)`](https://github.com/lastmile-ai/mcp-agent/blob/main/src/mcp_agent/workflows/factory.py#L501) – OpenAI/Anthropic-compatible handoffs between agents.
19+
- [`load_agent_specs_from_dir(...)`](https://github.com/lastmile-ai/mcp-agent/blob/main/src/mcp_agent/workflows/factory.py#L553) – hydrate agents from YAML/JSON specs.
1520

16-
## Example: Custom Pattern
21+
## Design playbook
22+
23+
1. **Model your specialists** as `AgentSpec` (name, instruction, tool access). Keep prompts short and behaviour-specific.
24+
2. **Pick a routing strategy**: intent classifier for lightweight gating, router for multi-skill dispatch, or orchestrator for complex plans.
25+
3. **Layer guardrails**: wrap high-risk steps in an evaluator-optimizer loop, or add policy agents inside an orchestrator step.
26+
4. **Add determinism**: integrate `fan_out_functions` for repeatable checks or use embedding routers for fixed scoring.
27+
5. **Expose the composition** with `@app.tool` / `@app.async_tool` so MCP clients can call it as a single tool.
28+
6. **Instrument** with the token counter (`await workflow.get_token_node()`) and tracing (`otel.enabled: true`) before shipping.
29+
30+
## Example: router ➝ parallel research ➝ evaluator
1731

1832
```python
19-
# Content to be added
33+
from mcp_agent.app import MCPApp
34+
from mcp_agent.workflows.factory import (
35+
AgentSpec,
36+
create_evaluator_optimizer_llm,
37+
create_parallel_llm,
38+
create_router_llm,
39+
)
40+
41+
app = MCPApp(name="composed_pattern")
42+
43+
# Cache long-lived components so we don't recreate them per request.
44+
router = None
45+
parallel_research = None
46+
research_loop = None
47+
48+
@app.async_tool(name="answer_question")
49+
async def answer(request: str) -> str:
50+
global router, parallel_research, research_loop
51+
async with app.run() as running_app:
52+
ctx = running_app.context
53+
54+
if router is None:
55+
router = await create_router_llm(
56+
name="triage",
57+
agents=[
58+
AgentSpec(name="qa", instruction="Answer factual questions concisely."),
59+
AgentSpec(
60+
name="analysis",
61+
instruction="Perform deep research with citations before answering.",
62+
),
63+
],
64+
provider="openai",
65+
context=ctx,
66+
)
67+
68+
if parallel_research is None:
69+
parallel_research = create_parallel_llm(
70+
name="research_parallel",
71+
fan_in=AgentSpec(
72+
name="aggregator",
73+
instruction="Blend researcher outputs into a single structured brief.",
74+
),
75+
fan_out=[
76+
AgentSpec(
77+
name="news",
78+
instruction="Search recent press releases.",
79+
server_names=["fetch"],
80+
),
81+
AgentSpec(
82+
name="financials",
83+
instruction="Lookup filings and key metrics.",
84+
server_names=["fetch"],
85+
),
86+
],
87+
context=ctx,
88+
)
89+
90+
if research_loop is None:
91+
research_loop = create_evaluator_optimizer_llm(
92+
name="research_with_qc",
93+
optimizer=parallel_research,
94+
evaluator=AgentSpec(
95+
name="editor",
96+
instruction=(
97+
"Score the brief from 1-5. Demand improvements if it lacks citations, "
98+
"actionable insights, or policy compliance."
99+
),
100+
),
101+
min_rating=4,
102+
max_refinements=3,
103+
context=ctx,
104+
)
105+
106+
decision = await router.route(request, top_k=1)
107+
top = decision[0]
108+
109+
if top.category == "agent" and top.result.name == "analysis":
110+
return await research_loop.generate_str(request)
111+
112+
if top.category == "agent":
113+
async with top.result:
114+
return await top.result.generate_str(request)
115+
116+
# Fallback: let the router destination handle it directly
117+
return await top.result.generate_str(request)
20118
```
21119

22-
[See Composition →](/mcp-agent-sdk/advanced/composition)
120+
Highlights:
121+
122+
- Router, parallel workflow, and evaluator are created once and reused across requests.
123+
- The evaluator-loop wraps the parallel workflow, so quality checks happen before the response leaves the system.
124+
- The entire composition is exposed as an MCP tool via `@app.async_tool`, making it callable from Claude, Cursor, or other MCP clients.
125+
126+
## Patterns that mix well
127+
128+
- **Intent classifier ➝ router**: Use the classifier for coarse gating (“is this support vs. billing?”) then route to specialists.
129+
- **Parallel ➝ evaluator**: Run multiple evaluators in parallel (policy, clarity, bias) and feed their combined verdict back to the optimizer.
130+
- **Orchestrator ➝ evaluator**: Wrap the final synthesis step in an evaluator loop so the orchestrator keeps iterating until the review passes.
131+
- **Router ➝ orchestrator**: Route strategic tasks to an orchestrator for deep execution, while simple tasks go to lightweight agents.
132+
- **Swarm handlers**: Use `create_swarm(...)` to hand off between agents mid-conversation, while still using MCP tools for capabilities.
133+
134+
## Operational tips
135+
136+
- **Share the context**: keep compositions inside `async with app.run()` so every component reuses the same `Context` (server registry, executor, secrets, tracing).
137+
- **Tune once, reuse everywhere**: store provider/model defaults in `mcp_agent.config.yaml`; override per pattern only when necessary.
138+
- **Observe everything**: `await workflow.get_token_node()` shows token spend for nested workflows; enable OTEL tracing to follow router choices, parallel branches, and evaluator scores.
139+
- **Blend deterministic helpers**: pass `fan_out_functions` or router `functions` for cheap heuristics (regex, lookups) alongside LLM-heavy steps.
140+
- **Think in tools**: once composed, wrap the entire pattern with `@app.tool` / `@app.async_tool` so it becomes an MCP tool. Other agents, orchestrators, or human operators can call it without knowing how it is assembled.
141+
142+
## Examples to study
143+
144+
- [workflow_orchestrator_worker](https://github.com/lastmile-ai/mcp-agent/tree/main/examples/workflows/workflow_orchestrator_worker) – combines routing, parallel tasks, and orchestration to grade student assignments.
145+
- [workflow_evaluator_optimizer](https://github.com/lastmile-ai/mcp-agent/tree/main/examples/workflows/workflow_evaluator_optimizer) – demonstrates evaluator loops, tool exposure, and cloud deployment.
146+
- [workflow_parallel](https://github.com/lastmile-ai/mcp-agent/tree/main/examples/workflows/workflow_parallel) – shows how to compose `AgentSpec`, AugmentedLLMs, and deterministic helpers inside one tool.
147+
- [Temporal examples](https://github.com/lastmile-ai/mcp-agent/tree/main/examples/temporal) – walk through exposing custom compositions as durable Temporal workflows.

0 commit comments

Comments
 (0)