Skip to main content

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,
)
name
str
default:"default"
Name of the agent
instruction
str | Path | AnyUrl
Base instruction for the agent. Can be a string, path to a file, or URL. Supports templates like {{currentDate}}, {{url:...}}, {{file:...}}
agents
list[str] | None
List of child agent names to attach via Agents-as-Tools
servers
list[str]
default:"[]"
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
function_tools
FunctionToolsConfig
List of Python function tools to include (e.g., ["tools.py:my_function"])
model
str | None
Model specification string (e.g., "openai:gpt-4", "anthropic:claude-3-5-sonnet-20241022")
use_history
bool
default:"True"
Whether to maintain conversation history
request_params
RequestParams | None
Additional request parameters for the LLM (temperature, max_tokens, etc.)
human_input
bool
default:"False"
Whether to enable human input capabilities
default
bool
default:"False"
Whether to mark this as the default agent for the application
elicitation_handler
ElicitationFnT | None
Custom elicitation handler function for processing user inputs
api_key
str | None
Optional API key for the LLM provider (overrides environment variables)
history_source
Any | None
Source for conversation history in Agents-as-Tools scenarios
history_merge_target
Any | None
Target for merging conversation history in Agents-as-Tools scenarios
max_parallel
int | None
Maximum number of parallel child agent invocations for Agents-as-Tools
child_timeout_sec
int | None
Timeout in seconds for child agent tool calls
max_display_instances
int | None
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,
)
cls
type
required
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,
)
name
str
required
Name of the orchestrator
agents
list[str]
required
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
plan_iterations
int
default:"5"
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,
)
plan_iterations
int
default:"-1"
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,
)
agents
list[str]
required
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,
)
sequence
list[str]
required
List of agent names to execute in order
cumulative
bool
default:"False"
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,
)
fan_out
list[str]
required
List of agent names to execute in parallel
fan_in
str | None
Optional agent name to aggregate the parallel results
include_request
bool
default:"True"
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,
)
generator
str
required
Name of the agent that generates initial responses
evaluator
str
required
Name of the agent that evaluates response quality
min_rating
str
default:"GOOD"
Minimum acceptable quality rating (EXCELLENT, GOOD, FAIR, POOR)
max_refinements
int
default:"3"
Maximum number of refinement iterations
refinement_instruction
str | None
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,
)
worker
str
required
Name of the agent to sample from for voting
k
int
default:"3"
Margin required to declare winner (first-to-ahead-by-k). Higher k = more reliable but more samples needed
max_samples
int
default:"50"
Maximum samples before falling back to plurality vote
match_strategy
str
default:"exact"
How to compare responses: “exact”, “normalized”, or “structured”
red_flag_max_length
int | None
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

Build docs developers (and LLMs) love