构建协作智能体团队¶
某些复杂任务可能需要多个具有特定职责的智能体,并从较松散的程序中获益,特别是对于包含多个重要子任务的迭代过程。在 ADK 的协作智能体团队中,一个协调者智能体处理向一个或多个子智能体的任务委派。这种方法使得构建复杂、自管理的智能体系统变得更加容易,子智能体被定义来处理特定任务,并在完成任务后自动返回到父智能体。
在使用这种自管理智能体团队方法时,子智能体会被分配一个运行模式来管理其行为并限制其工作范围。这些模式为子智能体设定了通用行为准则,并创建更可预测和可靠的多智能体工作流。以下是可用的协作模式设置:
- Chat(聊天):完全的用户交互,手动返回到父智能体(默认,当前行为)
- Task(任务):允许用户交互以进行澄清,自动返回到父智能体
- Single-turn(单轮):无用户交互,自动返回,可以并行运行
本指南介绍如何为子智能体使用模式以及这些模式如何影响智能体行为。
已禁用:基于图的工作流中的 Task 模式
协作模式 task 的行为在 ADK Python v2.0.0 中基于图的工作流中已被禁用。此功能预计将在未来的版本中重新启用。
开始使用¶
以下代码示例展示如何为一个小型子智能体团队设置运行模式,并将其分配给一个协调者智能体:
from google.adk import Agent
weather_agent = Agent(
name="weather_checker",
mode="single_turn", # 无用户交互
tools=[get_weather, user_info, geocode_address],
)
flight_agent = Agent(
name="flight_booker",
mode="task", # 可以向用户提问
input_schema=FlightInput,
output_schema=FlightResult,
tools=[search_flights, book_flight],
)
root = Agent(
name="travel_planner", # 协调者智能体
sub_agents=[weather_agent, flight_agent],
# 自动注入以每个子智能体命名的委派工具:
# weather_checker, flight_booker
)
在 ADK Go v2.0.0 中,llmagent.Config 上的 Mode 字段接受与 Python 相同的
模式字符串:"chat"、"task" 和 "single_turn"。在协调者智能体上声明
SubAgents 会导致 ADK 自动为每个子智能体生成一个委派工具,以子智能体自身命名,
与 Python 中的方式完全相同。
// Stub tool functions — in a real agent these call external services.
func getWeather(_ agent.Context, _ struct{ City string }) (string, error) {
return "Sunny, 22°C", nil
}
func searchFlights(_ agent.Context, _ struct{ Origin, Destination string }) (string, error) {
return "3 flights found", nil
}
func bookFlight(_ agent.Context, _ struct{ FlightID string }) (string, error) {
return "Flight booked", nil
}
// newCollaborativeTeam builds a coordinator agent with two subagents, each
// configured with a different collaboration mode. This is the Go equivalent of:
//
// weather_agent = Agent(name="weather_checker", mode="single_turn", ...)
// flight_agent = Agent(name="flight_booker", mode="task", ...)
// root = Agent(name="travel_planner", sub_agents=[weather_agent, flight_agent])
func newCollaborativeTeam(ctx context.Context) (agent.Agent, error) {
model, err := gemini.NewModel(ctx, "gemini-flash-latest", &genai.ClientConfig{})
if err != nil {
return nil, err
}
getWeatherTool, err := functiontool.New(functiontool.Config{
Name: "get_weather",
Description: "Returns the current weather for a city.",
}, getWeather)
if err != nil {
return nil, err
}
searchFlightsTool, err := functiontool.New(functiontool.Config{
Name: "search_flights",
Description: "Searches for available flights between two airports.",
}, searchFlights)
if err != nil {
return nil, err
}
bookFlightTool, err := functiontool.New(functiontool.Config{
Name: "book_flight",
Description: "Books a specific flight by ID.",
}, bookFlight)
if err != nil {
return nil, err
}
// weatherAgent runs in ModeSingleTurn: no user interaction, executes one
// turn and returns automatically. Equivalent to mode="single_turn" in Python.
weatherAgent, err := llmagent.New(llmagent.Config{
Name: "weather_checker",
Model: model,
Mode: llmagent.ModeSingleTurn,
Description: "Checks the current weather for a given city.",
Instruction: "Use the get_weather tool to look up the current weather.",
Tools: []tool.Tool{getWeatherTool},
})
if err != nil {
return nil, err
}
// flightAgent runs in ModeTask: may ask the user clarifying questions and
// automatically returns control to the coordinator when done. Equivalent to
// mode="task" in Python.
flightAgent, err := llmagent.New(llmagent.Config{
Name: "flight_booker",
Model: model,
Mode: llmagent.ModeTask,
Description: "Searches for and books flights.",
Instruction: "Help the user find and book a flight using the available tools.",
Tools: []tool.Tool{searchFlightsTool, bookFlightTool},
})
if err != nil {
return nil, err
}
// The coordinator agent declares SubAgents. ADK automatically generates
// weather_checker and flight_booker delegation tools, named after each
// subagent, so the coordinator can delegate work to each one.
return llmagent.New(llmagent.Config{
Name: "travel_planner",
Model: model,
Description: "Coordinator agent that delegates to weather and flight subagents.",
Instruction: "Help the user plan their trip. Use the weather checker and flight booker as needed.",
SubAgents: []agent.Agent{weatherAgent, flightAgent},
})
}
当你运行此工作流时,travel_planner 协调者智能体会自动识别任务并将其分配给子智能体。当子智能体完成任务后,它会自动返回到协调者智能体。有关使用input_schema和output_schema配合智能体、子智能体和工作流节点进行数据结构化的更多信息,请参阅智能体工作流的数据处理。
模式配置和行为¶
每种协作模式都有特定的行为和限制。下表比较了使用每种模式配置的子智能体的属性:
注意:模式仅适用于子智能体
mode设置专门用于由协调者父智能体调用的子智能体。不要为根智能体配置 mode 设置。
| 主题 \ 模式 | chat (default) |
task |
single_turn |
|---|---|---|---|
| 人在环中 | 完全交互 | 仅用于澄清 | 不允许 |
| 用户交互 | 用户自由与智能体聊天 | 智能体根据需要提问 | 无用户交互 |
| 控制流 | 智能体控制直到手动交接 | 智能体控制直到任务完成 | 任务完成后立即返回 |
| 并行执行 | 不支持 | 不支持 | 多个任务可以并行运行 |
| 返回父智能体 | 手动(通过 transfer) | 自动(通过 finish_task) |
自动(带结果) |
表 1. ADK 协作智能体模式行为和限制的比较。
运维注意事项¶
在使用协作智能体模式时,有一些控制转移和上下文管理的注意事项需要考虑,如下所述。
工作流节点和智能体转移¶
配置了task或single-turn模式的智能体可以用作工作流智能体图节点,并与LlmAgent实例一起使用。然而,执行转移行为会因调用方(或父)智能体的不同而有所不同:
作为工作流图节点:当 task 或 single-turn 智能体被置于工作流图中时——例如SequentialAgent或ParallelAgent(Python 和 Go 的预构建智能体),或在 ADK Go v2.0.0 图引擎中使用 workflow.NewAgentNode 包装——该智能体会执行其任务。完成后,控制会根据工作流智能体图的逻辑自动推进到下一个节点。
作为来自 LlmAgent 的转移接收方:当父LlmAgent通过以该子智能体命名的委派工具将控制权转移给 task 智能体时,task 智能体会执行直到调用 finish_task。此时,控制会自动返回到发起转移的原始智能体。此行为与默认的 chat 模式智能体不同,后者需要显式的 transfer_to_agent 调用来交回控制权。
| 调用上下文 | 任务完成后的结果 |
|---|---|
| 工作流节点 | 推进到图中的下一个节点 |
| 来自 LlmAgent 的转移 | 将控制权返回给原始智能体 |
这种区别使得同一个 task 智能体可以在两种上下文中重复使用而无需修改。运行时根据智能体的调用方式来决定适当的控制流。
智能体上下文隔离¶
每个task或single-turn模式的智能体在其自己隔离的会话分支中运行。当这些智能体并行运行时,每个智能体在构建 AI 模型调用的上下文时只能看到自己分支中的事件,而无法看到其对等智能体正在做什么。所有并行分支完成后,父智能体会收到收集的结果并继续执行。
已知限制¶
智能体协作模式存在一些已知限制:
- Task 模式智能体必须是叶子智能体,不能拥有子智能体。