使用 ADK 构建多智能体系统

1. 简介

概览

本实验将教您如何使用 Google 智能体开发套件 (Google ADK) 来编排复杂的多智能体系统。您将从简单的代理层次结构过渡到构建自动化协作式工作流。

构建内容

您将构建两个不同的多智能体系统:

  • 一个简单的旅游规划代理,可学习在“头脑风暴”代理和“景点规划”代理之间转移对话。
  • 一种更高级的电影推介生成器,它使用由自动化智能体(如研究员、编剧和影评人)组成的“编剧室”以循环方式协同工作,从而创建完整的电影情节。

学习内容

  • 如何创建父代理和子代理关系。
  • 如何从工具将数据写入会话 state
  • 如何使用键模板(例如,state{my_key?})。
  • 如何使用 SequentialAgent 创建分步工作流。
  • 如何使用 LoopAgent 创建迭代优化周期。
  • 如何使用 ParallelAgent 并发运行独立任务。

2. 多智能体系统

借助智能体开发套件 (ADK),开发者可以从生成式模型中获得更可靠、更复杂的多步行为。借助 ADK,您可以构建由多个更简单的智能体组成的流程,这些智能体通过分工协作来解决问题,而不是使用一个复杂的提示。

与使用单个单体式提示相比,这种方法具有以下几项优势:

  • 设计更简单:与设计一个大型复杂提示相比,设计和组织小型专业代理的流程更简单。
  • 可靠性:与大型复杂代理相比,专业代理在执行特定任务时更可靠。
  • 可维护性:可以更轻松地修复或改进小型专用代理,而不会破坏系统的其他部分。
  • 模块化:为某个工作流构建的代理可以轻松地在其他工作流中重复使用。

分层代理树

显示分层代理的树状结构

在 ADK 中,您可以采用树状结构来整理代理。此层次结构对于控制对话流程至关重要,因为它限制了哪个代理可以将对话“传递”给哪个其他代理。这样一来,系统行为会更易于预测,也更易于调试。福利包括:

  • 直观的设计:该结构的设计灵感源自现实世界的团队,因此更容易理解。
  • 受控流程:层次结构可让您精确控制任务委托,有助于进行调试。例如,即使您有两个描述类似的报告撰写代理,树结构也能确保调用正确的代理。

整个结构以 root_agent 开头。此代理充当父级,可以有一个或多个子代理,而子代理也可以是其自己的子代理的父级,从而形成树。

3. 项目设置

Google 账号

如果您还没有个人 Google 账号,则必须先创建一个 Google 账号

请使用个人账号,而不是工作账号或学校账号。

登录 Google Cloud 控制台

使用个人 Google 账号登录 Google Cloud 控制台

启用结算功能

兑换 5 美元的 Google Cloud 赠金(可选)

如需参加此研讨会,您需要拥有一个有一定信用额度的结算账号。如果您打算使用自己的结算方式,则可以跳过此步骤。

  1. 点击此链接,然后使用个人 Google 账号登录。您会看到类似以下内容:点击此处前往“赠金”页面
  2. 点击点击此处以访问您的积分按钮。系统会将您转到用于设置结算资料的页面“设置结算资料”页面
  3. 点击确认

您现在已关联到 Google Cloud Platform 试用结算账号。

结算概览的屏幕截图

设置个人结算账号

如果您使用 Google Cloud 抵用金设置了结算,则可以跳过此步骤。

如需设置个人结算账号,请点击此处在 Cloud 控制台中启用结算功能

注意事项:

  • 完成本实验的 Cloud 资源费用应不到 1 美元。
  • 您可以按照本实验结束时的步骤删除资源,以避免产生更多费用。
  • 新用户符合参与 $300 USD 免费试用计划的条件。

创建项目(可选)

如果您没有想要用于此实验的当前项目,请在此处创建一个新项目

4. 打开 Cloud Shell Editor

  1. 点击此链接可直接前往 Cloud Shell 编辑器
  2. 如果系统在今天任何时间提示您进行授权,请点击授权继续。点击以授权 Cloud Shell
  3. 如果终端未显示在屏幕底部,请打开它:
    • 点击查看
    • 点击终端在 Cloud Shell 编辑器中打开新终端
  4. 在终端中,使用以下命令设置项目:
    gcloud config set project [PROJECT_ID]
    
    • 示例:
      gcloud config set project lab-project-id-example
      
    • 如果您不记得自己的项目 ID,可以使用以下命令列出所有项目 ID:
      gcloud projects list
      
      在 Cloud Shell 编辑器终端中设置项目 ID
  5. 您应会看到以下消息:
    Updated property [core/project].
    

