Tutorial 04: Sequential Workflows - Build Agent Pipelines
Overviewβ
Connect your agents to create sophisticated multi-step workflows! Learn how to chain multiple agents in a strict sequence where each agent's output feeds into the next - perfect for content creation, data processing, or quality control pipelines.
What You'll Build: A Blog Post Generator Pipeline with 4 stages:
- Research Agent - Gathers information about the topic
- Writer Agent - Creates a draft blog post from research
- Editor Agent - Reviews and suggests improvements
- Formatter Agent - Converts to final markdown format
Implementation: tutorial_implementation/tutorial04 - Complete working blog creation pipeline with tests
Each agent's output feeds into the next, creating a complete content creation pipeline!
Prerequisitesβ
- Completed Tutorials 01-03 - Understanding of agents, tools, and OpenAPI
- Installed ADK -
pip install google-adk - API key configured - From Tutorial 01
Core Conceptsβ
SequentialAgentβ
The SequentialAgent is a workflow orchestrator that executes sub-agents in strict order. Unlike a regular agent, it's NOT powered by an LLM - it's deterministic and always runs agents in the exact sequence you define.
Key Characteristics:
- Executes sub-agents one at a time, in order
- Each agent completes before the next starts
- All agents share the same
InvocationContext(shared state) - Perfect for pipelines where order matters
Data Flow with output_keyβ
Agents pass data to each other using session state:
- Agent defines
output_key="my_result" - ADK automatically saves agent's response to
state['my_result'] - Next agent reads it using
{my_result}in its instruction
This creates a data pipeline!
When to Use Sequential Workflowsβ
Use SequentialAgent when:
- β Tasks MUST happen in specific order
- β Each step depends on previous step's output
- β You want predictable, deterministic execution
- β Building pipelines (ETL, content creation, review processes)
Don't use when:
- β Tasks are independent (use
ParallelAgentinstead) - β Need dynamic routing (use LLM-driven agent with sub-agents)
Use Caseβ
We're building a Blog Post Generator Pipeline with 4 stages:
- Research Agent - Gathers information about the topic
- Writer Agent - Creates a draft blog post from research
- Editor Agent - Reviews and suggests improvements
- Formatter Agent - Converts to final markdown format
Each agent's output feeds into the next, creating a complete content creation pipeline!
Step 1: Create Project Structureβ
mkdir blog_pipeline
cd blog_pipeline
touch __init__.py agent.py .env
Copy your .env file from previous tutorials.
Step 2: Set Up Package Importβ
blog_pipeline/init.py
from . import agent
Step 3: Define the Pipeline Agentsβ
blog_pipeline/agent.py
from __future__ import annotations
from google.adk.agents import Agent, SequentialAgent
# ===== Agent 1: Research Agent =====
# Gathers key facts about the topic
research_agent = Agent(
name="researcher",
model="gemini-2.0-flash",
description="Researches a topic and gathers key information",
instruction=(
"You are a research assistant. Your task is to gather key facts and information "
"about the topic requested by the user.\n"
"\n"
"Output a bulleted list of 5-7 key facts or insights about the topic. "
"Focus on interesting, specific information that would make a blog post engaging.\n"
"\n"
"Format:\n"
"β’ Fact 1\n"
"β’ Fact 2\n"
"β’ etc.\n"
"\n"
"Output ONLY the bulleted list, nothing else."
),
output_key="research_findings" # Saves to state['research_findings']
)
# ===== Agent 2: Writer Agent =====
# Writes blog post draft from research
writer_agent = Agent(
name="writer",
model="gemini-2.0-flash",
description="Writes a blog post draft based on research findings",
instruction=(
"You are a creative blog writer. Write an engaging blog post based on "
"the research findings below.\n"
"\n"
"**Research Findings:**\n"
"{research_findings}\n" # Reads from state!
"\n"
"Write a 3-4 paragraph blog post that:\n"
"- Has an engaging introduction\n"
"- Incorporates the key facts naturally\n"
"- Has a conclusion that wraps up the topic\n"
"- Uses a friendly, conversational tone\n"
"\n"
"Output ONLY the blog post text, no meta-commentary."
),
output_key="draft_post" # Saves to state['draft_post']
)
# ===== Agent 3: Editor Agent =====
# Reviews the draft and suggests improvements
editor_agent = Agent(
name="editor",
model="gemini-2.0-flash",
description="Reviews blog post draft and provides editorial feedback",
instruction=(
"You are an experienced editor. Review the blog post draft below and provide "
"constructive feedback.\n"
"\n"
"**Draft Blog Post:**\n"
"{draft_post}\n" # Reads from state!
"\n"
"Analyze the post for:\n"
"1. Clarity and flow\n"
"2. Grammar and style\n"
"3. Engagement and reader interest\n"
"4. Structure and organization\n"
"\n"
"Provide your feedback as a short list of specific improvements. "
"If the post is excellent, simply say: 'No revisions needed - post is ready.'\n"
"\n"
"Output ONLY the feedback, nothing else."
),
output_key="editorial_feedback" # Saves to state['editorial_feedback']
)
# ===== Agent 4: Formatter Agent =====
# Applies edits and formats as markdown
formatter_agent = Agent(
name="formatter",
model="gemini-2.0-flash",
description="Applies editorial feedback and formats the final blog post",
instruction=(
"You are a formatter. Create the final version of the blog post by applying "
"the editorial feedback to improve the draft.\n"
"\n"
"**Original Draft:**\n"
"{draft_post}\n" # Reads from state!
"\n"
"**Editorial Feedback:**\n"
"{editorial_feedback}\n" # Reads from state!
"\n"
"Create the final blog post by:\n"
"1. Applying the suggested improvements\n"
"2. Formatting as proper markdown with:\n"
" - A compelling title (# heading)\n"
" - Section headings if appropriate (## subheadings)\n"
" - Proper paragraph breaks\n"
" - Bold/italic for emphasis where appropriate\n"
"\n"
"If feedback said 'No revisions needed', just format the original draft nicely.\n"
"\n"
"Output ONLY the final formatted blog post in markdown."
),
output_key="final_post" # Saves to state['final_post']
)
# ===== Create the Sequential Pipeline =====
blog_creation_pipeline = SequentialAgent(
name="BlogCreationPipeline",
sub_agents=[
research_agent,
writer_agent,
editor_agent,
formatter_agent
], # Executes in this EXACT order!
description="Complete blog post creation pipeline from research to publication"
)
# MUST be named root_agent for ADK
root_agent = blog_creation_pipeline
Code Breakdownβ
State Flow Visualization:
```text
User Input: "Write about quantum computing"
β
Research Agent β state['research_findings'] = "β’ Quantum bits..."
β
Writer Agent (reads {research_findings}) β state['draft_post'] = "Quantum computing is..."
β
Editor Agent (reads {draft_post}) β state['editorial_feedback'] = "Add more examples..."
β
Formatter Agent (reads {draft_post}, {editorial_feedback}) β state['final_post'] = "# Quantum Computing\n\n..."
β
Final Output: formatted blog post
Key Pattern:
- Define
output_keyon each agent β saves response to state - Use
{state_key}in instructions β reads from state - Chain agents in
SequentialAgentβ strict execution order
Why This Works:
- All agents share the same
InvocationContext - State persists between agents in the sequence
{key}syntax auto-injects values into instructions
Step 4: Run the Pipelineβ
Demo in Actionβ
Here's what your sequential workflow pipeline looks like in action:

Navigate to parent directory and launch:
cd .. # Go to parent of blog_pipeline/
adk web
Open http://localhost:8000 and select "blog_pipeline".
Try These Promptsβ
Basic Usage:
Write a blog post about artificial intelligence
Specific Topic:
Create a blog post explaining how solar panels work
Technical Topic:
Write about the history of the Internet
Trending Topic:
Blog post about electric vehicles and their impact on climate
Understanding Pipeline Executionβ
Open the Events tab to see the magic! You'll see:
- Event: Research agent starts
- Event: Research agent completes β saves findings to state
- Event: Writer agent starts (with research_findings injected)
- Event: Writer agent completes β saves draft to state
- Event: Editor agent starts (with draft_post injected)
- Event: Editor agent completes β saves feedback to state
- Event: Formatter agent starts (with draft_post + feedback injected)
- Event: Formatter agent completes β final output!
Watch how each agent's output becomes the next agent's input!
Expected Behaviorβ
Example: "Write a blog post about quantum computing"
User: Write a blog post about quantum computing
[Agent 1: Researcher runs]
Research findings:
β’ Quantum computers use qubits that can be 0, 1, or both simultaneously
β’ IBM and Google are leading quantum computing research
β’ Potential applications include cryptography and drug discovery
β’ Current quantum computers require extremely cold temperatures
β’ Quantum supremacy was demonstrated in 2019
[Agent 2: Writer runs with research findings]
Draft: "Quantum computing represents one of the most exciting frontiers in
technology today..."
[Agent 3: Editor runs with draft]
Feedback: "Add a specific example of quantum supremacy. Clarify the temperature
requirements. Consider adding a future outlook section."
[Agent 4: Formatter runs with draft + feedback]
Final output:
# The Quantum Leap: Understanding Quantum Computing
Quantum computing represents one of the most exciting frontiers in technology today...
## How Quantum Computers Work
Unlike traditional computers that use bits (0 or 1), quantum computers use qubits...
## Real-World Applications
...
How It Works (Behind the Scenes)β
- User message arrives β ADK starts pipeline
- SequentialAgent begins:
- Calls research_agent.run()
- Waits for completion
- Saves output to
state['research_findings']
- Next agent in sequence:
- ADK injects
{research_findings}into writer instruction - Calls writer_agent.run()
- Waits for completion
- Saves output to
state['draft_post']
- ADK injects
- Continue down the chain:
- Editor reads
{draft_post} - Formatter reads
{draft_post}AND{editorial_feedback}
- Editor reads
- Pipeline complete β Returns final agent's output
Deterministic & Reliable:
- Always same order
- No LLM deciding order
- Predictable behavior
Visual Flow:
Key Takeawaysβ
β SequentialAgent chains agents in strict order - Perfect for pipelines
β output_key saves to state - Each agent stores its result
β
{key} syntax reads from state - Next agent accesses previous results
β Shared InvocationContext - All agents in sequence share state
β Deterministic execution - No LLM, always same order
β Perfect for workflows - Research β Write β Review β Format
β State flow is explicit - Easy to debug and understand
Best Practicesβ
DO:
- Give each agent a specific, focused task
- Use descriptive
output_keynames - Be explicit in instructions about what to output
- Use state injection
{key}for data flow - Keep agents stateless (rely on state, not internal memory)
DON'T:
- Make agents try to do too much
- Forget to set
output_key(data won't flow!) - Use generic state keys like
resultordata - Mix sequential with parallel without planning
- Assume agents remember across separate runs
Common Issuesβ
Problem: "Next agent doesn't see previous agent's output"
- Solution: Check that previous agent has
output_keydefined - Solution: Verify you're using
{correct_key_name}in instruction
Problem: "Pipeline seems to skip agents"
- Solution: All agents run, check Events tab to see their outputs
- Solution: Agent might be outputting empty response
Problem: "State values not injecting"
- Solution: Use exact
{key_name}matching theoutput_key - Solution: Keys are case-sensitive!
Problem: "Pipeline takes too long"
- Solution: This is normal - agents run sequentially (one at a time)
- Solution: Consider if some steps could be parallel instead
What We Builtβ
You now have a complete content creation pipeline that:
- Automatically researches topics
- Writes engaging blog posts
- Reviews for quality
- Formats for publication
And you understand how to build ANY sequential workflow!
Real-World Applicationsβ
Sequential Workflows Are Perfect For:
- Content Pipelines: Research β Write β Edit β Publish
- Data Processing: Extract β Transform β Validate β Load (ETL)
- Quality Control: Create β Review β Fix β Approve
- Analysis Pipelines: Gather Data β Analyze β Visualize β Report
- Code Workflows: Write β Review β Refactor β Test
- Customer Service: Classify β Route β Respond β Follow-up
π Related: Combine sequential workflows with Tutorial 06: Multi-Agent Systems for complex agent hierarchies.
Next Stepsβ
π Tutorial 05: Parallel Processing - Learn when and how to run agents concurrently for speed
π Further Reading:
Exercises (Try On Your Own!)β
- Add more agents - Add a "fact-checker" between writer and editor
- Different domain - Create a recipe pipeline (ingredients β instructions β nutrition β formatting)
- Code pipeline - Implement: write code β review β test β document
- Error handling - Add an agent that validates each step's output
- Conditional flow - Have editor decide if re-writing is needed
Complete Code Referenceβ
blog_pipeline/init.py
from . import agent
blog_pipeline/.env
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=your-api-key-here
blog_pipeline/agent.py
# See Step 3 above for complete code
Congratulations! You've mastered sequential workflows! π―π
π¬ Join the Discussion
Have questions or feedback? Discuss this tutorial with the community on GitHub Discussions.