Skip to main content

Overview

The Chain workflow executes agents in a defined sequence, where the output of each agent becomes the input to the next. This pattern is ideal for multi-step processes where each stage builds on the results of the previous one.
Chain workflows support both simple sequential processing and cumulative modes where agents can see all previous responses.

Key Features

  • Sequential Execution: Agents run one after another in a defined order
  • Output Passing: Each agent’s output becomes the next agent’s input
  • Cumulative Mode: Optional mode where agents see all previous responses
  • Flexible Composition: Chains can include other workflow types
  • Interactive Continuation: Chat with the final agent after chain execution

Basic Usage

import asyncio
from fast_agent import FastAgent

fast = FastAgent("Agent Chaining")

@fast.agent(
    "url_fetcher",
    instruction="Given a URL, provide a complete and comprehensive summary",
    servers=["fetch"],
)
@fast.agent(
    "social_media",
    instruction="""
    Write a 280 character social media post for any given text. 
    Respond only with the post, never use hashtags.
    """,
)
@fast.chain(
    name="post_writer",
    sequence=["url_fetcher", "social_media"],
    default=True,
)
async def main() -> None:
    async with fast.run() as agent:
        # Using chain workflow
        await agent.post_writer.send("https://llmindset.co.uk")

if __name__ == "__main__":
    asyncio.run(main())

Configuration Parameters

name
string
required
Name of the chain workflow
sequence
list[str]
required
List of agent names in execution order
instruction
string
Description of the chain for other workflows
cumulative
bool
default:"false"
Whether each agent sees all previous responses
continue_with_final
bool
default:"true"
Open chat with final agent after chain execution

Cumulative Mode

In cumulative mode, each agent receives:
  • The original user request
  • All previous agent responses
Responses are formatted with XML tags for clarity:
<fastagent:request>
  Original user message
</fastagent:request>

<fastagent:response agent='agent_name'>
  Agent response
</fastagent:response>

Command Line Usage

Run a chain from the command line:
uv run workflow/chaining.py --agent post_writer --message "<url>"
Add --quiet to return only the final response:
uv run workflow/chaining.py --agent post_writer --message "<url>" --quiet

How It Works

  1. Initial Request: The user message is sent to the first agent
  2. Sequential Processing: Each agent processes its input and generates output
  3. Output Forwarding: The output becomes input for the next agent
  4. Final Response: The last agent’s response is returned

Non-Cumulative Flow

Cumulative Flow

Advanced Examples

Multi-Stage Content Pipeline

@fast.agent(
    "researcher",
    instruction="Research the topic and gather key facts",
    servers=["fetch"],
)
@fast.agent(
    "writer",
    instruction="Write a comprehensive article based on the research",
)
@fast.agent(
    "editor",
    instruction="Edit and improve the article for clarity and style",
)
@fast.chain(
    name="content_pipeline",
    sequence=["researcher", "writer", "editor"],
    cumulative=False,
)
async def main() -> None:
    async with fast.run() as agent:
        await agent.content_pipeline.send("The impact of AI on healthcare")

Cumulative Analysis Chain

@fast.agent(
    "analyzer",
    instruction="Analyze the data and provide insights",
)
@fast.agent(
    "critic",
    instruction="Review the analysis critically",
)
@fast.agent(
    "synthesizer",
    instruction="Synthesize all feedback into actionable recommendations",
)
@fast.chain(
    name="deep_analysis",
    sequence=["analyzer", "critic", "synthesizer"],
    cumulative=True,  # Each agent sees all previous work
)
async def main() -> None:
    async with fast.run() as agent:
        await agent.deep_analysis.send("Analyze Q4 sales data")

Best Practices

Clear Boundaries

Define clear responsibilities for each agent in the sequence

Output Format

Ensure each agent’s output is suitable input for the next

Chain Length

Keep chains reasonably short (3-5 agents) for maintainability

Error Handling

Consider what happens if an agent fails mid-chain

Use Cases

  • Content Creation: Research → Write → Edit → Publish
  • Data Processing: Extract → Transform → Analyze → Report
  • Multi-step Tasks: Fetch → Summarize → Translate → Format
  • Quality Assurance: Generate → Review → Revise → Approve

Interactive Mode

After chain execution, you can continue chatting with the final agent:
async with fast.run() as agent:
    # Chain executes
    await agent.post_writer.send("https://example.com")
    # Now chatting with 'social_media' agent (the last in chain)
Switch agents using @agent-name in interactive mode.

Build docs developers (and LLMs) love