5. 启用 API

如需使用 Vertex AI API 并与 Gemini 模型互动,您需要在 Google Cloud 项目中启用 Vertex AI API。

  1. 在终端中,启用该 API:
    gcloud services enable aiplatform.googleapis.com
    

以下是更新后的部分,其中将手动创建文件替换为克隆 GitHub 代码库和安装依赖项的说明。

Python 版 Vertex AI SDK 简介

如需通过 Python 应用与 Vertex AI 上托管的模型进行交互,您需要使用 Vertex AI SDK for Python。此 SDK 简化了发送提示、指定模型参数和接收响应的过程,无需直接处理底层 API 调用的复杂性。

您可以在以下位置找到有关 Vertex AI SDK for Python 的全面文档:Vertex AI SDK for Python 简介 | Google Cloud

6. 设置项目环境

克隆代码库

  1. 终端中,克隆包含起始文件的代码库。
    git clone --depth 1 https://github.com/GoogleCloudPlatform/devrel-demos.git
    
    --depth 1 标志仅克隆最新版本,速度更快。
  2. 终端中,前往本实验的正确工作目录。
    cd devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    

激活虚拟环境

  1. 终端中,使用 uv 创建并激活虚拟环境:
    uv venv
    source .venv/bin/activate
    
  2. 终端中,安装 google-adkrequirements.txt 文件中的其他依赖项:
    uv pip install -r requirements.txt
    

查看文件结构

现在,所有文件都已创建完毕,请在资源管理器中打开 adk_multiagent_systems 文件夹,查看完整结构。

  1. 在 Cloud Shell 编辑器菜单中,选择文件 > 打开文件夹…
    Cloud Shell 编辑器的“文件”菜单,其中“打开文件夹”处于选中状态
  2. 在随即显示的框中,在您的用户名后添加以下文件夹信息:devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems/。点击确定
    结果应如下所示:
    打开包含项目路径的“打开文件夹”对话框
  3. 左侧的“探索器”面板将刷新。现在,您应该会看到完整的项目结构,其中包含 parent_and_subagentsworkflow_agents 子目录,可以进行后续步骤了。
    显示打开的 adk_multiagent_systems 文件夹的探索器面板

