Agent Task Planning (To-Do Lists) in Google ADK
January 27, 20266 min read
Agent Task Planning (To-Do Lists) in Google ADK
What is this? This guide explains how agents can create internal task lists to break down complex requests, track progress, and execute multi-step operations systematically.
🎯 What is Agent Task Planning?
When a user gives a complex request, the agent creates an internal to-do list to:
- Break the task into smaller steps
- Know what to do first
- Track what's done vs pending
- Coordinate tools and sub-agents
This is NOT a user-facing todo app — it's the agent's internal planning mechanism.
📊 Architecture Overview
🔧 Two Approaches to Task Planning
1. Built-in Planner (Gemini 2.5+)
Uses the model's native thinking capabilities.
2. PlanReActPlanner
Structured planning for any model — creates explicit plans with tags.
💻 Code Examples
Example 1: Basic Agent with PlanReActPlanner
from google.adk import Agent
from google.adk.planners import PlanReActPlanner
# Define tools the agent can use
def search_web(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
def save_note(content: str) -> str:
"""Save a note to the database."""
return f"Saved: {content}"
# Create agent with planning capability
research_agent = Agent(
name="ResearchAgent",
model="gemini-2.0-flash",
instruction="""
You are a research assistant. When given a complex task:
1. First create a plan
2. Execute each step
3. Report progress
""",
planner=PlanReActPlanner(), # Enables task planning!
tools=[search_web, save_note]
)
What happens when user says: "Research AI trends and summarize them"
The agent internally creates:
/*PLANNING*/
1. Search web for "AI trends 2025"
2. Search web for "AI industry reports"
3. Analyze and synthesize results
4. Create summary note
/*ACTION*/ Calling search_web("AI trends 2025")
/*REASONING*/ Found 5 key trends...
/*ACTION*/ Calling search_web("AI industry reports")
/*REASONING*/ Industry growing at 40% CAGR...
/*ACTION*/ Calling save_note(summary)
/*FINAL_ANSWER*/ Here are the AI trends...
Example 2: Built-in Planner (Gemini Thinking)
from google.adk import Agent
from google.adk.planners import BuiltInPlanner
from google.genai import types
# Agent with native thinking/planning
smart_agent = Agent(
name="SmartAgent",
model="gemini-2.5-flash", # Supports built-in thinking
planner=BuiltInPlanner(
thinking_config=types.ThinkingConfig(
include_thoughts=True, # Show thinking process
thinking_budget=1024 # Tokens for planning
)
),
tools=[your_tools_here]
)
Example 3: Multi-Agent with Task Delegation
from google.adk.agents import LlmAgent
from google.adk.planners import PlanReActPlanner
# Specialized worker agents
research_agent = LlmAgent(
name="Researcher",
model="gemini-2.0-flash",
description="Finds information on topics"
)
analysis_agent = LlmAgent(
name="Analyst",
model="gemini-2.0-flash",
description="Analyzes data and finds patterns"
)
writer_agent = LlmAgent(
name="Writer",
model="gemini-2.0-flash",
description="Writes reports and summaries"
)
# Orchestrator creates to-do list and delegates
orchestrator = LlmAgent(
name="Orchestrator",
model="gemini-2.0-flash",
instruction="""
You manage complex tasks by:
1. Breaking them into subtasks (your to-do list)
2. Delegating to the right specialist
3. Tracking completion
4. Combining results
Available specialists:
- Researcher: for finding information
- Analyst: for data analysis
- Writer: for creating reports
""",
planner=PlanReActPlanner(),
sub_agents=[research_agent, analysis_agent, writer_agent]
)
Example 4: Session State for Progress Tracking
from google.adk import Agent
from google.adk.sessions import InMemorySessionService
from google.adk.runners import Runner
def update_progress(task_name: str, status: str, ctx) -> str:
"""Update task status in session state."""
# Get or create task list
tasks = ctx.session.state.get("todo_list", {})
tasks[task_name] = status
ctx.session.state["todo_list"] = tasks
return f"Updated: {task_name} = {status}"
def get_progress(ctx) -> str:
"""Get current to-do list status."""
tasks = ctx.session.state.get("todo_list", {})
if not tasks:
return "No tasks in progress"
return "\n".join([f"- {k}: {v}" for k, v in tasks.items()])
agent = Agent(
name="TaskTracker",
model="gemini-2.0-flash",
instruction="""
For complex requests:
1. Create tasks using update_progress(task, "pending")
2. Work on each task
3. Mark complete with update_progress(task, "done")
4. Use get_progress() to check status
""",
tools=[update_progress, get_progress]
)
🌐 A2A Protocol: Remote Agent Collaboration
For distributed systems, agents can delegate tasks to remote agents using A2A.
# Remote agent exposes an Agent Card for discovery
# agent_card.json (served at /.well-known/agent.json)
{
"name": "DataAnalysisAgent",
"description": "Analyzes datasets and returns insights",
"url": "https://analysis-agent.example.com",
"skills": [
{
"id": "analyze-data",
"name": "Data Analysis",
"description": "Analyzes CSV/JSON data"
}
]
}
# Orchestrator discovers and delegates to remote agents
from google.adk.tools.a2a import A2ATool
remote_analyzer = A2ATool(
agent_url="https://analysis-agent.example.com"
)
orchestrator = LlmAgent(
name="Orchestrator",
model="gemini-2.0-flash",
tools=[remote_analyzer],
planner=PlanReActPlanner()
)
📋 When to Use Task Planning
| Scenario | Use Planning? | Why |
|---|---|---|
| Simple Q&A | ❌ No | Single-step, no coordination needed |
| Multi-step research | ✅ Yes | Multiple tools, needs tracking |
| Data pipeline | ✅ Yes | Sequential operations |
| Long-running jobs | ✅ Yes | Progress visibility important |
| Multi-agent tasks | ✅ Yes | Coordination required |
🎓 Key Concepts Summary
| Concept | Description |
|---|---|
| Planner | Component that breaks tasks into steps |
| PlanReActPlanner | Structured planning with explicit tags |
| BuiltInPlanner | Uses model's native thinking (Gemini 2.5+) |
| Session State | Stores to-do list and progress |
| Sub-agents | Specialized workers for delegation |
| A2A Protocol | Remote agent-to-agent communication |
| Agent Card | Metadata describing agent capabilities |
🚀 Quick Start Template
from google.adk import Agent
from google.adk.planners import PlanReActPlanner
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
# 1. Define your tools
def step_one(input: str) -> str:
"""First step of the process."""
return f"Step 1 done: {input}"
def step_two(input: str) -> str:
"""Second step of the process."""
return f"Step 2 done: {input}"
# 2. Create agent with planner
agent = Agent(
name="TaskAgent",
model="gemini-2.0-flash",
instruction="Break complex tasks into steps and execute systematically.",
planner=PlanReActPlanner(),
tools=[step_one, step_two]
)
# 3. Run the agent
session_service = InMemorySessionService()
runner = Runner(agent=agent, session_service=session_service)
# 4. Execute
async def main():
session = await session_service.create_session(
app_name="my_app",
user_id="user1"
)
async for event in runner.run_async(
session_id=session.id,
user_id="user1",
new_message="Do the complex task with multiple steps"
):
print(event)
import asyncio
asyncio.run(main())