Agents as Tools exposes child agents as callable tools to a parent agent, enabling the parent’s LLM to naturally route, parallelize, and orchestrate work across specialized agents through function calling. This pattern combines the simplicity of tool calling with the power of multi-agent coordination.
Inspired by OpenAI’s Agents SDK Agents as Tools feature, with enhancements for parallel execution and detached instances.
@fast.agent( name="billing_specialist", instruction="Handle billing, payments, and invoice questions",)@fast.agent( name="technical_support", instruction="Resolve technical issues and product questions",)@fast.agent( name="account_manager", instruction="Handle account changes and general inquiries",)@fast.agent( name="customer_service", instruction="Route customer inquiries to the appropriate specialist based on the topic.", agents=["billing_specialist", "technical_support", "account_manager"],)
@fast.agent( name="translator", instruction="Translate text to the specified language",)@fast.agent( name="translation_coordinator", instruction=( "Translate the given text to French, German, and Spanish. " "Use one tool call per language. Return all translations." ), agents=["translator"],)
@fast.agent( name="researcher", instruction="Research topics using web search", servers=["fetch"],)@fast.agent( name="writer", instruction="Write comprehensive articles",)@fast.agent( name="editor", instruction="Edit and improve content",)@fast.agent( name="content_pipeline", instruction=( "Create a blog post: " "1. Call researcher to gather information " "2. Call writer with research to draft article " "3. Call editor with draft to polish final version" ), agents=["researcher", "writer", "editor"],)
@fast.agent( name="project_status_agent", instruction="Get project status including health, blockers, and next steps", servers=["jira", "github"],)@fast.agent( name="dashboard_coordinator", instruction=( "Generate a status dashboard for all active projects. " "Call project_status_agent once per project in parallel. " "Projects: [ProjectA, ProjectB, ProjectC, ProjectD]. " "Aggregate into a summary dashboard with highlights and concerns." ), agents=["project_status_agent"], max_parallel=10,)async def main() -> None: async with fast.run() as agent: await agent.dashboard_coordinator.send("Generate current project dashboard")
@fast.agent( name="academic_researcher", instruction="Search academic papers and journals", servers=["fetch"],)@fast.agent( name="news_researcher", instruction="Find recent news and current events", servers=["fetch"],)@fast.agent( name="code_researcher", instruction="Search code repositories and documentation", servers=["github", "fetch"],)@fast.agent( name="research_coordinator", instruction=( "Conduct comprehensive research on the given topic. " "Determine which research types are relevant, call those agents, " "and synthesize findings into a coherent report. " "Available: academic_researcher, news_researcher, code_researcher" ), agents=["academic_researcher", "news_researcher", "code_researcher"], servers=["filesystem"], # Coordinator can also use tools directly)async def main() -> None: async with fast.run() as agent: await agent.research_coordinator.send( "Research the latest developments in transformer architectures" )
@fast.agent( name="doc_writer", instruction="Write technical documentation in the specified language",)@fast.agent( name="doc_coordinator", instruction=( "Generate documentation in English, Spanish, French, German, and Japanese. " "Call doc_writer once per language with the language specified in the message. " "Aggregate all versions and create an index page." ), agents=["doc_writer"], servers=["filesystem"], max_parallel=5,)async def main() -> None: async with fast.run() as agent: await agent.doc_coordinator.send( "Generate API documentation for the authentication module" )
Control how message history flows between parent and child agents:
@fast.agent( name="orchestrator", instruction="Coordinate tasks across child agents", agents=["worker1", "worker2"], history_source="orchestrator", # Children see parent's history history_merge_target="orchestrator", # Children's history merges back to parent)
History Source Options:
none: Children start with empty history (default)
child: Children start with template child’s history
orchestrator: Children start with parent’s history