设置环境变量

  1. 您已位于 adk_multiagent_systems 目录中。在终端中,创建一个 .env 文件来存储环境变量:
    cloudshell edit .env
    
  2. 将以下内容粘贴到编辑器中打开的 .env 文件中:
    GOOGLE_GENAI_USE_VERTEXAI=TRUE
    GOOGLE_CLOUD_PROJECT="[YOUR-PROJECT-ID]"
    GOOGLE_CLOUD_LOCATION=global
    MODEL="gemini-2.5-flash"
    
  3. [YOUR-PROJECT-ID] 替换为您的实际 Google Cloud 项目 ID。(例如 PROJECT_ID = "google-cloud-labs"
    如果您忘记了项目 ID,请在终端中运行以下命令。系统会显示您的所有项目及其 ID 的列表。
    gcloud projects list
    
  4. 终端中,将此 .env 文件复制到子代理目录中,以便它们也能访问这些变量:
    cp .env parent_and_subagents/.env
    cp .env workflow_agents/.env
    
    文件结构现在应如下所示:
    显示打开的 adk_multiagent_systems 文件夹的探索器面板

7. 了解父代理、子代理和同级代理之间的转移

对话始终以 root_agent 开头。默认情况下,父代理会使用其子代理的 description 来决定何时转移对话。您还可以通过使用子代理的 name 在父代理的 instruction 中明确指导这些转移。

我们来测试一下。

  1. 在 Cloud Shell 编辑器中,打开 adk_multiagent_systems/parent_and_subagents/agent.py。请注意 agent.py 文件中的三个代理:
    • root_agent(命名为 steering:向用户提出问题,以确定要转接到的子代理。最初,它仅依赖于其子代理的 description
    • travel_brainstormer:帮助用户集思广益,寻找目的地。
    • attractions_planner:帮助用户列出特定国家/地区要做的事情。
  2. 通过在 root_agent 的创建中添加以下行,使 travel_brainstormerattractions_planner 成为 root_agent 的子代理:
        sub_agents=[travel_brainstormer, attractions_planner]
    
  3. 终端中,与代理聊天:
    cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    adk run parent_and_subagents
    
  4. 终端中的 [user]: 提示符处,输入:
    hello
    
    输出示例(您的输出可能略有不同):
    [steering]: Hi there! Do you already have a country in mind for your trip, or would you like some help deciding where to go?
    
  5. 现在,在终端中告知代理:
    I could use some help deciding.
    
    输出示例(您的输出可能略有不同):
    [travel_brainstormer]: Okay! To give you the best recommendations, I need to understand what you're looking for in a trip.
    ...
    
    请注意 [travel_brainstormer] 标记。root_agent 转移的控制权仅基于子代理的 description
  6. 终端中的 user: 提示符处,输入 exit,然后按 Enter 键结束对话。
  7. 现在,我们来更明确地说明一下。在 agent.py 中,将以下内容添加到 root_agentinstruction 中:
            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'.
    
  8. 终端中,再次运行代理:
    adk run parent_and_subagents
    
  9. 终端中的 [user]: 提示符处,输入:
    hello
    
  10. 回复时请附上以下信息:
    I would like to go to Japan.
    
    输出示例(您的输出可能略有不同):
    [attractions_planner]: Okay, I can help you with that! Here are some popular attractions in Japan:
    ...
    
    按照新说明,将数据转移到 attractions_planner
  11. 现在,请回复以下内容:
    Actually I don't know what country to visit.
    
    输出示例(您的输出可能略有不同):
    [travel_brainstormer]: Okay! I can help you brainstorm some countries for travel...
    
    请注意,您已转移到 attractions_planner 的同级 travel_brainstormer此设置默认处于允许状态。
  12. 在用户提示符处,输入 exit 以结束会话。

回顾

在本部分中,您学习了代理层次结构和对话流程的基础知识:

  • 对话始终以 root_agent 开头。
  • 父代理可以根据其 description 自动转移到子代理。
  • 您可以明确控制此流程,方法是向父代理提供 instruction 以通过其 name 转移到子代理。
  • 默认情况下,代理可以转接给其 peer 代理(层次结构中的同级代理)。

8. 使用会话状态存储和检索信息

每个 ADK 对话都有一个 Session,其中包含会话状态字典。所有代理都可以访问此状态,因此它是代理之间传递信息或在整个对话过程中维护数据(例如列表)的完美方式。

如需了解如何向状态添加内容以及如何从状态读取内容,请执行以下操作:

  1. 返回到文件 adk_multiagent_systems/parent_and_subagents/agent.py
  2. 将以下函数定义粘贴到 # 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"}
    
    在此代码中,请注意:
    • 该函数接收 tool_context: ToolContext。此对象是会话的网关。
    • tool_context.state["attractions"] = ... 行直接从会话的状态字典读取数据和向其写入数据。ADK 会处理其余事宜。
  3. 通过添加 tools 参数,将该工具添加到 attractions_planner 代理:
        tools=[save_attractions_to_state]
    
  4. 将以下项目符号添加到 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.
    
  5. 终端中使用以下命令启动 Agent 开发套件 Web 界面
    adk web
    
    输出
    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)
    
  6. 在 Cloud Shell 终端中,点击网页预览按钮,然后选择更改端口,即可在新标签页中查看网页界面。
    “网页预览”菜单
  7. 输入端口号 8000,然后点击更改并预览。系统随即会打开一个新的浏览器标签页,其中显示 ADK Dev 界面。
    “更改端口”弹出式框,文本框中输入了 8000
  8. 从左侧的选择代理下拉菜单中,选择 parent_and_subagents
  9. 开始对话:hello
  10. 在代理向您问好后,请回复:
    I'd like to go to Egypt.
    
    您应该会被转到 attractions_planner,并获得景点列表。
  11. 选择一个景点,例如:
    I'll go to the Sphinx
    
  12. 您应该会收到类似如下的回答:好的,已将斯芬克斯添加到您的清单中...
  13. 点击响应工具箱(带有对勾标记),查看根据工具的响应创建的活动。
    请注意,它包含一个 actions 字段,其中包含描述状态变化的 stateDelta
  14. 回复代理列表中的另一个景点。
  15. 在左侧导航菜单中,点击“X”以退出之前检查的事件的聚焦模式。
  16. 在左侧边栏中,点击标签页。您现在可以在会话的状态中看到 attractions 数组,其中应包含您选择的两个商品。Web 界面中的会话状态预览
  17. 向代理发送以下消息:
    What is on my list?
    
    代理现在应从状态读取数据并返回您的列表。
  18. 完成代理实验后,关闭浏览器标签页,然后在 Cloud Shell 终端中按 Ctrl+C 停止服务器。

部分总结

在本部分中,您学习了如何使用 Session 状态来共享数据:

  • 写入状态:您可以在工具内使用 tool_context.state 对象(例如 tool_context.state["my_list"] = [...])。
  • 读取状态:您可以使用键模板(例如 instructionHere is your list: {my_list?})。
  • 检查状态:您可以使用“状态”标签页在 ADK 开发者界面中实时监控会话状态。

9. 工作流智能体

到目前为止,您已经了解了父代理如何转移到子代理,然后等待用户。工作流代理则不同:它们会以自动化的流程执行其子代理,而无需等待用户输入。

这非常适合自动化多步骤任务,例如“规划和执行”或“起草和修订”流水线。ADK 提供了三个内置工作流代理来管理此问题:

  • SequentialAgent
  • LoopAgent
  • ParallelAgent

本实验的其余部分将重点介绍如何使用这三个工作流代理构建多代理系统

您将构建一个代理,该代理可以为一部关于历史人物的新电影撰写推介文档。代理将负责研究、迭代写作和报告生成。

最后,您的系统将如下所示:

电影概念团队多代理系统示意图

您将逐步构建此系统,首先从最简单的工作流开始。

10. 使用 SequentialAgent 构建多智能体系统

SequentialAgent 是一种工作流代理,可按简单的线性序列执行其子代理。系统会按顺序依次运行 sub_agents 列表中的每个代理。这非常适合必须按特定顺序执行任务的流水线,例如您现在要构建的电影推介代理。

第一个版本将采用以下结构:

Film_concept_team 多智能体系统步骤 1

  • root_agent (greeter) 将欢迎用户并获取电影主题。
  • 然后,该账号将转移到名为 film_concept_teamSequentialAgent,该账号将:
    1. 运行 researcher 代理,从维基百科获取事实信息。
    2. 运行 screenwriter 代理,以使用这些事实来撰写情节。
    3. 运行 file_writer 代理,将最终图表保存到文件中。

我们来运行一下。

  1. Cloud Shell 编辑器中,打开 adk_multiagent_systems/workflow_agents/agent.py
    仔细阅读此代理定义文件。由于必须先定义子代理,然后才能将其分配给父代理,因此为了按对话流程的顺序读取文件,您可以从文件的底部到顶部读取代理。
  2. 请注意 append_to_state 工具。借助此辅助函数,代理可以向会话状态中的列表附加数据,researcherscreenwriter 将通过这种方式传递其工作。
  3. 试用代理。在终端中,启动已启用实时重新加载功能的 Web 界面:
    cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    adk web --reload_agents
    
  4. 在 Cloud Shell 终端中,点击网页预览按钮,然后选择更改端口,即可在新标签页中查看网页界面。
    “网页预览”菜单
  5. 输入端口号 8000,然后点击更改并预览。系统随即会打开一个新的浏览器标签页,其中显示 ADK Dev 界面。
    “更改端口”弹出式框,文本框中输入了 8000
  6. 选择代理下拉菜单中,选择 workflow_agents
  7. hello 开始对话。greeter 代理会做出响应。
  8. 出现提示时,输入一位历史人物。您可以使用以下任一选项,也可以使用自己的选项:
    • 张仲景
    • Ada Lovelace
    • 马可·奥勒留
  9. 现在,SequentialAgent 将接管。您不会看到任何中间消息。researcherscreenwriterfile_writer 将依次运行。只有在整个序列完成时,代理才会做出响应。
    如果失败,您可以点击右上角的 + 新会话,然后重试。
  10. 当代理确认文件已写入后,在 Cloud Shell Editor 的 movie_pitches 目录中找到并打开新的 .txt 文件,即可查看输出。
  11. 在 ADK 开发者界面中,点击对话记录中的最后一个代理图标,打开事件视图
  12. 事件视图会显示代理树的直观图表。您可以看到 greeter 如何调用 film_concept_team,然后 film_concept_team 按顺序调用每个子代理。adk 网络图
  13. 您可以点击图表中任何代理的请求响应标签页,以检查传递的确切数据(包括会话状态)。

部分总结

在本部分中,您学习了如何使用工作流代理

  • SequentialAgent 会按顺序逐个执行其子代理,而无需在各个步骤之间等待用户输入。
  • 这是一个“工作流”,因为用户与 root_agent 对话,然后 root_agent工作交给 SequentialAgent 完成。
  • 序列中的子代理使用会话状态(例如,{ PLOT_OUTLINE? })来访问之前客服人员的工作。
  • 您可以使用开发者界面中的事件图来直观呈现并调试整个代理到代理的工作流。

11. 添加 LoopAgent 以进行迭代工作

LoopAgent 是一种工作流代理,它会按顺序运行其子代理,然后从头开始重复运行。此“循环”会一直持续,直到满足某个条件,例如达到 max_iterations 次数或子代理调用内置的 exit_loop 工具。

对于需要迭代改进的任务,此功能非常有用。您将添加此 LoopAgent,为电影推介代理创建“编剧室”。这样一来,researcherscreenwriter 和新的 critic 代理就可以循环工作,每次通过时都会改进情节,直到 critic 认为情节已准备就绪。这还有助于代理通过研究和完善想法来处理更模糊的用户输入(例如“一位古代医生”)。

Film_concept_team 多智能体系统步骤 2

如需进行这些更改,请执行以下操作:

  1. adk_multiagent_systems/workflow_agents/agent.py 中,添加 exit_loop 的导入项(在其他 google.adk 导入项附近):
    from google.adk.tools import exit_loop
    
  2. 添加新的 critic 代理。该代理会审核剧情。如果运行状况良好,则调用 exit_loop。如果不是,则将反馈添加到状态中,以供下一个循环使用。
    将以下代理定义粘贴到 # Agents 部分下:
    critic = Agent(
        name="critic",
        model=model_name,
        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]
    )
    
  3. 创建 writers_room LoopAgent。此列表将包含将在循环中运行的三个代理。
    将以下代码粘贴到 film_concept_team 代理定义上方
    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,
    )
    
  4. 更新 film_concept_team SequentialAgent 以使用新的 writers_room 循环。将 researcherscreenwriter 替换为单个 writers_room 代理。将现有的 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
        ],
    )
    
  5. 返回 ADK 开发者界面标签页,然后点击右上角的 + 新会话
  6. 开始与以下对象进行新对话:hello
  7. 在系统提示时,这次给代理提供一个更宽泛的主题。以下是一些建议:
    • 一位为大众设计产品的工业设计师
    • 制图师(地图制作者)
    • 让农作物产出更多食物的那个人
    代理现在将通过循环工作。在 ADK 开发者界面中,您会看到代理多次运行时的日志(例如,“[研究人员]”“[编剧]”“[影评人]”“[研究人员]”“[编剧]”“[影评人]…”)。
  8. 当循环完成时,代理将写入文件。查看 adk_multiagent_systems/movie_pitches 目录中生成的文件。
  9. 检查开发者界面中的事件图,查看循环结构。

