使用 ADK 构建 AI 智能体:编排智能体工作流

1. 概览

为了满足多约束条件的旅行请求(例如,设计一个预算在 100 美元以内、专注于历史寺庙和当地美食、不包含现代艺术画廊的京都全天行程),需要提取约束条件、同时研究景点和餐饮、制定详细的日程安排,并审核最终计划。如果仅依赖一个包含众多工具的单体式智能体,可能会跳过验证步骤或违反排除规则,因此需要通过编排,利用确定性工作流控制器来协调专门的子智能体。

在使用 ADK 构建 AI 智能体系列的第三部分中,您将使用智能体开发套件 (ADK) 2 工作流控制器(SequentialAgent、ParallelAgent 和 LoopAgent),在 Agent Platform 上构建一个自包含的多智能体旅行规划工具。在三个渐进阶段(无需第 1 部分或第 2 部分的工作区设置)中,您将协调六个由 gemini-3.8-flash 提供支持的专业智能体,这些智能体具有共享会话状态 (output_key)、并发 google_search 执行和迭代式 Maker-Checker 优化循环。

前提条件

学习内容

  • 如何从头开始搭建多智能体 ADK 2 项目
  • 如何设计一个由专业智能体组成的团队,并使用 output_key 共享会话状态
  • 如何使用 SequentialAgent 在确定性的分步流水线中执行子智能体
  • 如何使用 ParallelAgent 并发运行独立的研究智能体,以缩短延迟时间
  • 如何使用 LoopAgent 和 ToolContext 升级来实现迭代式 maker-checker 优化循环
  • 如何将依序、并行和循环模式组合到分层多智能体工作流中

所需条件

  • Google 账号(如果需要领取研讨会赠金,请使用个人 @gmail.com 账号)
  • 讲师提供的研讨会赠金链接(以及用于扫描二维码的手机摄像头)或有效的 Cloud Billing 账号
  • Google Chrome(建议使用无痕式窗口,以免混淆个人账号和工作账号)

2. 领取 Google Cloud 赠金(可选)

如果您参加的研讨会提供活动赠金链接,请领取 Google 开发者计划赠金,以便在没有信用卡的情况下预配结算账号。

领取活动赠金

  1. 在无痕窗口中打开研讨会赠金链接,然后使用您的 @gmail.com 账号登录。
  2. 在领取福利页面上,点击领取赠金:

Google Builders Hub“领取福利”卡片,其中显示了“领取赠金”按钮

  1. 如果系统提示您创建 Google 开发者计划个人资料,请填写表单。
  2. 当系统显示扫描以验证您是真人时,请使用手机扫描二维码并完成验证(如果未显示二维码,请刷新并再次点击领取赠金):

Google 开发者计划“请扫描此二维码,以验证您是真人”二维码对话框

  1. 确认显示已成功领取活动赠金!,然后点击打开结算账号:

Google Builders Hub 页面,显示“已成功领取活动赠金”和“打开结算账号”按钮

🔍 检查您的工作

结算账号开设最多需要 3 分钟:

  1. 打开 Google Cloud Billing(或将网址复制到无痕式窗口中),然后选择您的结算账号:
https://console.cloud.google.com/billing
  1. 刷新,直到您的 GDP Credit 账号显示状态为有效:

Google Cloud Billing 账号管理页面,其中显示了一个有效的 GDP 赠金结算账号

3. 创建 Google Cloud 项目(可选)

创建一个专用的 Google Cloud 项目,以便将此 Codelab 中的所有资源隔离开来,并便于清理。

  1. 打开创建项目(或将网址复制到无痕式窗口中):
https://console.cloud.google.com/projectcreate
  1. 输入项目详细信息:
    • 项目名称:例如 google-cloud-workshop
    • 结算账号(如果显示):选择 GDP Credit(或您的有效结算账号)
    • 父级资源:无组织(或您的组织,如果需要)
  2. 记下项目名称下方生成的项目 ID,然后点击创建:

“创建 Google Cloud 项目”界面,其中显示了“项目名称”“项目 ID”“父级资源”和“创建”按钮

🔍 检查您的工作

点击右上角工具栏中的通知,然后在项目创建完成后点击选择项目:

Google Cloud 控制台“通知”菜单,其中显示“创建项目”和“选择项目”链接

4. 设置您的环境

配置 Google Cloud Shell,启用 Agent Platform API,并使用 uv 创建一个隔离的 Python 3.12 虚拟环境。

配置 Cloud Shell

  1. 点击 Google Cloud 控制台工具栏中的激活 Cloud Shell (>_),或直接打开 Google Cloud Shell(或将网址复制到无痕式窗口中):
https://shell.cloud.google.com/?show=ide,terminal

Google Cloud 控制台工具栏中的“激活 Cloud Shell”按钮

  1. 如果出现提示,请点击授权:

“为 Cloud Shell 提供授权”对话框

  1. 从终端的编号菜单中选择有效的 Google Cloud 项目 ID:
unset CLOUDSDK_CORE_PROJECT
PS3="Select your project (e.g. 1): "
select PROJECT_ID in $(gcloud projects list --format="value(projectId)"); do
  [ -n "$PROJECT_ID" ] && gcloud config set project "$PROJECT_ID" && break
done

您应该会看到如下所示的输出(未标记的项目也会输出信息性 [environment: untagged] 行):

1) google-cloud-workshop-4210
2) my-cloud-project-8812
Select your project (e.g. 1): 1
Updated property [core/project].

验证您选择的项目 ID 是否在 Cloud Shell 提示中以黄色突出显示:

Cloud Shell 终端,其中所选项目 ID 以黄色突出显示

启用必需的 API

启用 Agent Platform API,以便 ADK 智能体可以调用 Gemini 模型:

gcloud services enable aiplatform.googleapis.com

您看到的输出结果应该类似于以下内容:

Operation "operations/acat.p2-..." finished successfully.

创建 Python 虚拟环境并安装 ADK

创建 ~/adk-agents 工作区并激活 Python 3.12 虚拟环境:

cd ~
mkdir -p adk-agents && cd ~/adk-agents

which uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"

uv venv .venv --python 3.12
source .venv/bin/activate

确认 (.venv) 前缀显示在终端提示符的开头:

Cloud Shell 终端,显示活跃 Python 虚拟环境上的 .venv 前缀

在活跃的虚拟环境中安装 ADK 2:

uv pip install --no-cache "google-adk==2.14.0"

🔍 检查您的工作

验证已安装的 adk CLI 版本:

adk --version

您看到的输出结果应该类似于以下内容:

adk, version 2.14.0

5. 搭建旅行规划工具智能体

环境准备就绪后,使用 ADK 的内置 adk create 命令为 travel_planner 智能体软件包生成起始文件。

生成入门软件包

从 ~/adk-agents 目录中运行 adk create:

cd ~/adk-agents
adk create travel_planner

当终端中出现提示时,请选择以下配置选项(如果首次运行时出现 Enable telemetry? [Y/n]: 提示,请按 Enter 键或输入 n 并按 Enter 键):

  1. Choose a model for the root agent(为根智能体选择模型):输入 2 以选择 gemini-3.8-flash(选项 1 会选择 gemini-3.5-flash),然后按 Enter 键。
  2. 选择后端:输入 2 以选择 Google Cloud Agent Platform 后端(下方 CLI 菜单中的选项 2),然后按 Enter。
  3. 输入 Google Cloud 项目 ID:按 Enter 键,确认括号中显示的项目 ID。
  4. Enter Google Cloud region(输入 Google Cloud 区域):输入 global,然后按 Enter 键。

adk create 会将 GOOGLE_GENAI_USE_ENTERPRISE=1、您的项目 ID 和 GOOGLE_CLOUD_LOCATION=global 写入 travel_planner/.env,这样,当您稍后更新 agent.py 时,您的凭证仍会保持配置状态。

