GENAI106
概览
本实验介绍了如何在 Google 智能体开发套件 (Google ADK) 中编排多智能体系统。
本实验假定您已熟悉以下实验中介绍的 ADK 基础知识和工具使用方法:
- Google 智能体开发套件 (ADK) 使用入门
- 为 ADK 智能体配备工具
目标
在本实验中,您将执行以下操作:
- 创建多个智能体,并通过父智能体与子智能体关系将其相互关联起来。
- 通过写入会话的状态字典,跨多轮对话和多个智能体构建内容。
- 指示智能体从会话状态读取值,以用作其回答的上下文。
- 使用工作流智能体直接在智能体之间传递对话。
设置和要求
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。为此,我们会向您提供新的临时凭证,您可以在该实验的规定时间内通过此凭证登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的网络浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式(推荐)或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
注意:请仅使用学生账号完成本实验。如果您使用其他 Google Cloud 账号,则可能会向该账号收取费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个对话框供您选择支付方式。左侧是“实验详细信息”窗格,其中包含以下各项:
- “打开 Google Cloud 控制台”按钮
- 剩余时间
- 进行该实验时必须使用的临时凭证
- 完成实验所需的其他信息(如有)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示“登录”页面。
提示:将这些标签页安排在不同的窗口中,并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在“实验详细信息”窗格中找到“用户名”。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在“实验详细信息”窗格中找到“密码”。
-
点击下一步。
重要提示:您必须使用实验提供的凭证。请勿使用您的 Google Cloud 账号凭证。
注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
依次点击进入后续页面:
- 接受条款及条件。
- 由于这是临时账号,请勿添加账号恢复选项或双重身份验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需访问 Google Cloud 产品和服务,请点击导航菜单,或在搜索字段中输入服务或产品的名称。
多智能体系统
智能体开发套件旨在赋能开发者,使其生成模型能够更可靠地执行复杂的多步骤任务。您可以构建由多个简单智能体组成的流程,通过划分任务和责任让它们协作解决复杂问题,而不是编写冗长复杂且可能无法可靠地提供结果的提示。
这种架构方法具有一些关键优势,例如:
-
更易于设计:您可以基于具备专属职能和技能的智能体开展设计构思。
-
功能专用化,运行性能更稳定可靠:专用智能体可通过清晰的样本进行学习,在完成各自专项任务方面表现更加稳定可靠。
-
流程条理清晰:将工作流划分给不同的智能体,可形成结构层次清晰规整、逻辑更易梳理的设计方案。
-
易于优化与维护:相较于修改复杂的智能体(调整某一项行为可能会对其他功能造成连带影响),优化或修复单一专用组件会更加简便。
-
模块化:同一工作流中的不同智能体可轻松复制并复用至其他同类工作流中。
分层智能体树