部分总结

在本部分中,您学习了如何使用 LoopAgent

  • LoopAgent 是一种工作流代理,可重复执行其子代理序列,从而为迭代任务创建“内循环”。
  • 循环中的代理使用会话状态来传递工作(例如,PLOT_OUTLINE)和反馈(例如,CRITICAL_FEEDBACK)彼此之间在后续传递中。
  • 循环可以通过达到 max_iterations 限制或通过代理调用 exit_loop 工具来停止。

12. 使用 ParallelAgent 进行“扇出和收集”

ParallelAgent 是一种工作流代理,可同时(并发)执行其所有子代理。对于可划分为独立子任务的任务(例如运行两个不同的研究作业),此功能非常有用。

您将使用 ParallelAgent 创建一个并行工作的“预制作团队”。一位代理会研究票房潜力,而另一位代理则会同时集思广益,提出选角创意。这通常称为“扇出和收集”模式:ParallelAgent“扇出”工作,而后续智能体(我们的 file_writer)“收集”结果。

Film_concept_team 多智能体系统第 3 步

最终的代理流程将如下所示:

  1. greeter(根)开始聊天。
  2. 它会转移到 film_concept_team (SequentialAgent),后者会运行:
    • 用于创建图表的 writers_room (LoopAgent)。
    • 新的 preproduction_team (ParallelAgent) 可用于同时研究票房和演员阵容。
    • 用于收集所有结果并保存文件的 file_writer