🔍 检查您的工作

您看到的输出结果应该类似于以下内容:

Choose a model for the root agent:
1. gemini-3.5-flash
2. gemini-3.8-flash
3. Other models (fill later)
Choose model (1, 2, 3): 2
1. Google AI
2. Vertex AI
3. Login with Google
Choose a backend (1, 2, 3): 2

You need an existing Google Cloud account and project, check out this link for details:
https://google.github.io/adk-docs/get-started/quickstart/#gemini---google-cloud-vertex-ai

Enter Google Cloud project ID [google-cloud-workshop-4210]:
Enter Google Cloud region [us-central1]: global

Agent created in /home/your_username/adk-agents/travel_planner:
- .env
- .gitignore
- __init__.py
- agent.py

⚠️  WARNING: Secrets (like GOOGLE_API_KEY) are stored in .env.

Next steps:
- Chat with your agent in the terminal: adk run travel_planner
- Or in the browser: adk web .
- Have your coding agent evaluate and deploy it: uvx google-agents-cli setup
  (other install options: https://adk.dev/get-started/agents-cli/)

在 Cloud Shell 代码编辑器中打开当前文件夹,以便您在终端旁边检查和修改文件:

which cloudshell >/dev/null 2>&1 && cloudshell workspace ~/adk-agents || true
cd ~/adk-agents
source .venv/bin/activate

测试默认的单一智能体

在构建多智能体工作流之前,请启动 ADK 开发界面,观察默认的单个智能体如何响应宽泛的旅行规划查询:

cd ~/adk-agents
adk web --allow_origins "*"

使用 Cloud Shell 网页预览在浏览器中打开开发界面:

  1. 点击 Cloud Shell 右上角工具栏中的网页预览图标。
  2. 选择更改端口,输入 8000,然后点击更改并预览。

Cloud Shell 网页预览端口配置对话框,设置为 8000

ADK Web 界面加载后,发送问候语,例如 "hello, what can you do?" 或 "Help me plan a trip to Japan":

ADK 开发网页界面,显示基本的单智能体对话

请注意,单个 root_agent 会直接一次性回答,而不会进行结构化偏好提取、实时网络研究或预算验证。

测试完成后,在 Cloud Shell 终端中按 Ctrl + C 停止 adk web 服务器并返回命令提示符。

6. 构建 SequentialAgent 工作流

现在,您将构建第一个编排模式:由 SequentialAgent 提供支持的线性工作流。在依序流水线中,子智能体按严格的顺序执行。第一个专家提取结构化参数,并使用 output_key="user_preferences" 将其保存到共享会话状态,第二个专家从共享状态读取 {user_preferences} 以起草行程。

架构图:展示了 root_agent 委托给 master_travel_agent (SequentialAgent),后者通过共享会话状态运行 user_profiler_agent,然后运行 itinerary_synthesizer_agent

创建初始专家 (specialists.py)

在 travel_planner/ 中打开一个名为 specialists.py 的新文件:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

将以下代码粘贴到 travel_planner/specialists.py 中,以定义 user_profiler_agent 和 itinerary_synthesizer_agent(预先导入 ToolContext 和 google_search,以便在后续步骤中使用):

from google.adk import Agent
from google.adk.tools import ToolContext, google_search

# --- Specialist 1: The User Profiler ---
user_profiler_agent = Agent(
    name="user_profiler_agent",
    description="Extracts travel preferences and constraints from user input.",
    instruction="""
        Extract destination, duration (default 1 day), budget, interests, and exclusions.
        Return a single JSON object with keys: "destination", "duration", "budget", "interests", "exclusions".
    """,
    output_key="user_preferences",  # Saves output to state['user_preferences']
)

# --- Specialist 2: The Synthesizer ---
itinerary_synthesizer_agent = Agent(
    name="itinerary_synthesizer_agent",
    description="Compiles preferences and research into a final Markdown itinerary.",
    instruction="""
        You are an elite Travel Concierge. Write a Markdown itinerary with an itemized USD and local currency cost breakdown using:
        - User Preferences: {user_preferences}
        - Activities (if available): {activity_recommendations?}
        - Restaurants (if available): {restaurant_recommendations?}
    """,
    output_key="final_itinerary",
)

连接顺序流水线 (workflows.py)

在 travel_planner/ 中创建一个名为 workflows.py 的新文件,用于协调专家:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

将以下 SequentialAgent 定义添加到 travel_planner/workflows.py:

from google.adk.agents import SequentialAgent
from .specialists import (
    user_profiler_agent,
    itinerary_synthesizer_agent,
)

# 1. SEQUENTIAL PHASE: A linear two-step workflow
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,         # Step 1: Extract constraints into user_preferences
        itinerary_synthesizer_agent,  # Step 2: Draft itinerary from user_preferences
    ],
)

