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

ScenarioUse Planning?Why
Simple Q&A❌ NoSingle-step, no coordination needed
Multi-step research✅ YesMultiple tools, needs tracking
Data pipeline✅ YesSequential operations
Long-running jobs✅ YesProgress visibility important
Multi-agent tasks✅ YesCoordination required

🎓 Key Concepts Summary

ConceptDescription
PlannerComponent that breaks tasks into steps
PlanReActPlannerStructured planning with explicit tags
BuiltInPlannerUses model's native thinking (Gemini 2.5+)
Session StateStores to-do list and progress
Sub-agentsSpecialized workers for delegation
A2A ProtocolRemote agent-to-agent communication
Agent CardMetadata 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())

📚 Resources