在智能体开发套件中,您可以采用树状结构来整理智能体。这有助于限制树状结构中每个智能体的转移选项,从而更轻松地控制和预测对话在树状结构中可能经过的路径。分层结构的优势包括:
- 借鉴了现实世界中协作团队的运作模式,让多智能体系统的行为设计与分析推理变得更加简单。
-
对开发者来说非常直观,因为它与常见的软件开发模式类似。
- 可更好地控制系统内的信息流和任务委托,让您能够更轻松地了解可能的路径并调试系统。例如,如果一个系统在其流程的不同部分有两个说明相似的报告生成智能体,则树状结构可帮助您更轻松地确保调用正确的智能体。
该结构始终从 root_agent 变量中定义的智能体开始(尽管它可能使用其他面向用户的名称来标识自己)。root_agent 可以充当一个或多个子智能体的父智能体。每个子智能体也可以拥有自己的子智能体。
任务 1. 安装 ADK 并设置环境
本实验环境已为您启用 Agent Platform API。如果您要在自己的项目中执行这些步骤,可以前往 Agent Platform,然后按照提示启用该 API。
准备 Cloud Shell 编辑器标签页
- 在 Google Cloud 控制台窗口处于选中状态时,依次按下键盘上的 G 键和 S 键,打开 Cloud Shell。或者,您也可以点击 Cloud 控制台右上角的“激活 Cloud Shell”按钮 (
)。
- 点击继续。
- 如果系统提示您为 Cloud Shell 授权,请点击授权。
- 在 Cloud Shell 终端面板的右上角,点击在新窗口中打开按钮
。
- 点击窗格顶部的打开编辑器铅笔图标 (
) 即可查看文件。
- 在左侧导航菜单顶部,点击“资源管理器”图标 (
) 即可打开文件资源管理器。
- 点击打开文件夹按钮。
- 在出现的“打开文件夹”对话框中,点击确定,选择 Qwiklab 学员账号的主文件夹。
- 关闭屏幕右侧显示的任何其他教程或 Gemini 面板,在窗口中为代码编辑器腾出更多空间。
- 在接下来的实验过程中,您可以将此窗口作为 IDE 使用,直接利用其中的 Cloud Shell 编辑器和终端进行操作。
下载并安装本实验所需的 ADK 和代码示例
-
将以下命令粘贴到 Cloud Shell 终端中,以便从本实验的 Cloud Storage 存储桶中复制代码文件:
gcloud storage cp -r gs://{{{project_0.project_id| YOUR_GCP_PROJECT_ID}}}-bucket/* .
-
在 Cloud Shell 终端中运行以下命令,更新 PATH 环境变量,安装 ADK,并满足其他实验要求。
export PATH=$PATH:"/home/${USER}/.local/bin"
python3 -m pip install google-adk[otel-gcp]==1.30.0 -r adk_multiagent_systems/requirements.txt
任务 2. 了解父智能体、子智能体和同级智能体之间的转移
对话始终从定义为 root_agent 变量的智能体开始。
父智能体的默认行为是了解每个子智能体的说明,并确定是否应在任何时间点将对话控制权转移给子智能体。
您可以在父智能体的 instruction 中按名称(子智能体的 name 参数,而不是其变量名称)引用子智能体,从而帮助引导控制权的转移。尝试一个示例:
-
在 Cloud Shell 终端中,运行以下命令,在 parent_and_subagents 目录中创建一个 .env 文件,用于对智能体进行身份验证。
cd ~/adk_multiagent_systems
cat << EOF > parent_and_subagents/.env
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_PROJECT={{{project_0.project_id| YOUR_GCP_PROJECT_ID}}}
GOOGLE_CLOUD_LOCATION=global
MODEL={{{project_0.startup_script.gemini_flash_model_id | gemini_flash_model_id}}}
EOF
这些变量的作用如下:
-
GOOGLE_GENAI_USE_VERTEXAI=TRUE 表示您将使用 Agent Platform 完成身份验证,而不是使用 Gemini API 密钥。
-
GOOGLE_CLOUD_PROJECT 和 GOOGLE_CLOUD_LOCATION 提供模型调用关联的项目和位置。
-
MODEL 会存储在此处,好处是可作为另一个环境变量加载。
-
运行以下命令,将该 .env 文件复制到 workflow_agents 目录,稍后您将在实验中用到此目录:
cp parent_and_subagents/.env workflow_agents/.env
-
在 Cloud Shell 编辑器的“文件资源管理器”窗格中,前往 adk_multiagent_systems/parent_and_subagents 目录。
-
点击 agent.py 文件以将其打开。
提示:由于 Python 代码要求必须先定义子智能体,才能将其添加到父智能体中,因此,若要按照对话流程的顺序读取 agent.py 文件,您可能需要从底部智能体开始,逐步向上读取。
-
可以看到,这里有三个智能体:
- 一个名为
steering 的 root_agent(其名称用于在 ADK 的开发者界面和命令行界面中进行标识)。它会询问用户一个问题(是否已确定要去哪里旅行,或是否需要一些帮助来做出决定),用户对该问题的回答将帮助此引导智能体判断应将对话引导至两个子智能体中的哪一个。请注意,它只有一条简单的 instruction,其中并未提及子智能体,但它知道子智能体的说明。
- 一个 travel_brainstormer,当用户不确定要去哪里旅行时,协助其探索和筛选心仪的目的地。
- 一个 attractions_planner,在用户确定要前往的国家/地区后,帮助用户制定一份推荐活动清单。
-
通过在创建 root_agent 时添加以下代码行,使 travel_brainstormer 和 attractions_planner 成为 root_agent 的子智能体:
sub_agents=[travel_brainstormer, attractions_planner]
-
保存文件。
-
请注意,您无需向子智能体添加相应的 parent 参数。在创建父智能体时,仅需通过指定 sub_agents 即可定义层级树。
-
在 Cloud Shell 终端中,运行以下命令,使用 ADK 命令行界面与智能体聊天:
cd ~/adk_multiagent_systems
adk run parent_and_subagents
-
当系统显示 [user]: 提示时,请使用以下问候语向智能体打招呼:
hello
输出示例(您的输出可能略有不同):
[user]: hello
[steering]: Hello! Welcome to your travel adventure. Do you already know where you'd like to travel, or would you like some help deciding?
-
告诉智能体:
I could use some help deciding.
输出示例(您的输出可能略有不同):
[user]: I could use some help deciding.
[travel_brainstormer]: Hello! I'd love to help you decide on the perfect destination for your next trip.
To start, here are a few highly popular countries that travelers love:
* **Italy:** Famous for food, history, art, and beautiful landscapes.
* **Japan:** A unique blend of ultra-modern cities, ancient temples, stunning nature, and incredible cuisine.
* **Costa Rica:** A paradise for nature lovers, wildlife, and outdoor adventures.
* **France:** Renowned for world-class art, fashion, gastronomy, and romantic cities.
To help narrow things down to the perfect match for you, what are your primary goals for this trip? Are you looking for:
1. **Adventure** (hiking, wildlife, outdoor activities)
2. **Leisure** (relaxing on beaches, spas, slow-paced exploring)
3. **Learning** (history, museums, exploring different cultures)
4. **Shopping** (fashion, local markets, unique finds)
5. **Viewing Art** (galleries, architecture, world-famous masterpieces)
Let me know what sounds most exciting to you, or if you have a mix of these in mind!
-
从回答中方括号内的名称 [travel_brainstormer] 可以看出,root_agent(名为 [steering])已仅根据相应子智能体的 description 将对话转移到该子智能体。
-
在 user: 提示处,输入 exit 以结束对话。
-
您还可以在智能体的 instructions 中提供更详细的指令,说明何时将对话转移到子智能体。在 agent.py 文件中,将以下几行内容添加到 root_agent 的 instruction 中:
If they need help deciding, send them to
'travel_brainstormer'.
If they know what country they'd like to visit,
send them to the 'attractions_planner'.
-
保存文件。
-
在 Cloud Shell 终端中,运行以下命令,重新启动命令行界面:
adk run parent_and_subagents
-
使用以下问候语向智能体问好:
hello
-
使用以下内容回复智能体的问候:
I would like to go to Japan.
输出示例(您的输出可能略有不同):
[user]: I would like to go to Japan.
[attractions_planner]: Japan is an incredible destination with a perfect blend of ancient traditions and futuristic cities!
Here are some of the top attractions and regions to consider for your trip, categorized by the type of experience:
### 1. **The Modern & Futuristic (Tokyo)**
* **Shibuya Crossing & Harajuku:** Experience the bustling energy of the world's busiest pedestrian crossing and the quirky fashion of Takeshita Street.
* **teamLab Planets:** An immersive, digital-art museum where you walk through water and interact with stunning light projections.
* **Senso-ji Temple:** Tokyo's oldest and most iconic Buddhist temple, located in the historic Asakusa district.
### 2. **History & Tradition (Kyoto & Nara)**
* **Fushimi Inari Shrine (Kyoto):** Famous for its path of thousands of vibrant red torii gates winding up the mountain.
* **Kinkaku-ji (The Golden Pavilion, Kyoto):** A breathtaking Zen temple covered in gold leaf, reflecting over a serene pond.
* **Nara Park (Nara):** Home to hundreds of freely roaming, bowing deer and the massive Great Buddha statue at Todai-ji Temple.
### 3. **Nature & Scenic Views**
* **Mount Fuji & Lake Kawaguchiko:** Enjoy stunning views of Japan's iconic volcano, especially beautiful during cherry blossom or autumn foliage seasons.
* **Arashiyama Bamboo Grove (Kyoto):** Walk through a towering forest of green bamboo that feels like another world.
### 4. **Food & Entertainment (Osaka)**
* **Dotonbori:** Osaka's neon-lit food street, famous for street foods like *takoyaki* (octopus balls) and *okonomiyaki* (savory pancakes).
* **Osaka Castle:** A magnificent historic landmark surrounded by a massive park and moat.
---
To help me tailor the perfect itinerary for you, **what kinds of things are you most interested in?**
* Historic temples and shrines?
* Modern city life and pop culture (anime, gaming, shopping)?
* Nature, hiking, and scenic landscapes?
* Incredible food and culinary experiences?
Let me know, and we can start building your custom list of stops!
-
可以看到,您已转移到另一个子智能体 attractions_planner。
-
用以下内容回复:
Actually I don't know what country to visit.
输出示例(您的输出可能略有不同):
user: actually I don't know what country to visit
[travel_brainstormer]: Okay! I can help you brainstorm some countries for travel...
-
可以看到,您已转移到 travel_brainstormer 智能体,该智能体是 attractions_planner 的同级智能体。默认情况下允许转移到同级智能体。如果您想阻止转移到同级智能体,可以将 attacks_planner 智能体的 disallow_transfer_to_peers 参数设置为 True。
-
在用户提示处,输入 exit 以结束会话。
分步处理模式:如果您需要设计一个智能体,引导用户逐步完成某个流程,一种实用的模式是:将负责第一步的智能体设为 root_agent,将负责第二步的智能体设为其唯一子智能体,然后继续将负责后续每一步的智能体设为前一步智能体的唯一子智能体。
点击检查我的进度以验证是否完成了以下目标:
了解父智能体、子智能体和同级智能体之间的转移
任务 3. 使用会话状态存储和检索特定信息
ADK 中的每个对话都包含在一个 Session 中,参与对话的所有智能体都可以访问该会话。会话包含对话历史记录,智能体会读取这些历史记录,作为生成回答时使用的上下文的一部分。会话还包含一个会话状态字典,您可以使用该字典更好地控制要突出显示的最重要信息以及这些信息的访问方式。
这对于在智能体之间传递信息或在与用户的对话过程中维持简单的数据结构(例如任务列表)特别有用。
如需了解如何向状态添加内容以及如何从状态读取内容,请执行以下操作:
-
返回到文件 adk_multiagent_systems/parent_and_subagents/agent.py
-
将以下函数定义粘贴到 # Tools 标题后面:
def save_attractions_to_state(
tool_context: ToolContext,
attractions: List[str]
) -> dict[str, str]:
"""Saves the list of attractions to state["attractions"].
Args:
attractions [str]: a list of strings to add to the list of attractions
Returns:
None
"""
# Load existing attractions from state. If none exist, start an empty list
existing_attractions = tool_context.state.get("attractions", [])
# Update the 'attractions' key with a combo of old and new lists.
# When the tool is run, ADK will create an event and make
# corresponding updates in the session's state.
tool_context.state["attractions"] = existing_attractions + attractions
# A best practice for tools is to return a status message in a return dict
return {"status": "success"}
-
在此代码中,可以看到:
- 会话作为
ToolContext 传递给您的工具函数。您只需分配一个参数来接收它,如您在此处看到的名为 tool_context 的参数。然后,您可以通过 tool_context 访问会话信息,例如对话历史记录(通过 tool_context.events)和会话状态字典(通过 tool_context.state)。当您的工具函数修改 tool_context.state 字典时,相应更改会在工具完成执行后反映在会话的状态中。
- 文档字符串提供了清晰的说明,并包含实参和返回值部分。
- 带注释的函数代码展示了更新状态字典有多么简单。
-
在创建智能体时添加 tools 参数,将该工具添加到 attractions_planner 智能体:
tools=[save_attractions_to_state]
-
将以下要点添加到 attractions_planner 智能体的现有 instruction 中:
- When they reply, use your tool to save their selected attraction
and then provide more possible attractions.
- If they ask to view the list, provide a bulleted list of
{ attractions? } and then suggest some more.
-
请注意大括号部分:{ attractions? }。此 ADK 功能(键模板)从状态字典中加载 attractions 键的值。attractions 键后面的问号可防止在相应字段尚不存在时出现错误。
-
现在,您将通过网页界面运行智能体,该界面提供了一个标签页,用于查看对会话状态所做的更改。使用以下命令启动智能体开发套件网页界面:
adk web --allow_origins "regex:https://.*\.cloudshell\.dev"
输出
INFO: Started server process [2434]
INFO: Waiting for application startup.
+-------------------------------------------------------+
| ADK Web Server started |
| |
| For local testing, access at http://localhost:8000. |
+-------------------------------------------------------+
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-
如需在新标签页中查看网页界面,请点击终端输出中的 http://127.0.0.1:8000 链接。
-
系统即会在一个新浏览器标签页中打开 ADK 开发者界面。
-
从左侧的选择智能体下拉菜单中,选择 parent_and_subagents 智能体。
-
输入 hello 发起对话
-
在智能体向您问好后,回复以下内容:
I'd like to go to Egypt.
您应该会被转移到 attractions_planner,并获得景点列表。
-
选择一个景点,例如:
I'll go to the Sphinx
-
您收到的回答中应该会包含确认内容,例如:Okay, I've saved The Sphinx to your list. Here are some other attractions…
-
点击回答工具箱(带有对勾标记),查看根据工具的回答创建的事件。可以看到,它包含一个 actions 字段,该字段内的 state_delta 描述了状态的更改情况。
-
智能体应该会提示您选择更多景点。通过说出智能体提供的某个选项进行回复。
-
在左侧导航菜单中,点击“X”以退出之前查看的事件聚焦状态。
-
现在,您应该会在边栏中看到事件列表和几个标签页选项。选择状态标签页。在这里,您可以查看当前状态,包括具有您请求的两个值的 attractions 数组。