将工作流关联到 root_agent (agent.py)

现在,将 master_travel_agent 注册为 root_agent 的子智能体。打开 travel_planner/agent.py:

cloudshell edit ~/adk-agents/travel_planner/agent.py

将 travel_planner/agent.py 的内容替换为以下代码:

from google.adk import Agent
from .workflows import master_travel_agent

MODEL = "gemini-3.8-flash"

root_agent = Agent(
    model=MODEL,
    name="root_agent",
    description="A helpful assistant for user questions.",
    instruction=(
        "Greet the user and delegate any travel or trip planning requests "
        "to master_travel_agent."
    ),
    sub_agents=[master_travel_agent],
)

🔍 检查您的工作

从终端启动 ADK 网页界面:

cd ~/adk-agents
adk web --allow_origins "*"

在端口 8000 上打开网页预览,然后输入以下提示:

Help me plan a trip to Kyoto

您应该会在事件视图中看到类似于以下执行流程的输出:

1. root_agent -> calls transfer_to_agent(agent_name="master_travel_agent")
2. user_profiler_agent -> outputs JSON {"destination": "Kyoto", "duration": "1 day", ...} to state['user_preferences']
3. itinerary_synthesizer_agent -> reads {user_preferences} and outputs the formatted Markdown itinerary

ADK 2.14.0 网页界面,显示了从 root_agent 经过 master_travel_agent 到 user_profiler_agent 和 itinerary_synthesizer_agent 的执行图,以及生成的京都行程

点击任意事件标记(或 State: final_itinerary 标记),然后切换到左侧检查器面板中的状态标签页,确认 user_preferences 和 final_itinerary 均已填充到会话状态中。

检查完跟踪记录后,在终端中按 Ctrl + C 即可停止 adk web。

7. 使用 ParallelAgent 进行研究

虽然顺序工作流将偏好提取与行程草拟清晰地分离开来,但其建议仍然完全依赖于模型的静态训练知识。您可以添加两个由内置 google_search 工具提供支持的专用研究员,让行程安排基于实时网络数据:

  • activity_finder_agent:查找与用户目的地和兴趣相符的 3 个特定景点,以及预估票价。
  • restaurant_finder_agent:查找 3 家评价较高的本地餐厅及其人均预估消费。

由于研究景点和研究餐厅并不相互依赖,因此一个接一个地运行它们会浪费时间。相反,您需要将两个研究员封装在 ParallelAgent (parallel_research_agent) 中,以便 ADK 同时执行两个 Google 搜索工作流,并在将控制权移交给 itinerary_synthesizer_agent 之前填充 {activity_recommendations?} 和 {restaurant_recommendations?}。

架构图,显示了 master_travel_agent 在第 1 阶段运行 user_profiler_agent,在第 2 阶段运行 parallel_research_agent(包含 activity_finder_agent 和 restaurant_finder_agent 的 ParallelAgent),在第 3 阶段运行 itinerary_synthesizer_agent

将并行研究专家附加到 specialists.py

