This blog is part of the ADK Masterclass - Hands-On Series. While standard LLM Agents are great for open-ended tasks, many business processes require structure and predictability. This is where Workflow Agents come in.
Workflow Agents in ADK allow us to orchestrate other agents in predefined patterns: strict sequences, parallel execution, or iterative loops. They provide the control structure needed for robust applications.
View Code on GitHubTable of Contents
1. What are Workflow Agents?
Workflow Agents are a unique class of components in ADK that focus exclusively on coordinating and scheduling other agents. They act as the traffic controllers of our agent system, dictating the order and timing of when each sub-agent executes.
While standard LLM Agents leverage language models to make intelligent decisions on the fly, Workflow Agents follow a rigid, code-defined blueprint. The sequence of operations is determined by the workflow type we choose (sequential, parallel, or loop) and is executed mechanically, with no AI reasoning involved in deciding what happens next. This mechanical approach ensures that our process runs the same way every time, with no surprises.
2. Why Use Workflow Agents?
In real-world applications, we can't afford to let an LLM "figure out" the process flow on its own. Workflow Agents solve this by giving us programmatic control over our agent orchestration, delivering three critical advantages:
- Predictable Execution: The execution path is locked in at development time. We define the sequence once, and it runs the same way every single execution. No LLM can decide to skip a step or change the order.
- Repeatable Results: Because the workflow structure is deterministic, we can test it, version it, and deploy it with confidence. The same input will always produce the same execution pattern.
- Modular Architecture: Instead of one monolithic agent trying to do everything, we break complex problems into smaller, focused agents that the workflow coordinates. This makes our code easier to understand, modify, and maintain.
3. Core Workflow Patterns
ADK offers three fundamental workflow architectures, each serving a different organizational need:
Sequential Agents
These agents run their sub-agents in a strict, linear order. Each agent waits for the previous one to finish, then uses that output as its input. Think of it like a relay race where the baton (data) is passed from one runner (agent) to the next. This pattern works best when each step depends on the results of the previous step.
Parallel Agents
These agents launch all their sub-agents simultaneously, giving them the same starting point. Each agent works independently, and we collect all their outputs at the end. It's like asking multiple experts to review the same document at the same time, which gives us faster results and multiple viewpoints. We use this when tasks are independent and can benefit from concurrent execution.
Loop Agents
These agents repeatedly execute their sub-agents until a stopping condition is satisfied. It's the AI equivalent of a "do-while" loop, where the agent keeps refining or retrying until it meets our criteria. This is invaluable for quality control, iterative improvement, or any scenario where we need the agent to self-correct until it gets it right.
4. Tutorial
We'll build three different pipelines to demonstrate each workflow pattern. Before we start, let's set up our environment.
Prerequisites
- Google AI Studio API Key
- Python 3.9+ installed
Step 1: Setup Environment
python3 -m venv .venv
source .venv/bin/activate
pip install google-adk python-dotenv
# Set your API Key
export GEMINI_API_KEY=your_api_key_here
4.1. Building an Investment Research Pipeline - Sequential Agent
Let's build a practical Sequential Workflow for a financial services firm. We want to take a company ticker symbol and generate a comprehensive investment research report with analysis and recommendations.
Initialize the project:
adk create investment_pipeline
cd investment_pipeline
Step 1: Define the Workers
We'll create three specialized agents that work together. Each agent stores its output in the shared state using output_key, allowing the next agent to access previous results.
from google.adk.agents import SequentialAgent, LlmAgent
import os
MODEL = os.getenv("GEMINI_MODEL", "gemini-2.5-flash")
# Data Collector Agent: Gathers financial information
data_collector = LlmAgent(
name="FinancialDataCollector",
model=MODEL,
instruction="""For the given company ticker, compile key financial data:
- Recent stock performance
- Revenue trends
- Profitability metrics
- Market position
- Industry context
Present as structured bullet points with numbers where relevant.""",
description="Collects and structures financial data about a company.",
output_key="financial_data"
)
# Analyst Agent: Performs financial analysis
financial_analyst = LlmAgent(
name="FinancialAnalyst",
model=MODEL,
instruction="""Analyze this financial data and provide investment insights:
{financial_data}
Provide:
- Strengths and opportunities
- Risks and concerns
- Key financial ratios assessment
- Competitive positioning
Format as a structured analysis.""",
description="Analyzes financial data and identifies key insights.",
output_key="analysis"
)
# Report Generator Agent: Creates final report
report_generator = LlmAgent(
name="ReportGenerator",
model=MODEL,
instruction="""Create a professional investment research report using:
Financial Data:
{financial_data}
Analysis:
{analysis}
Structure the report with:
- Executive Summary
- Financial Overview
- Investment Thesis
- Risk Assessment
- Recommendation (Buy/Hold/Sell)
Keep it professional and suitable for institutional investors.""",
description="Generates comprehensive investment research reports.",
output_key="final_report"
)
Step 2: Create the Workflow
We combine these agents into a SequentialAgent. The workflow will execute them in order: Collect Data → Analyze → Generate Report.
research_pipeline = SequentialAgent(
name="InvestmentResearchPipeline",
sub_agents=[data_collector, financial_analyst, report_generator],
description="Generates investment research reports through data collection, analysis, and report generation."
)
root_agent = research_pipeline
Step 3: Run the Pipeline
We can run this pipeline using the ADK web interface. Each agent's output flows to the next via the shared state.
adk web
How It Works
When we run this SequentialAgent pipeline with a company ticker, ADK executes each sub-agent in order, automatically managing data flow through a shared state dictionary:
- Input: A company ticker (e.g., "AAPL") enters the
SequentialAgentas the user query. - Step 1 - FinancialDataCollector: The first sub-agent receives the ticker and gathers financial information. The output is stored in
state['financial_data']viaoutput_key="financial_data". - Step 2 - FinancialAnalyst: ADK automatically injects
state['financial_data']into the FinancialAnalyst's instruction. The analysis is stored instate['analysis']. - Step 3 - ReportGenerator: ADK automatically injects both
state['financial_data']andstate['analysis']. The final report is stored instate['final_report']. - Output: The complete investment research report is returned.
The SequentialAgent ensures each sub-agent runs in the exact order we specified in sub_agents=[data_collector, financial_analyst, report_generator]. This state-based pattern modularizes our logic and makes data flow explicit.
4.2. Building a Risk Assessment Pipeline - Parallel Agent
Let's build a practical Parallel Workflow for comprehensive risk assessment. We want multiple analysts to evaluate the same investment opportunity simultaneously, each focusing on a different risk dimension.
Initialize the project:
adk create risk_assessment
cd risk_assessment
Step 1: Define the Workers
We'll create three specialized risk assessment agents that work independently on the same input. Each agent focuses on a different risk category and stores its output in the shared state.
from google.adk.agents import ParallelAgent, LlmAgent
import os
MODEL = os.getenv("GEMINI_MODEL", "gemini-2.5-flash")
# Market Risk Analyst: Evaluates market volatility and trends
market_risk_analyst = LlmAgent(
name="MarketRiskAnalyst",
model=MODEL,
instruction="""Analyze the market risk factors for this investment:
{input}
Assess:
- Market volatility trends
- Sector performance
- Macroeconomic factors
- Market sentiment indicators
Provide a risk score (1-10) and detailed analysis.""",
description="Evaluates market-related risks for investments.",
output_key="market_risk_analysis"
)
# Credit Risk Analyst: Evaluates financial stability
credit_risk_analyst = LlmAgent(
name="CreditRiskAnalyst",
model=MODEL,
instruction="""Analyze the credit risk factors for this investment:
{input}
Assess:
- Debt-to-equity ratios
- Credit ratings
- Liquidity position
- Financial leverage
Provide a risk score (1-10) and detailed analysis.""",
description="Evaluates credit and financial risks for investments.",
output_key="credit_risk_analysis"
)
# Operational Risk Analyst: Evaluates business operations
operational_risk_analyst = LlmAgent(
name="OperationalRiskAnalyst",
model=MODEL,
instruction="""Analyze the operational risk factors for this investment:
{input}
Assess:
- Management quality
- Operational efficiency
- Regulatory compliance
- Business model sustainability
Provide a risk score (1-10) and detailed analysis.""",
description="Evaluates operational and business risks for investments.",
output_key="operational_risk_analysis"
)
Step 2: Create the Parallel Workflow
We combine these agents into a ParallelAgent. All three agents will execute simultaneously, receiving the same input and working independently. Each agent stores its analysis in the shared state using its output_key.
# Create the ParallelAgent (Runs risk analysts concurrently)
# This agent orchestrates the concurrent execution of the three risk analysts.
# It finishes once all analysts have completed and stored their results in state.
risk_assessment_pipeline = ParallelAgent(
name="ParallelRiskAssessment",
sub_agents=[market_risk_analyst, credit_risk_analyst, operational_risk_analyst],
description="Runs multiple risk assessment agents in parallel to gather comprehensive risk analysis."
)
root_agent = risk_assessment_pipeline
Step 3: Run the Pipeline
We can run this pipeline using the ADK web interface. All three agents execute simultaneously, and their outputs are collected in the shared state.
adk web
How It Works
When we run this ParallelAgent pipeline, ADK executes all sub-agents simultaneously, each receiving the same input and working independently:
- Input: An investment opportunity enters the
ParallelAgentas the user query. - Parallel Execution: All three risk analysts (Market, Credit, Operational) receive the same input and execute simultaneously.
- State Storage: Each agent stores its analysis in separate state keys:
state['market_risk_analysis'],state['credit_risk_analysis'], andstate['operational_risk_analysis']. - Output: All three risk assessments are available in the shared state for further processing or review.
The ParallelAgent ensures all sub-agents run concurrently, significantly reducing total processing time when tasks are independent. There is no automatic sharing of conversation history or state between the parallel branches during execution.
4.3. Building a Report Refinement Pipeline - Loop Agent
Let's build a practical Loop Workflow for iterative report refinement. We want an agent to repeatedly improve a report until it meets our quality criteria.
Initialize the project:
adk create report_refiner
cd report_refiner
Step 1: Define the Workers
We'll create two agents that work together in the loop: a quality checker that evaluates the report, and a refiner that improves it based on feedback.
from google.adk.agents import LoopAgent, LlmAgent
import os
MODEL = os.getenv("GEMINI_MODEL", "gemini-2.5-flash")
# Quality Checker: Evaluates the report against quality criteria
quality_checker = LlmAgent(
name="QualityChecker",
model=MODEL,
instruction="""Review this investment report against quality criteria:
Current Report:
{refined_report}
Quality Criteria:
- Executive summary must be under 200 words
- All financial data must be cited
- Risk assessment must include specific metrics
- Recommendation must be clearly justified
IF the report meets all criteria:
Respond with exactly: "QUALITY_APPROVED"
ELSE:
Provide specific, actionable feedback on what needs improvement. Output *only* the feedback.""",
description="Evaluates investment reports against quality criteria.",
output_key="quality_feedback"
)
# Report Refiner: Improves the report based on feedback
report_refiner = LlmAgent(
name="ReportRefiner",
model=MODEL,
instruction="""Refine this investment report based on quality feedback:
Current Report:
{refined_report}
Quality Feedback:
{quality_feedback}
IF the feedback is exactly "QUALITY_APPROVED":
The report is complete. Return the current report unchanged.
ELSE:
Apply the feedback to improve the report. Output *only* the refined report text.""",
description="Refines investment reports based on quality feedback.",
output_key="refined_report"
)
Step 2: Create the Workflow
We combine these agents into a LoopAgent with a maximum iteration limit. The loop will run the quality checker and refiner in sequence, repeating until the quality checker signals completion or the max iterations are reached.
# Create the LoopAgent (Runs quality checker and refiner iteratively)
# The loop will execute the sub-agents in order, repeating until max_iterations
# or until the quality checker signals completion
report_refinement_pipeline = LoopAgent(
name="ReportRefinementPipeline",
sub_agents=[quality_checker, report_refiner],
max_iterations=5,
description="Iteratively refines investment reports until quality criteria are met."
)
root_agent = report_refinement_pipeline
Step 3: Run the Pipeline
We can run this pipeline using the ADK web interface. The agent will loop until the report meets all quality criteria.
adk web
How It Works
When we run this LoopAgent pipeline, ADK repeatedly executes the sub-agents in sequence until the stopping condition is met or max iterations are reached:
- Input: An initial report enters the
LoopAgentas the user query. - Iteration 1: The QualityChecker evaluates the report. If it finds issues, it provides feedback stored in
state['quality_feedback']. If no issues, it responds with "QUALITY_APPROVED". - Refinement: The ReportRefiner receives both the report and feedback. If feedback indicates issues, it refines the report and stores it in
state['refined_report']. If feedback is "QUALITY_APPROVED", it returns the report unchanged. - Loop Decision: If the quality feedback is "QUALITY_APPROVED", the loop stops. Otherwise, the loop continues with the refined report (up to
max_iterations=5). - Output: The final refined report is stored in
state['refined_report']and returned.
The LoopAgent iterates through the sub-agents list in order for each iteration. You must implement a termination mechanism (like the "QUALITY_APPROVED" signal or max_iterations) to prevent infinite loops.
Next Steps
Now that we've covered workflow patterns, let's explore how multiple independent agents can collaborate:
- Multi-Agent Systems: Build hierarchical teams of agents (e.g., Managers and Workers).