-
向智能体发送以下消息:
What is on my list?
-
智能体应该会根据其 instruction 以项目符号列表的格式返回您的列表。
-
试用智能体后,关闭网络浏览器标签页,然后在 Cloud Shell 终端中按 CTRL + C 停止服务器。
在本实验的后续部分,您将演示如何使用状态在智能体之间进行通信。
点击检查我的进度以验证是否完成了以下目标:
使用会话状态存储和检索特定信息
如果您想将智能体的完整文本回答存储在状态字典中(而非保存零散信息),可以在定义智能体时设置 output_key 参数,这样智能体的完整输出将会以该字段名称存储在状态字典中。
工作流智能体
如果您有多个专业子智能体,并且希望用户与每个子智能体互动,那么从父智能体到子智能体的转移非常适合。
不过,如果您希望智能体无需等待用户回应便可依次执行操作,可以使用工作流智能体。以下是一些您可能会使用工作流智能体的示例场景:
-
规划和执行:您需要让一个智能体准备项目列表,然后让其他智能体使用该列表执行后续任务,例如撰写文档的各个部分
-
研究和写作:您需要让一个智能体调用函数从 Google 搜索或其他数据源收集上下文信息,然后让另一个智能体使用该信息生成一些输出
-
起草和修订:您需要让一个智能体准备文档草稿,然后让其他智能体检查该草稿并进行迭代
为了完成这些类型的任务,工作流智能体设有不同的子智能体,并能确保每个子智能体都执行相应操作。智能体开发套件提供 3 个内置工作流智能体,并允许您定义自己的智能体:
SequentialAgent
LoopAgent
ParallelAgent
在本实验的剩余部分中,您将构建一个多智能体系统,该系统使用多个 LLM 智能体、工作流智能体和工具来帮助控制智能体的流程。
具体而言,您将构建一个智能体,用于为一部新的热门电影(一部根据某位历史人物生平改编的传记片)撰写宣传文案。您有子智能体负责研究,screenwriter 和 critic 会进行迭代式写作,还有一些子智能体帮助您集思广益,提出选角想法,并使用历史票房数据对票房结果进行预测。
最后,您的多智能体系统将如下所示(您可以点击图片放大查看):