打开 travel_planner/specialists.py:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

将以下两位 Google 搜索专家附加到 travel_planner/specialists.py 的底部(紧挨着 itinerary_synthesizer_agent 的下方):

# --- Specialist 3: The Activity Finder ---
activity_finder_agent = Agent(
    name="activity_finder_agent",
    description="Finds 3 attractions matching the user's destination and interests.",
    instruction="""
        Based on {user_preferences}, use google_search to find 3 specific attractions (including budget-friendly options).
        Return a JSON list with keys: "attraction_name", "estimated_cost_local", "estimated_cost_usd", "notes".
    """,
    tools=[google_search],
    output_key="activity_recommendations",
)

# --- Specialist 4: The Restaurant Finder ---
restaurant_finder_agent = Agent(
    name="restaurant_finder_agent",
    description="Finds 3 restaurants matching the destination and budget.",
    instruction="""
        Based on {user_preferences}, use google_search to find 3 highly-rated restaurants across price points.
        Return a JSON list with keys: "restaurant_name", "cuisine", "estimated_cost_local", "estimated_cost_usd".
    """,
    tools=[google_search],
    output_key="restaurant_recommendations",
)

将 ParallelAgent 插入 workflows.py

打开 travel_planner/workflows.py:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

更新 travel_planner/workflows.py,以使用 ParallelAgent 定义 parallel_research_agent,并将其放置在 user_profiler_agent 和 itinerary_synthesizer_agent 之间:

from google.adk.agents import ParallelAgent, SequentialAgent
from .specialists import (
    activity_finder_agent,
    itinerary_synthesizer_agent,
    restaurant_finder_agent,
    user_profiler_agent,
)

# Parallel branch: Run activity and restaurant research simultaneously
parallel_research_agent = ParallelAgent(
    name="parallel_research_agent",
    description="Runs activity and restaurant research concurrently.",
    sub_agents=[
        activity_finder_agent,
        restaurant_finder_agent,
    ],
)

# Master pipeline: Profile -> Parallel Research -> Synthesize
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,          # Step 1: Extract constraints
        parallel_research_agent,      # Step 2: Research activities & restaurants in parallel
        itinerary_synthesizer_agent,  # Step 3: Synthesize into an itinerary
    ],
)

🔍 检查您的工作

再次启动 adk web 以测试并行研究流水线:

cd ~/adk-agents
adk web --allow_origins "*"

在 Web 预览界面中,发送以下提示:

Help me plan a trip to Kyoto focused on historic temples and ramen

您应该会在事件视图中看到类似于以下序列的输出:

1. user_profiler_agent -> writes state['user_preferences']
2. parallel_research_agent -> fans out concurrently:
   - activity_finder_agent invokes google_search -> writes state['activity_recommendations']
   - restaurant_finder_agent invokes google_search -> writes state['restaurant_recommendations']
3. itinerary_synthesizer_agent -> merges all three state keys into state['final_itinerary']
  1. “跟踪记录”视图:点击对话窗格顶部的跟踪记录(位于事件旁边),然后检查您的轮次。您会在parallel_research_agent下看到activity_finder_agent和restaurant_finder_agent的时间轴跨度重叠,与按顺序运行相比,总网络研究延迟时间几乎缩短了一半。
  2. “State”(状态)标签页:点击左侧检查器面板中的 State 标签页,以检查实时会话字典(user_preferences、activity_recommendations、restaurant_recommendations 和 final_itinerary)。

测试完成后,在终端中按 Ctrl + C 即可停止 adk web。

8. 使用 LoopAgent 优化草稿

即使有实时搜索结果,itinerary_synthesizer_agent 生成的初始草稿也可能会超出用户的总预算,或者意外包含排除的类别(例如,用户要求不包含现代艺术画廊,但草稿中却包含了)。