如需进行这些更改,请执行以下操作:

  1. adk_multiagent_systems/workflow_agents/agent.py 中,将新的 ParallelAgent 及其子代理粘贴到 # Agents 标题下。
    box_office_researcher = Agent(
        name="box_office_researcher",
        model=model_name,
        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=model_name,
        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
        ]
    )
    
  2. 更新 film_concept_team SequentialAgentsub_agents 列表,以包含新的 preproduction_team(介于 writers_roomfile_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,
            preproduction_team,
            file_writer
        ],
    )
    
  3. 更新 file_writer 代理的 instruction,使其从状态中“收集”新报告并将其添加到文件中。
    file_writerinstruction 字符串替换为以下内容:
        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? }
        """,
    
  4. 返回到 ADK Dev 界面标签页,然后点击 + 新会话
  5. 输入 hello 即可开始对话。
  6. 当系统提示时,输入新的角色创意。以下是一些建议:
    • 发明了 Wi-Fi 技术的那个女演员
    • 一位令人兴奋的厨师
    • 世界博览会展览中的主要参与者
  7. 当代理完成其工作后,检查 adk_multiagent_systems/movie_pitches 目录中的最终文件。现在,它应该包含剧情、票房报告和演员阵容报告,所有内容都在一个文档中。

部分总结

在本部分中,您学习了如何使用 ParallelAgent

  • ParallelAgent“扇出”工作,同时运行所有子代理,而不是按顺序运行。
  • 对于不相互依赖的任务(例如研究两个不同的主题),这种方式非常高效。
  • 并行代理的结果由后续代理“收集”。为此,并行代理会将自己的工作保存到会话状态(使用 output_key),并让最终代理(例如 file_writer)读取这些键。

13. 自定义工作流智能体

SequentialAgentLoopAgentParallelAgent 的预定义工作流代理无法满足您的需求时,CustomAgent 可让您灵活地实现新的工作流逻辑。

您可以定义子代理之间的流程控制、条件执行或状态管理模式。这对于复杂的工作流、有状态的编排或将自定义业务逻辑集成到框架的编排层中非常有用。

创建 CustomAgent 超出了本实验的范围,但如果您需要,最好知道它存在!

14. 恭喜!

您已使用 Google 智能体开发套件 (ADK) 成功构建了一个复杂多智能体系统。您已经从简单的父级-子级智能体关系发展到编排复杂的自动化工作流,这些工作流可以研究、撰写和完善创意项目。

回顾

在本实验中,您完成了以下操作:

  • 分层树形式组织的代理,具有父代理和子代理关系。
  • 受控的代理到代理转移,包括自动转移(使用 description)和显式转移(使用 instruction)。
  • 使用工具将数据写入 tool_context.state 字典。
  • 使用密钥模板(例如,{ PLOT_OUTLINE? })从会话状态读取数据并引导智能体的提示。
  • 实现了 SequentialAgent,以创建简单的分步工作流(研究 -> 撰写 -> 保存)。
  • 使用 critic 代理和 exit_loop 工具创建迭代优化周期。LoopAgent
  • 使用 ParallelAgent 将独立任务(例如演员阵容和票房研究)“分发”以并发运行。

持续实验

您可以利用所学知识以多种方式继续深造。以下是一些建议:

  • 添加更多代理:尝试向 preproduction_team ParallelAgent 添加新代理。例如,您可以创建一个 marketing_agent,用于根据 PLOT_OUTLINE 为电影撰写宣传语。
  • 添加更多工具:为 researcher 代理提供更多工具。您可以创建一个使用 Google 搜索 API 的工具,以查找 Wikipedia 上没有的信息。
  • 探索 CustomAgent:实验中提到了不适合标准模板的工作流的 CustomAgent。尝试构建一个代理,例如,仅当会话状态中存在特定键时才以条件方式运行该代理。