不过,您将从一个更简单的版本着手。
任务 4. 使用 SequentialAgent 开始构建多智能体系统
SequentialAgent 按线性序列执行其子智能体。其 sub_agents 列表中的各个子智能体会按照指定顺序依次运行。
这非常适合具有以下特征的工作流:必须按特定顺序执行任务,且一个任务的输出会作为下一个任务的输入。
在此任务中,您将运行 SequentialAgent 来构建电影宣传多智能体系统的第一个版本。智能体的初稿将采用以下结构:

-
在 Cloud Shell 编辑器中,前往 adk_multiagent_systems/workflow_agents 目录。
-
点击 workflow_agents 目录中的 agent.py 文件。
-
通读此智能体定义文件。由于必须先定义子智能体,然后才能将其分配给父智能体,因此若要按照对话流程的顺序读取该文件,您可以从文件底部往上读取智能体。
-
您还有一个函数工具 append_to_state。此函数允许使用该工具的智能体向状态中的字典值添加内容。对于可能会多次调用工具或在 LoopAgent 的多轮迭代中执行操作的智能体,此函数特别有用,因为这可使智能体每次执行操作时的输出都得到存储。
-
从 Cloud Shell 终端启动网页界面,试用当前版本的智能体。您将使用 --reload_agents 实参启用基于智能体变更实时重新加载的功能:
cd ~/adk_multiagent_systems
adk web --allow_origins "regex:https://.*\.cloudshell\.dev" --reload_agents
注意:如果您未关闭之前的 adk web 会话,默认端口 8000 将被屏蔽,但您可以通过新端口启动开发者界面,例如使用 adk web --port 8001。
-
如需在新标签页中查看网页界面,请点击终端输出中的 http://127.0.0.1:8000 链接。
-
系统即会在一个新浏览器标签页中打开 ADK 开发者界面。
-
从左侧的选择智能体下拉菜单中,选择 workflow_agents。
-
输入 hello 发起对话。智能体可能需要一些时间才能做出回答,但它应该会要求您输入一位历史人物,以便开始生成电影情节。
-
当系统提示您输入历史人物时,您可以输入自己选择的人物,也可以使用以下示例之一:
-
Zhang Zhongjing - 公元 2 世纪中国著名医学家。
-
Ada Lovelace - 英国数学家兼作家,以其在早期计算机领域的工作而闻名
-
Marcus Aurelius - 以哲学著作而闻名的罗马皇帝。
-
现在,智能体应该会在执行工作流时依次调用其子智能体,并将情节大纲文件写入 ~/adk_multiagent_systems/movie_pitches 目录。文件写入磁盘后,智能体应该会通知您。
如果您没有看到智能体报告为您生成了文件,或者您想尝试另一位历史人物,可以点击右上角的 + 新建会话,然后重试。
-
在 Cloud Shell 编辑器中查看智能体的输出。(您可能需要在 Cloud Shell 编辑器菜单中依次点击“视图”>“自动换行”,以便在不进行频繁水平滚动的情况下查看完整文本。)
-
在 ADK 开发者界面中,点击代表一轮对话的某个智能体图标 (
) 以查看事件视图。
-
事件视图直观地展示了此会话中使用的智能体和工具树。您可能需要在事件面板中滚动才能看到完整的情节。