为确保符合约束条件,您将使用 LoopAgent 在流水线末尾添加创建者-检查者优化循环:

  1. itinerary_critic_agent(检查器):根据 {user_preferences} 审核 {final_itinerary}。它会汇总估算费用,检查每个负面限制条件,然后将具体的修订说明写入 critique_feedback,或使用确切短语 "APPROVED" 进行回复。
  2. itinerary_refiner_agent(制造者/退出者):读取 {critique_feedback}。如果批评等于 "APPROVED",它会调用 exit_loop 工具 (tool_context.actions.escalate = True) 以立即退出 LoopAgent。否则,它会修改 {final_itinerary} 以解决标记的问题,并覆盖 final_itinerary 以便在下一次传递中使用。

架构图,显示了 master_travel_agent 与第 4 阶段 refinement_loop_agent (LoopAgent) 在 itinerary_critic_agent 和 itinerary_refiner_agent 之间循环,直到调用 exit_loop

将 exit_loop、Critic 和 Refiner 附加到 specialists.py

打开 travel_planner/specialists.py:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

将 exit_loop 工具 (ToolContext)、itinerary_critic_agent 和 itinerary_refiner_agent 附加到 travel_planner/specialists.py 的底部:

def exit_loop(tool_context: ToolContext) -> dict:
    """Call ONLY when the critique is APPROVED to exit the refinement loop."""
    print(f"[Tool Call] exit_loop triggered by {tool_context.agent_name}")
    tool_context.actions.escalate = True
    return {"status": "approved", "message": "Itinerary approved. Exiting refinement loop."}


# --- Specialist 5: The Budget & Constraint Critic (Inside LoopAgent) ---
itinerary_critic_agent = Agent(
    name="itinerary_critic_agent",
    include_contents="none",
    description="Audits the itinerary draft against budget and negative constraints.",
    instruction="""
        Audit Current Itinerary ({final_itinerary}) against User Preferences ({user_preferences}).
        Verify that the USD total stays within the user's budget and no excluded venue types appear.
        If all checks pass, respond EXACTLY with the single word "APPROVED".
        Otherwise, output 1-2 concise revision instructions explaining what to swap or adjust.
    """,
    output_key="critique_feedback",
)

# --- Specialist 6: The Itinerary Refiner / Exiter (Inside LoopAgent) ---
itinerary_refiner_agent = Agent(
    name="itinerary_refiner_agent",
    include_contents="none",
    description="Refines the itinerary from critique feedback, or calls exit_loop when APPROVED.",
    instruction="""
        Review Auditor Critique ({critique_feedback}) for Current Itinerary ({final_itinerary}).
        If the critique is EXACTLY "APPROVED", call `exit_loop` immediately and return the itinerary unchanged.
        Otherwise, revise the draft using {activity_recommendations} and {restaurant_recommendations}
        so all USD budget and exclusion rules pass, and output ONLY the updated Markdown itinerary.
    """,
    tools=[exit_loop],
    output_key="final_itinerary",
)

为 workflows.py 添加 LoopAgent

打开 travel_planner/workflows.py:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

更新 travel_planner/workflows.py,将 itinerary_critic_agent 和 itinerary_refiner_agent 封装在 LoopAgent (max_iterations=3) 中,并将其附加为 master_travel_agent 的第四个阶段:

from google.adk.agents import LoopAgent, ParallelAgent, SequentialAgent
from .specialists import (
    activity_finder_agent,
    itinerary_critic_agent,
    itinerary_refiner_agent,
    itinerary_synthesizer_agent,
    restaurant_finder_agent,
    user_profiler_agent,
)

# Stage 2: Parallel research branch
parallel_research_agent = ParallelAgent(
    name="parallel_research_agent",
    description="Runs activity and restaurant research concurrently.",
    sub_agents=[
        activity_finder_agent,
        restaurant_finder_agent,
    ],
)

# Stage 4: Iterative Maker-Checker refinement loop
refinement_loop_agent = LoopAgent(
    name="refinement_loop_agent",
    description="Iteratively audits and refines the itinerary until constraints and budget are approved.",
    sub_agents=[
        itinerary_critic_agent,
        itinerary_refiner_agent,
    ],
    max_iterations=3,
)

