Overview
Fast Agent provides decorators for defining agents directly in Python code. All decorators are methods on the FastAgent class and are used to register agent configurations.
Basic Agent Types
@agent()
Decorator to create a standard agent with basic capabilities.
@fast.agent(
name: str = "default",
instruction: str | Path | AnyUrl = DEFAULT_AGENT_INSTRUCTION,
agents: list[str] | None = None,
servers: list[str] = [],
tools: dict[str, list[str]] | None = None,
resources: dict[str, list[str]] | None = None,
prompts: dict[str, list[str]] | None = None,
skills: SkillConfig = SKILLS_DEFAULT,
function_tools: FunctionToolsConfig = None,
model: str | None = None,
use_history: bool = True,
request_params: RequestParams | None = None,
human_input: bool = False,
default: bool = False,
elicitation_handler: ElicitationFnT | None = None,
api_key: str | None = None,
history_source: Any | None = None,
history_merge_target: Any | None = None,
max_parallel: int | None = None,
child_timeout_sec: int | None = None,
max_display_instances: int | None = None,
)
Base instruction for the agent. Can be a string, path to a file, or URL. Supports templates like {{currentDate}}, {{url:...}}, {{file:...}}
List of child agent names to attach via Agents-as-Tools
List of MCP server names the agent should connect to
tools
dict[str, list[str]] | None
Map of server names to tool name patterns to include
resources
dict[str, list[str]] | None
Map of server names to resource name patterns to include
prompts
dict[str, list[str]] | None
Map of server names to prompt name patterns to include
skills
SkillConfig
default:"SKILLS_DEFAULT"
Skills configuration for the agent
List of Python function tools to include (e.g., ["tools.py:my_function"])
Model specification string (e.g., "openai:gpt-4", "anthropic:claude-3-5-sonnet-20241022")
Whether to maintain conversation history
Additional request parameters for the LLM (temperature, max_tokens, etc.)
Whether to enable human input capabilities
Whether to mark this as the default agent for the application
Custom elicitation handler function for processing user inputs
Optional API key for the LLM provider (overrides environment variables)
Source for conversation history in Agents-as-Tools scenarios
Target for merging conversation history in Agents-as-Tools scenarios
Maximum number of parallel child agent invocations for Agents-as-Tools
Timeout in seconds for child agent tool calls
Maximum number of child agent instances to display in progress updates
Example
from fast_agent import FastAgent
fast = FastAgent("my-app")
@fast.agent(
name="assistant",
instruction="You are a helpful AI assistant.",
servers=["filesystem"],
model="anthropic:claude-3-5-sonnet-20241022",
default=True
)
async def assistant():
pass
# With function tools
@fast.agent(
name="calculator",
instruction="Perform calculations using provided tools.",
function_tools=["tools.py:add", "tools.py:multiply"]
)
async def calculator():
pass
@smart()
Decorator to create a smart agent with enhanced reasoning capabilities. Uses extended system instructions optimized for complex problem-solving.
@fast.smart(
name: str = "default",
instruction: str | Path | AnyUrl = SMART_AGENT_INSTRUCTION,
# ... same parameters as @agent()
)
Parameters are identical to @agent(), but the default instruction is optimized for advanced reasoning.
Example
@fast.smart(
name="analyst",
instruction="Analyze data and provide insights.",
servers=["database", "analytics"]
)
async def analyst():
pass
@custom()
Decorator to create a custom agent using a user-defined agent class.
@fast.custom(
cls, # Custom agent class
name: str = "default",
instruction: str | Path | AnyUrl = "You are a helpful agent.",
agents: list[str] | None = None,
servers: list[str] = [],
tools: dict[str, list[str]] | None = None,
resources: dict[str, list[str]] | None = None,
prompts: dict[str, list[str]] | None = None,
skills: SkillConfig = SKILLS_DEFAULT,
model: str | None = None,
use_history: bool = True,
request_params: RequestParams | None = None,
human_input: bool = False,
default: bool = False,
elicitation_handler: ElicitationFnT | None = None,
api_key: str | None = None,
)
Custom agent class that implements the agent protocol
Other parameters match @agent().
Example
from fast_agent.interfaces import AgentProtocol
class MyCustomAgent(AgentProtocol):
async def send(self, message, **kwargs):
# Custom implementation
return "Custom response"
@fast.custom(
MyCustomAgent,
name="custom",
instruction="Custom agent behavior"
)
async def custom_agent():
pass
Workflow Decorators
@orchestrator()
Decorator to create an orchestrator agent that plans and executes tasks using child agents.
@fast.orchestrator(
name: str,
agents: list[str], # Required
instruction: str | Path | AnyUrl = DEFAULT_INSTRUCTION_ORCHESTRATOR,
model: str | None = None,
request_params: RequestParams | None = None,
use_history: bool = False,
human_input: bool = False,
plan_type: Literal["full", "iterative"] = "full",
plan_iterations: int = 5,
default: bool = False,
api_key: str | None = None,
)
List of child agent names the orchestrator can delegate to
plan_type
Literal['full', 'iterative']
default:"full"
Planning approach: “full” for upfront planning, “iterative” for step-by-step
Maximum number of planning iterations
Example
@fast.orchestrator(
name="coordinator",
agents=["researcher", "writer", "reviewer"],
plan_type="iterative",
plan_iterations=10
)
async def coordinator():
pass
@iterative_planner()
Decorator to create an iterative planner agent that plans and executes tasks step-by-step.
@fast.iterative_planner(
name: str,
agents: list[str], # Required
instruction: str | Path | AnyUrl = ITERATIVE_PLAN_SYSTEM_PROMPT_TEMPLATE,
model: str | None = None,
request_params: RequestParams | None = None,
plan_iterations: int = -1, # -1 = unlimited
default: bool = False,
api_key: str | None = None,
)
Maximum number of planning iterations (-1 for unlimited)
Example
@fast.iterative_planner(
name="adaptive_planner",
agents=["data_collector", "analyzer", "reporter"],
plan_iterations=-1 # No limit
)
async def adaptive_planner():
pass
@router()
Decorator to create a router agent that selects the appropriate child agent based on the request.
@fast.router(
name: str,
agents: list[str], # Required
instruction: str | Path | AnyUrl | None = None, # Defaults to ROUTING_SYSTEM_INSTRUCTION
servers: list[str] = [],
tools: dict[str, list[str]] | None = None,
resources: dict[str, list[str]] | None = None,
prompts: dict[str, list[str]] | None = None,
model: str | None = None,
use_history: bool = False,
request_params: RequestParams | None = None,
human_input: bool = False,
default: bool = False,
elicitation_handler: ElicitationFnT | None = None,
api_key: str | None = None,
)
List of agent names the router can select from
Example
@fast.router(
name="request_router",
agents=["support_agent", "sales_agent", "technical_agent"]
)
async def request_router():
pass
@chain()
Decorator to create a chain agent that executes child agents in sequence.
@fast.chain(
name: str,
sequence: list[str], # Required
instruction: str | Path | AnyUrl | None = None,
cumulative: bool = False,
default: bool = False,
)
List of agent names to execute in order
If True, each agent sees all previous responses; if False, only the previous response
Example
@fast.chain(
name="content_pipeline",
sequence=["researcher", "writer", "editor", "publisher"],
cumulative=True
)
async def content_pipeline():
pass
@parallel()
Decorator to create a parallel agent that executes multiple child agents simultaneously.
@fast.parallel(
name: str,
fan_out: list[str], # Required
fan_in: str | None = None,
instruction: str | Path | AnyUrl | None = None,
include_request: bool = True,
default: bool = False,
)
List of agent names to execute in parallel
Optional agent name to aggregate the parallel results
Whether to include the original request when aggregating results
Example
@fast.parallel(
name="multi_analyzer",
fan_out=["sentiment_analyzer", "topic_classifier", "entity_extractor"],
fan_in="result_aggregator",
include_request=True
)
async def multi_analyzer():
pass
@evaluator_optimizer()
Decorator to create an evaluator-optimizer agent that iteratively refines responses.
@fast.evaluator_optimizer(
name: str,
generator: str, # Required
evaluator: str, # Required
instruction: str | Path | AnyUrl | None = None,
min_rating: str = "GOOD",
max_refinements: int = 3,
refinement_instruction: str | None = None,
default: bool = False,
)
Name of the agent that generates initial responses
Name of the agent that evaluates response quality
Minimum acceptable quality rating (EXCELLENT, GOOD, FAIR, POOR)
Maximum number of refinement iterations
Custom instruction for refinement iterations
Example
@fast.evaluator_optimizer(
name="quality_writer",
generator="draft_writer",
evaluator="content_critic",
min_rating="EXCELLENT",
max_refinements=5
)
async def quality_writer():
pass
@maker()
Decorator to create a MAKER agent for statistical error correction via voting.
MAKER: Massively decomposed Agentic processes with K-voting Error Reduction. Based on the paper “Solving a Million-Step LLM Task with Zero Errors” (arXiv:2511.09030).
@fast.maker(
name: str,
worker: str, # Required
k: int = 3,
max_samples: int = 50,
match_strategy: str = "exact",
red_flag_max_length: int | None = None,
instruction: str | Path | AnyUrl | None = None,
default: bool = False,
)
Name of the agent to sample from for voting
Margin required to declare winner (first-to-ahead-by-k). Higher k = more reliable but more samples needed
Maximum samples before falling back to plurality vote
How to compare responses: “exact”, “normalized”, or “structured”
Discard responses longer than this (in characters). Per the paper, overly long responses correlate with errors
Example
@fast.agent(
name="calculator",
instruction="Return only the numeric result"
)
async def calculator():
pass
@fast.maker(
name="reliable_calc",
worker="calculator",
k=3,
max_samples=50,
match_strategy="normalized"
)
async def reliable_calc():
pass
async with fast.run() as app:
result = await app.reliable_calc.send("What is 17 * 23?")
print(result.text) # High-confidence result via voting
Template Support
Instructions support several template patterns:
Current Date
@fast.agent(
name="daily_agent",
instruction="Today is {{currentDate}}. Help the user with their tasks."
)
URL Content
@fast.agent(
name="policy_agent",
instruction="Follow these guidelines: {{url:https://example.com/policy.txt}}"
)
File Content
@fast.agent(
name="doc_agent",
instruction="Use this context: {{file:./context.txt}}"
)
File templates are resolved at runtime relative to the workspace root.
See Also