- 除了图表视图之外,您还可以点击事件的请求标签页,查看智能体收到的作为请求一部分的信息,包括对话历史记录。
- 您也可以点击事件的回答标签页,查看智能体返回的内容。
注意:虽然此系统可以生成有趣的结果,但我们并非暗示指令可以如此简短,或者可以跳过添加示例的步骤。如果为每个智能体添加更为详尽的指令和示例,系统的可靠性将大大提高。
点击检查我的进度以验证是否完成了以下目标:
使用 SequentialAgent 开始构建多智能体系统
任务 5. 添加 LoopAgent 以进行迭代工作
LoopAgent 会按指定序列执行其子智能体,然后再次从序列的开头开始执行,不会因用户输入而中断。它会持续循环执行,直到达到一定迭代次数或其中一个子智能体发出退出循环的指令(通常是通过调用内置的 exit_loop 工具来实现)。
这对于需要持续优化、监控或循环工作流的任务而言大有裨益。例如:
-
迭代优化:通过重复的智能体循环不断改进文档或方案。
-
持续监控:使用一系列智能体定期检查数据源或条件。
-
辩论或协商:模拟智能体之间的迭代讨论,以获得更好的结果。
您将向电影宣传智能体添加 LoopAgent,以便在构思故事时进行多轮研究和迭代。除完善剧本外,这还支持用户输入模糊需求:用户无需指定具体历史人物,仅需明确想要一个以古代医者为主角的故事,智能体便能通过研究和写作迭代循环找到合适人选,然后开始创作故事。