# Master pipeline: Profile -> Parallel Research -> Synthesize -> Refinement Loop
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,          # Stage 1: Extract constraints
        parallel_research_agent,      # Stage 2: Research activities & restaurants in parallel
        itinerary_synthesizer_agent,  # Stage 3: Draft initial itinerary
        refinement_loop_agent,        # Stage 4: Audit and refine until approved
    ],
)

🔍 检查您的工作

启动 adk web 以测试完整的多智能体工作流:

cd ~/adk-agents
adk web --allow_origins "*"

在端口 8000 上打开网页预览界面,启动新会话,然后使用以下京都多约束提示测试整个系统:

Design a full-day itinerary for Kyoto with a total budget of $100. My main interests are historical landmarks, temples, and authentic local cuisine. Please do not include any modern art museums or galleries.

您应该会在事件视图和终端日志中看到类似于以下执行序列的输出:

1. user_profiler_agent -> writes JSON with destination="Kyoto", budget="$100", exclusions=["modern art museums", "galleries"]
2. parallel_research_agent -> runs activity_finder_agent and restaurant_finder_agent in parallel
3. itinerary_synthesizer_agent -> produces initial draft in state['final_itinerary']
4. refinement_loop_agent:
   - itinerary_critic_agent -> audits USD budget and exclusions -> outputs "APPROVED" (or revision notes)
   - itinerary_refiner_agent -> triggers [Tool Call] exit_loop triggered by itinerary_refiner_agent and outputs the approved itinerary
  1. “事件”视图:点击 itinerary_critic_agent 或 itinerary_refiner_agent 中的任意事件条状标签,即可在左侧的信息标签页中检查其载荷。当 itinerary_refiner_agent 调用 exit_loop 时,检查事件以查看 actions.escalate: true,该信号会告知 LoopAgent 在达到 max_iterations=3 之前停止迭代。
  2. “State”(状态)标签页:点击状态标签页,观察 state['critique_feedback'] 和 state['final_itinerary'] 在各次传递中的更新情况。如果初始草稿超过 $100 USD,critique_feedback 会在第 1 轮中保留审核者的修订说明,然后 final_itinerary 会在第 2 轮中更新为成本较低的替代方案,critique_feedback 会在第 2 轮中更改为 "APPROVED"。

测试完成后,在终端中按 Ctrl + C 即可停止 adk web。

9. 清理

删除本地项目文件

如需从 Cloud Shell 主文件夹中移除 adk-agents 项目目录和虚拟环境,请运行以下命令:

cd ~
rm -rf ~/adk-agents

停用 Agent Platform API

如果您不再需要在项目中启用 Agent Platform API,请使用 gcloud 将其停用:

gcloud services disable aiplatform.googleapis.com --quiet

删除整个 Google Cloud 项目(可选)

PROJECT_ID=$(gcloud config get-value project)
gcloud projects delete "$PROJECT_ID" --quiet

🔍 检查您的工作

确认 ~/adk-agents 已被移除:

test ! -d ~/adk-agents && echo "Workspace ~/adk-agents removed"

您看到的输出结果应该类似于以下内容:

Workspace ~/adk-agents removed

10. 恭喜

恭喜!您已使用 Google 智能体开发套件 (ADK) 构建了一个分层多智能体系统,该系统可协调由六个专业智能体组成的团队,执行依序、并行和迭代循环工作流。

您完成的任务

  • 通过共享会话状态(output_key 和 {state_variable} 模板注入)实现结构化智能体间通信
  • 使用 SequentialAgent 构建了确定性的分步流水线
  • 使用 ParallelAgent 并发执行了独立的 Google 搜索研究智能体
  • 使用 LoopAgent 和 tool_context.actions.escalate = True 实现了自动化制单人-复核人验证循环

后续步骤