ec2b666284
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
276 lines
9.0 KiB
Markdown
276 lines
9.0 KiB
Markdown
# Task Mode: Structured Delegation
|
|
|
|
Delegate structured tasks to sub-agents with typed input/output schemas.
|
|
|
|
## 📋 Agent Verification Checklist (Task Mode)
|
|
Use this checklist to verify your Task Mode configuration:
|
|
- [ ] **Mode Setting**: Did you explicitly set `mode='task'` or `mode='single_turn'` on the sub-agent?
|
|
- [ ] **Description**: Does the sub-agent have a clear `description`? (Crucial for the auto-generated tool's description)
|
|
- [ ] **Schemas**: Are `input_schema` and `output_schema` defined as Pydantic models? (If not, defaults are used)
|
|
- [ ] **Completion**: Does the sub-agent know it must call `finish_task` to return results to the coordinator?
|
|
|
|
## 💡 Quick Reference (Generated Tools)
|
|
- **`request_task_{agent_name}`**: Generated on the **coordinator** to delegate tasks.
|
|
- **`finish_task`**: Generated on the **sub-agent** to return results and complete the task.
|
|
|
|
## Overview
|
|
|
|
ADK agents support three delegation modes via the `mode` parameter on `Agent`:
|
|
|
|
| Mode | Tool Generated | User Interaction | Completion |
|
|
|------|---------------|------------------|------------|
|
|
| `chat` (default) | `transfer_to_agent` | Full conversational | Agent transfers back |
|
|
| `task` | `request_task_{name}` | Multi-turn (can chat with user) | Calls `finish_task` |
|
|
| `single_turn` | `request_task_{name}` | None (autonomous) | Calls `finish_task` |
|
|
|
|
## Imports
|
|
|
|
```python
|
|
from google.adk import Agent
|
|
from pydantic import BaseModel
|
|
```
|
|
|
|
**Note**: Task mode uses `Agent` (aliased from `LlmAgent`) from `google.adk`. Both task sub-agents and coordinators use the same `Agent` class — set `mode='task'` or `mode='single_turn'` on sub-agents.
|
|
|
|
## Task Mode (`mode='task'`)
|
|
|
|
A task agent receives structured input via `request_task_{name}`, can interact with the user for clarification, and returns structured output via `finish_task`.
|
|
|
|
### Delegation Lifecycle
|
|
|
|
1. User asks the coordinator to do something
|
|
2. Coordinator calls `request_task_{agent_name}(...)` with structured input
|
|
3. Task agent receives the input, works on it (may use tools, may chat with user)
|
|
4. Task agent calls `finish_task(...)` with structured output
|
|
5. Coordinator receives the result and responds to the user
|
|
|
|
### Example
|
|
|
|
```python
|
|
from google.adk import Agent
|
|
from pydantic import BaseModel
|
|
|
|
class ResearchInput(BaseModel):
|
|
topic: str
|
|
depth: str = 'standard'
|
|
|
|
class ResearchOutput(BaseModel):
|
|
summary: str
|
|
key_findings: str
|
|
confidence: str
|
|
|
|
def search_web(query: str) -> str:
|
|
"""Search the web for information."""
|
|
return f'Results for "{query}": ...'
|
|
|
|
def analyze_sources(sources: str) -> str:
|
|
"""Analyze and synthesize source material."""
|
|
return f'Analysis of {len(sources.split())} words complete.'
|
|
|
|
researcher = Agent(
|
|
name='researcher',
|
|
mode='task',
|
|
input_schema=ResearchInput,
|
|
output_schema=ResearchOutput,
|
|
instruction=(
|
|
'You are a research assistant. When given a topic:\n'
|
|
'1. Use search_web to find information.\n'
|
|
'2. Use analyze_sources to synthesize findings.\n'
|
|
'3. If the user asks for changes, adjust your research.\n'
|
|
'4. Call finish_task with summary, key_findings, and confidence.'
|
|
),
|
|
description='Researches topics using web search and analysis.',
|
|
tools=[search_web, analyze_sources],
|
|
)
|
|
|
|
root_agent = Agent(
|
|
name='coordinator',
|
|
model='gemini-2.5-flash',
|
|
sub_agents=[researcher],
|
|
instruction=(
|
|
'When the user asks you to research something, delegate to'
|
|
' the researcher using request_task_researcher. After the'
|
|
' researcher completes, summarize the results for the user.'
|
|
),
|
|
)
|
|
```
|
|
|
|
## Single-Turn Mode (`mode='single_turn'`)
|
|
|
|
A single-turn agent completes autonomously with no user interaction. It receives input, does its work, and returns a result.
|
|
|
|
### Example
|
|
|
|
```python
|
|
class SummaryOutput(BaseModel):
|
|
summary: str
|
|
word_count: int
|
|
key_points: str
|
|
|
|
def extract_text(url: str) -> str:
|
|
"""Extract text from a URL."""
|
|
return f'Extracted content from {url}: ...'
|
|
|
|
summarizer = Agent(
|
|
name='summarizer',
|
|
mode='single_turn',
|
|
output_schema=SummaryOutput,
|
|
instruction=(
|
|
'Summarize the document:\n'
|
|
'1. Use extract_text to get content.\n'
|
|
'2. Call finish_task with summary, word_count, key_points.\n'
|
|
'Complete autonomously without user interaction.'
|
|
),
|
|
description='Summarizes documents autonomously.',
|
|
tools=[extract_text],
|
|
)
|
|
|
|
root_agent = Agent(
|
|
name='coordinator',
|
|
model='gemini-2.5-flash',
|
|
sub_agents=[summarizer],
|
|
instruction='Delegate summarization to summarizer via request_task_summarizer.',
|
|
)
|
|
```
|
|
|
|
## Input and Output Schemas
|
|
|
|
### Custom Schemas (Pydantic Models)
|
|
|
|
Define `input_schema` and/or `output_schema` with Pydantic `BaseModel`:
|
|
|
|
```python
|
|
class TaskInput(BaseModel):
|
|
query: str
|
|
max_results: int = 10
|
|
format: str = 'text'
|
|
|
|
class TaskOutput(BaseModel):
|
|
results: str
|
|
count: int
|
|
status: str
|
|
|
|
agent = Agent(
|
|
name='worker',
|
|
mode='task',
|
|
input_schema=TaskInput, # Validates request_task_worker args
|
|
output_schema=TaskOutput, # Validates finish_task args
|
|
...
|
|
)
|
|
```
|
|
|
|
### Default Schemas
|
|
|
|
When no custom schema is provided:
|
|
|
|
**Default input** (used by `request_task_{name}`):
|
|
```python
|
|
class _DefaultTaskInput(BaseModel):
|
|
goal: str | None = None
|
|
background: str | None = None
|
|
```
|
|
|
|
**Default output** (used by `finish_task`):
|
|
```python
|
|
class _DefaultTaskOutput(BaseModel):
|
|
result: str
|
|
```
|
|
|
|
## Auto-Generated Tools
|
|
|
|
### `request_task_{agent_name}`
|
|
|
|
Auto-generated on the **coordinator** for each `mode='task'` or `mode='single_turn'` sub-agent. The tool name is `request_task_{agent.name}`.
|
|
|
|
- Parameters come from `input_schema` (or default: `goal`, `background`)
|
|
- Description includes the agent's `description` field
|
|
- Validates input against the schema before delegating
|
|
|
|
### `finish_task`
|
|
|
|
Auto-generated on the **task agent** itself. Called by the task agent when work is complete.
|
|
|
|
- Parameters come from `output_schema` (or default: `result`)
|
|
- Validates output against the schema before signaling completion
|
|
- Sets `tool_context.actions.finish_task` with a `TaskResult`
|
|
|
|
## Mixed-Mode Patterns
|
|
|
|
Combine task and single-turn agents under one coordinator:
|
|
|
|
```python
|
|
# Interactive: user can discuss options
|
|
flight_searcher = Agent(
|
|
name='flight_searcher',
|
|
mode='task',
|
|
input_schema=FlightSearchInput,
|
|
output_schema=FlightSearchOutput,
|
|
instruction='Search flights, discuss with user, then finish_task.',
|
|
description='Searches and books flights interactively.',
|
|
tools=[search_flights, book_flight],
|
|
)
|
|
|
|
# Autonomous: no user interaction
|
|
weather_checker = Agent(
|
|
name='weather_checker',
|
|
mode='single_turn',
|
|
output_schema=WeatherOutput,
|
|
instruction='Check weather and call finish_task. No user interaction.',
|
|
description='Checks weather for a destination.',
|
|
tools=[get_weather],
|
|
)
|
|
|
|
# Autonomous: no user interaction
|
|
hotel_finder = Agent(
|
|
name='hotel_finder',
|
|
mode='single_turn',
|
|
output_schema=HotelOutput,
|
|
instruction='Find hotels and call finish_task. No user interaction.',
|
|
description='Finds hotels for a destination.',
|
|
tools=[find_hotels],
|
|
)
|
|
|
|
root_agent = Agent(
|
|
name='travel_planner',
|
|
model='gemini-2.5-flash',
|
|
sub_agents=[flight_searcher, weather_checker, hotel_finder],
|
|
instruction=(
|
|
'Help users plan trips:\n'
|
|
'- request_task_weather_checker: autonomous weather check\n'
|
|
'- request_task_hotel_finder: autonomous hotel search\n'
|
|
'- request_task_flight_searcher: interactive flight booking'
|
|
),
|
|
)
|
|
```
|
|
|
|
## Key Rules
|
|
|
|
- Both task sub-agents and coordinators use `Agent` from `google.adk`
|
|
- Each sub-agent needs a `description` (used in the auto-generated tool description)
|
|
- `input_schema` and `output_schema` are optional; defaults are provided
|
|
- Sub-agents inherit model from the coordinator if not set
|
|
- `finish_task` instructions are auto-injected into the task agent's LLM context
|
|
- Single-turn agents receive an extra instruction telling them no user replies will come
|
|
|
|
## Task Mode vs Chat Mode
|
|
|
|
| Feature | Chat (`transfer_to_agent`) | Task (`request_task`) |
|
|
|---------|---------------------------|----------------------|
|
|
| Input | Free-form conversation | Structured (schema-validated) |
|
|
| Output | Free-form conversation | Structured (schema-validated) |
|
|
| Control flow | Agent decides when to transfer back | Agent calls `finish_task` |
|
|
| User interaction | Full chat | `task`: multi-turn; `single_turn`: none |
|
|
| Tool name | `transfer_to_agent` | `request_task_{name}` |
|
|
| Parallel delegation | Not supported | Supported (multiple `request_task` calls) |
|
|
|
|
## Source File Locations
|
|
|
|
| Component | File |
|
|
|-----------|------|
|
|
| Agent/LlmAgent (mode, schemas) | `src/google/adk/agents/llm_agent.py` |
|
|
| BaseLlmFlow (base flow class) | `src/google/adk/flows/llm_flows/base_llm_flow.py` |
|
|
| RequestTaskTool | `src/google/adk/agents/llm/task/_request_task_tool.py` |
|
|
| FinishTaskTool | `src/google/adk/agents/llm/task/_finish_task_tool.py` |
|
|
| TaskRequest, TaskResult | `src/google/adk/agents/llm/task/_task_models.py` |
|
|
| Task samples | `contributing/task_samples/` |
|