修改后的智能体将按此流程运行:
-
root_agent greeter 将保持不变。
-
film_concept_team
SequentialAgent 现在将包含:
-
writers_room
LoopAgent,将启动该序列。它包含:
-
researcher,将与之前相同。
-
screenwriter,将与之前类似。
-
critic,将针对当前草稿提供批判性反馈意见,以推动循环中下一轮的研究和改进。
- 当循环终止时,它会将对话控制权交还给 film_concept_team
SequentialAgent,后者随后会将控制权传递给序列中的下一个智能体 file_writer,该智能体将像之前一样为电影命名并将序列的结果写入文件。
如需进行这些更改,请执行以下操作:
-
在 adk_multiagent_systems/workflow_agents/agent.py 文件中,添加以下工具导入语句,使智能体能够在需要时退出循环:
from google.adk.tools import exit_loop
from google.adk.models import Gemini
-
为了确定何时退出循环,可以添加此 critic 智能体,由其判定情节大纲何时准备就绪。将以下新智能体代码粘贴到 agent.py 文件的 # Agents 部分标题下(不要覆盖现有智能体代码)。请注意,它将 exit_loop 工具作为其工具之一,并提供了有关何时使用该工具的说明:
critic = Agent(
name="critic",
model=Gemini(model=model_name, retry_options=RETRY_OPTIONS),
description="Reviews the outline so that it can be improved.",
instruction="""
INSTRUCTIONS:
Consider these questions about the PLOT_OUTLINE:
- Does it meet a satisfying three-act cinematic structure?
- Do the characters' struggles seem engaging?
- Does it feel grounded in a real time period in history?
- Does it sufficiently incorporate historical details from the RESEARCH?
If the PLOT_OUTLINE does a good job with these questions, exit the writing loop with your 'exit_loop' tool.
If significant improvements can be made, use the 'append_to_state' tool to add your feedback to the field 'CRITICAL_FEEDBACK'.
Explain your decision and briefly summarize the feedback you have provided.
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
RESEARCH:
{ research? }
""",
before_model_callback=log_query_to_model,
after_model_callback=log_model_response,
tools=[append_to_state, exit_loop]
)
-
创建一个名为 writers_room 的新 LoopAgent,用于创建 researcher、screenwriter 和 critic 的迭代循环。每次循环结束时,都会对当前已完成的工作进行批判性审查,从而为下一轮改进提供指引。将以下内容粘贴到现有 film_concept_team SequentialAgent 的上方。
writers_room = LoopAgent(
name="writers_room",
description="Iterates through research and writing to improve a movie plot outline.",
sub_agents=[
researcher,
screenwriter,
critic
],
max_iterations=5,
)
-
请注意,在创建 LoopAgent 时,包含了一个 max_iterations 参数。此参数用于定义循环在结束之前将运行的次数。即使您打算通过其他方法中断循环,最好还是对总迭代次数予以限制。
-
更新 film_concept_team SequentialAgent,以将 researcher 和 screenwriter 替换为您刚刚创建的 writers_room LoopAgent。file_writer 智能体应保留在序列末尾。film_concept_team 现在应如下所示:
film_concept_team = SequentialAgent(
name="film_concept_team",
description="Write a film plot outline and save it as a text file.",
sub_agents=[
writers_room,
file_writer
],
)
-
返回 ADK 开发者界面标签页,然后点击右上角的 + 新建会话按钮,以开启新会话。
-
输入 hello 发起新对话
-
当系统提示您选择历史人物类型时,选择您感兴趣的类型。下面的一些想法供您参考:
-
an industrial designer who made products for the masses(一位为大众设计产品的工业设计师)
-
a cartographer (a map maker)(制图师 [地图制作者])
-
that guy who made crops yield more food(让农作物增产的人)
-
您选择人物类型后,智能体应按循环迭代流程逐步推进,最终为电影命名并将大纲写入文件。
-
使用 Cloud Shell 编辑器查看生成的文件,该文件应保存在 adk_multiagent_systems/movie_pitches 目录中。(您可能需要再次在 Cloud Shell 编辑器菜单中依次点击“视图”>“自动换行”,以便在不进行频繁水平滚动的情况下查看完整文本。)
点击检查我的进度以验证是否完成了以下目标:
添加 LoopAgent 以进行迭代工作
任务 6. 使用 ParallelAgent 的“扇出和收集”模式生成报告
ParallelAgent 支持并发执行其子智能体。每个子智能体在各自的分支中运行,默认情况下,它们在并行执行期间不会直接共享对话历史记录或状态。
它非常适合可拆分为多个能够并行处理的独立子任务的任务。使用 ParallelAgent 可以显著缩短此类任务的总体执行时间。
在本实验中,您将添加一些补充性报告(包括有关潜在票房表现的一些研究和有关选角的一些初步想法),以增强新电影的宣传效果。

修改后的智能体将按此流程运行:
-
greeter 将保持不变。
-
film_concept_team
SequentialAgent 现在将包含:
-
writers_room
LoopAgent,它将保持不变,包括:
-
researcher 智能体
-
screenwriter 智能体
-
critic 智能体
- 接着,新的 preproduction_team
ParallelAgent 将执行操作,它包含:
-
box_office_researcher 智能体,用于根据历史票房数据生成有关这部电影潜在票房表现的报告
-
casting_agent 智能体,用于根据出演过类似电影的演员生成有关选角的初步想法
-
file_writer 将保持不变,用于将序列的结果写入文件。
虽然此示例的许多内容展现的是由人类团队完成的创造性工作,但这一工作流体现了如何将复杂的任务链拆分给多个子智能体处理,从而生成复杂文档的草稿,供人类团队成员修改和改进。
-
将以下新智能体和 ParallelAgent 粘贴到 workflow_agents/agent.py 文件的 # Agents 标题下:
box_office_researcher = Agent(
name="box_office_researcher",
model=Gemini(model=model_name, retry_options=RETRY_OPTIONS),
description="Considers the box office potential of this film",
instruction="""
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
INSTRUCTIONS:
Write a report on the box office potential of a movie like that described in PLOT_OUTLINE based on the reported box office performance of other recent films.
""",
output_key="box_office_report"
)
casting_agent = Agent(
name="casting_agent",
model=Gemini(model=model_name, retry_options=RETRY_OPTIONS),
description="Generates casting ideas for this film",
instruction="""
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
INSTRUCTIONS:
Generate ideas for casting for the characters described in PLOT_OUTLINE
by suggesting actors who have received positive feedback from critics and/or
fans when they have played similar roles.
""",
output_key="casting_report"
)
preproduction_team = ParallelAgent(
name="preproduction_team",
sub_agents=[
box_office_researcher,
casting_agent
]
)
-
更新现有 film_concept_team 智能体的 sub_agents 列表,在 writers_room 和 file_writer 之间添加 preproduction_team:
film_concept_team = SequentialAgent(
name="film_concept_team",
description="Write a film plot outline and save it as a text file.",
sub_agents=[
writers_room,
preproduction_team,
file_writer
],
)
-
将 file_writer 的 instruction 更新为:
INSTRUCTIONS:
- Create a marketable, contemporary movie title suggestion for the movie described in the PLOT_OUTLINE. If a title has been suggested in PLOT_OUTLINE, you can use it, or replace it with a better one.
- Use your 'write_file' tool to create a new txt file with the following arguments:
- for a filename, use the movie title
- Write to the 'movie_pitches' directory.
- For the 'content' to write, include:
- The PLOT_OUTLINE
- The BOX_OFFICE_REPORT
- The CASTING_REPORT
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
BOX_OFFICE_REPORT:
{ box_office_report? }
CASTING_REPORT:
{ casting_report? }
-
保存文件。
-
在 ADK 开发者界面中,点击右上角的 + 新建会话。
-
输入 hello 以发起对话。
-
当系统提示时,输入一个您感兴趣的新人物想法。下面的一些想法供您参考:
-
that actress who invented the technology for wifi(发明了 Wi-Fi 技术的女演员)
-
an exciting chef(一位出色的厨师)
-
key players in the worlds fair exhibitions(世界博览会展览中的关键人物)
-
当智能体完成编写并生成报告后,检查其在 adk_multiagent_systems/movie_pitches 目录中生成的文件。如果流程的某个环节失败,请点击右上角的 + 新建会话,然后重试。
自定义工作流智能体
如果预定义工作流智能体 SequentialAgent、LoopAgent 和 ParallelAgent 无法满足您的需求,CustomAgent 可让您灵活地实现新的工作流逻辑。您可以定义子智能体之间的流控制、条件执行或状态管理模式。这适用于复杂的工作流、有状态的编排,或将自定义业务逻辑集成到框架的编排层中。
创建 CustomAgent 不在本实验范围内,不过了解其存在以备不时之需也是很有益处的!
恭喜!
在本实验中,您学习了如何创建多个代理,并通过父代理与分代理关系将它们相互关联;如何在会话状态中添加内容并在代理指令中读取该内容;以及如何使用工作流代理直接在代理之间传递对话。
Google Cloud 培训和认证
…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您检验并证明您在 Google Cloud 技术方面的技能与专业知识。
上次更新手册的时间:2026 年 7 月 26 日
上次测试实验的时间:2026 年 7 月 26 日
版权所有 2026 Google LLC。保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名称和产品名称可能是其各自相关公司的商标。