Next ‘26 开发者主旨演讲:使用技能和工具构建 ADK 智能体

1. 简介

在此 Codelab 中,您将使用智能体开发套件 (ADK) 构建复杂的马拉松计划智能体 。您将逐步了解智能体的功能,从结构良好的系统提示到动态技能加载和映射 MCP 工具。最后,您将在本地测试智能体并将其部署到智能体运行时(智能体引擎)。

您将执行的操作

  • 初始化新的 ADK 智能体 项目
  • 使用结构化构建器编写稳健的系统提示
  • 添加 Google 地图 MCP 工具 以获取真实世界的位置上下文
  • 技能 动态加载到智能体的工具集中
  • 在本地测试智能体执行情况
  • 将智能体部署 到智能体引擎 (Cloud Run)

所需条件

  • 网络浏览器,例如 Chrome
  • 启用了结算功能的 Google Cloud 项目
  • 对 Python 有基本的了解

此 Codelab 适合希望构建专用生成式 AI 智能体的中级开发者。

预计时长:45 分钟

在此 Codelab 中创建的资源费用应低于 2 美元。

2. 准备工作

创建 Google Cloud 项目

  1. Google Cloud 控制台 的项目选择器页面上,选择或创建一个 Google Cloud 项目
  2. 确保您的云项目已启用结算功能。了解如何检查项目是否已启用结算功能

启动 Cloud Shell

Cloud Shell 是在 Google Cloud 中运行的一个命令行环境,其中预加载了必要的工具。

  1. 点击 Google Cloud 控制台顶部的激活 Cloud Shell
  2. 连接到 Cloud Shell 后,验证您的身份验证:
    gcloud auth list
    
  3. 确认您的项目已配置:
    gcloud config get project
    
  4. 如果您的项目未按预期设置,请进行设置:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

验证身份验证:

gcloud auth list

确认您的项目:

gcloud config get project

根据需要进行设置:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

启用 API

运行此命令以启用所有必需的 API:

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  secretmanager.googleapis.com \
  mapstools.googleapis.com \
  storage.googleapis.com \
  cloudresourcemanager.googleapis.com \
  serviceusage.googleapis.com

创建 Google 地图 API 密钥

如需使用 Google 地图 MCP 工具,您需要生成地图 API 密钥。

  1. 在 Google Cloud 控制台中,使用搜索栏前往 Google Maps Platform > 凭据
  2. 在系统提示时,确认您的 Google Cloud 云项目。
  3. 点击创建凭据 ,然后选择 API 密钥
  4. 复制生成的 API 密钥。下一步操作将会用到该地址。

3. 设置您的环境

在此 Codelab 中,代码托管在 GitHub 上。您将克隆代码库,其中包含目录结构和所需的子组件(例如 skills/ 目录)。

  1. 克隆代码库并前往项目文件夹:
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/demo-1
  1. 设置 Python 虚拟环境并安装 ADK:
uv venv
source .venv/bin/activate
uv sync
  1. 设置您的地图 API 密钥。应用会从环境变量中读取该密钥:
export GOOGLE_MAPS_API_KEY="<YOUR_MAPS_API_KEY>"

配置环境变量

模拟器智能体使用 .env 文件进行配置。复制示例文件并使用您的项目 ID 对其进行更新。

  1. 复制示例环境文件:
cp planner_agent/sample.env planner_agent/.env
  1. 打开 planner_agent/.env,使用您的实际 Google Cloud 项目 ID 更新 GOOGLE_CLOUD_PROJECT 字段,并使用您创建的 Google 地图 API 密钥更新 GOOGLE_MAPS_API_KEY 字段。

文件内容应如下所示:

GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=us-west1
GOOGLE_MAPS_API_KEY=<YOUR_MAPS_API_KEY>
GOOGLE_CLOUD_AGENT_ENGINE_ENABLE_TELEMETRY=true
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS=true

4. 创建新的 ADK 智能体

探索定义智能体的核心文件:planner_agent/agent.py

build-agents-with-skills 代码库中,智能体使用 ADK 的 Agent 类进行初始化。它指定了底层模型、身份名称,并提取了在其他模块中定义的指令和工具。

打开 planner_agent/agent.py 以检查初始化代码:

instruction="Answer user questions to the best of your knowledge"
description="A helpful assistant for user questions."
tools=[]

# ...

root_agent = Agent(
    model='gemini-3-flash-preview',
    name='planner_agent',
    description=description,
    instruction=instruction,
    tools=tools
)

Agent 类抽象出了消息记录、工具编排和 LLM 通信,让您可以专注于智能体的行为。

目前,智能体非常通用。您可以像使用任何其他 LLM 一样与它互动。

uv run adk run planner_agent

此命令将启动与智能体的对话。它使用 gemini-3-flash-preview 作为其模型,并且可以回答基本问题。

Running agent planner_agent, type exit to exit.
[user]: What is the length of a Marathon
[planner_agent]: The official length of a marathon is **26.2 miles**, which is
equivalent to **42.195 kilometers**.

智能体已经了解一些关于马拉松的事实。但是,这不足以规划包含规则和路线规划的适当马拉松。

5. 创建系统提示

系统提示(指令)决定了智能体的行为。此项目没有使用单个大型字符串,而是使用 PromptBuilder (planner_agent/utils.py) 动态编写指令。

打开 planner_agent/prompts.py,了解提示如何构建为逻辑部分:

from collections import OrderedDict
from .utils import PromptBuilder

ROLE = """\
...
"""

RULES = """\
...
"""

WORKFLOW = """\
...
"""

###

# Planner instructions with no tools mentioned
PLANNER_INSTRUCTION_NO_TOOLS = PromptBuilder(
    OrderedDict(
        role=ROLE,
        rules=RULES,
        tools=TOOLS_PROMPT_ONLY,
        workflow=WORKFLOW_PROMPT_ONLY,
    )
).build()

# Planner instruction with skills and tools defined
PLANNER_INSTRUCTION = PromptBuilder(
    OrderedDict(
        role=ROLE,
        rules=RULES,
        skills=SKILLS,
        tools=TOOLS,
        workflow=WORKFLOW,
    )
).build()

返回 planner_agent/agent.py,它已导入。

找到包含 TODO: Replace Instruction and Description 的部分,并取消对 instructiondescription 变量重新赋值的注释。

该部分代码应如下所示:

instruction=PLANNER_INSTRUCTION_NO_TOOLS
description="Expert GIS analyst for marathon route and event planning."

您正在导入智能体的提示版本,该版本未引用任何工具。您将在后续步骤中添加工具。

您可以测试此版本的智能体:

uv run adk run planner_agent

在聊天窗口中,发送以下提示:

Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe

片刻之后,您应该会收到类似如下所示的响应:

Running agent planner_agent, type exit to exit.
[user]: Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the evening timeframe
[planner_agent]: Here is the comprehensive marathon plan for Las Vegas.

As requested, I have designed this event for an evening start on April 24, 2027. Because certain parameters (theme and budget) were not specified, I have applied pragmatic defaults: this will be a "Neon Nights" scenic theme to capitalize on the evening Strip, operating on a moderate-to-high budget given the infrastructure needed to secure major Las Vegas corridors.

### 1. Intent Alignment
*   **City & Theme:** Las Vegas, Nevada. Theme: "Neon Nights" an evening race maximizing the visual impact of the illuminated city.
*   **Date & Time:** Saturday, April 24, 2027. Late April evenings in Las Vegas offer optimal running weather (temperatures dropping from ~70°F at sunset to ~60°F). Race start is 6:30 PM (sunset is approx. 7:20 PM).
...
...

通过明确定义的提示,输出结果已经非常接近预期结果。在下一步中,您将添加工具,使智能体更上一层楼。

6. 添加技能和工具

如需在 planner_agent/agent.py 中启用技能和工具,请找到包含 TODO: Replaces Tools 的部分,并取消对接下来两行的注释。您的代码应如下所示:

instruction=PLANNER_INSTRUCTION
tools=get_tools()

这是此步骤中唯一需要的代码更改。本部分的其余内容将介绍技能和工具背后的概念。

技能

智能体技能是 ADK 智能体可用于执行特定任务的自包含功能单元。智能体技能根据智能体技能规范封装了任务所需的必要指令、资源和工具。技能的结构允许以增量方式加载技能,以最大限度地减少对智能体操作上下文窗口的影响。

对于马拉松计划智能体,定义了 3 项技能:

  1. gis-spatial-engineering - 负责处理 GeoJSON 数据以创建马拉松路线。
  2. mapping - 使用 Google 地图工具搜索地点和天气信息。
  3. race-director - 验证马拉松路线是否遵循规划指南。

技能可以包含脚本、其他资产和引用。

应用会加载所有技能,并在 planner_agent/tools.py 中将其作为工具提供。请注意 get_tools() 函数中是如何完成此操作的:

def get_tools() -> list:
    """Build the planner's tool list with lazy-loaded skills."""
    from google.adk.code_executors.unsafe_local_code_executor import UnsafeLocalCodeExecutor

    skills_dir = pathlib.Path(__file__).parent / "skills"

    skills = []
    if skills_dir.exists():
        skills = [
            load_skill_from_dir(d)
            for d in sorted(skills_dir.iterdir())
            if d.is_dir() and not d.name.startswith("_") and (d / "SKILL.md").exists()
        ]

    additional_tools = _load_additional_tools(skills_dir)

    skill_toolset = SkillToolset(
        skills=skills,
        code_executor=UnsafeLocalCodeExecutor(),
        additional_tools=additional_tools,
    )

    tools = [
        skill_toolset,
        PreloadMemoryTool(),
    ]

    tools.extend(get_maps_tools())

    return tools

最有趣的部分是 ADK 中的 load_skill_from_dir 方法。在 ADK 中,还有另一种创建技能的方法,即内联。虽然在此 Codelab 中未使用,但它看起来类似于以下内容:

from google.adk.skills import models

greeting_skill = models.Skill(
    frontmatter=models.Frontmatter(
        name="greeting-skill",
        description=(
            "A friendly greeting skill that can say hello to a specific person."
        ),
    ),
    instructions=(
        "Step 1: Read the 'references/hello_world.txt' file to understand how"
        " to greet the user. Step 2: Return a greeting based on the reference."
    ),
    resources=models.Resources(
        references={
            "hello_world.txt": "Hello! So glad to have you here!",
            "example.md": "This is an example reference.",
        },
    ),
)

添加地图工具

马拉松计划智能体需要空间上下文才能生成路线。您可以通过集成 Google 地图 MCP(Model Context Protocol)服务器来提供此信息。

planner_agent/tools.py 中,请注意如何使用 ApiRegistry 工具注册 MCP 服务器:

from google.adk.integrations.api_registry import ApiRegistry

class MapsApiRegistry(ApiRegistry):
    """ApiRegistry subclass that strips ADC headers to force API key auth."""

    def get_toolset(self, *args, **kwargs):  # noqa: ANN002, ANN003
        toolset = super().get_toolset(*args, **kwargs)
        conn = getattr(toolset, "_connection_params", None)
        headers = getattr(conn, "headers", None) if conn else None
        if headers:
            headers.pop("Authorization", None)  # type: ignore[union-attr]
            headers.pop("x-goog-user-project", None)  # type: ignore[union-attr]
        return toolset

def get_maps_tools() -> list:
    """Return Maps MCP toolset if configured."""
    project_id = os.getenv("GOOGLE_CLOUD_PROJECT", "").strip()
    maps_key = _resolve_maps_key()

    if not project_id or not maps_key:
        return []

    # Map the MCP server location on Google Cloud
    mcp_server_name = f"projects/{project_id}/locations/global/mcpServers/google-mapstools.googleapis.com-mcp"
    
    # Initialize the custom API registry that supports header injection
    api_registry = MapsApiRegistry(
        api_registry_project_id=project_id,
        header_provider=header_provider,
    )
    return [api_registry.get_toolset(mcp_server_name=mcp_server_name)]

通过添加 MCP 工具集,智能体将自动获得查询 Google 地图以获取路线、海拔和位置详细信息的功能!

7. 在本地运行智能体

现在,智能体、提示和工具已连接在一起,请在本地运行智能体。这次,您将使用 adk web,以便查看技能加载和工具调用事件。

uv run adk web

您应该会看到类似如下所示的内容

INFO:     Started server process [99665]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://127.0.0.1:8000.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
  1. 打开浏览器,然后前往终端中显示的网址(通常为 http://localhost:8000)。
  2. 在左上角的下拉列表中,选择 planner_agent
  3. 在聊天窗口中,发送以下提示:
Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe

您应该会看到技能正在加载,工具正在被调用。片刻之后,智能体将生成马拉松计划。

您的界面应如下所示:

ADK 网页界面

8. 部署智能体

如果您对智能体在本地的执行情况感到满意,则可以将其部署到智能体引擎,该引擎会在 Cloud Run 上安全地托管智能体。

如需部署智能体,请使用 ADK CLI 部署命令:

uv run adk deploy agent_engine \
  --env_file planner_agent/.env \
  planner_agent

部署完成后,CLI 会为您的智能体输出安全托管的端点。现在,您可以将此端点集成到前端应用、聊天机器人或其他后端系统中。您还可以使用智能体运行时 Playground 来测试智能体。

输出如下所示:

Files and dependencies resolved
Deploying to agent engine...
✅ Created agent engine: projects/<PROJECT_ID>/locations/us-west1/reasoningEngines/<AGENT_ID>

您可以使用提供的 Python 脚本与智能体通信。

  1. 复制示例环境文件:
cp sample.env .env
  1. 打开 .env,使用您的实际 Google Cloud 项目 ID 更新 GOOGLE_CLOUD_PROJECT 字段。

文件内容应如下所示:

GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=us-west1
  1. 您可以列出项目中的智能体。
python main.py list

您应该会看到类似如下所示的内容

Listing deployed agents...

ID: <AGENT_ID> | Display Name: planner_agent

获得已部署的智能体 ID 后,您可以发送提示:

export AGENT_ID=<AGENT_ID>
python main.py prompt --agent-id ${AGENT_ID} --message "Plan a marathon for
10000 participants in Las Vegas on April 24, 2027 in the evening timeframe"

您将获得如下所示的输出:

Streaming response from agent <AGENT_ID>:

{'model_version': 'gemini-3-flash-preview', 'content': {'parts': [{'text': 'Here is a comprehensive
...
...
...

9. 清理

为避免系统持续向您的 Google Cloud 账号收费,请删除在此 Codelab 期间创建的资源。

删除部署创建的 Cloud Run 服务:

python main.py delete --agent-id ${AGENT_ID}

如果您将地图 API 密钥存储在 Secret Manager 中,请删除该 Secret:

gcloud secrets delete maps-api-key --project=$PROJECT_ID

如果您为此 Codelab 创建了新的 Google Cloud 项目,则可以删除整个项目以移除与其关联的所有资源和 API:

gcloud projects delete $PROJECT_ID

10. 恭喜

恭喜!您已使用 ADK 构建了复杂的马拉松计划智能体。

您学到的内容

  • 初始化智能体开发套件 (ADK) 项目
  • 利用 PromptBuilder 实现模块化系统提示
  • 使用 MCP 工具和 ApiRegistry 集成地图功能
  • 使用 SkillToolset 有条件地加载技能
  • 在本地进行测试并部署到智能体引擎

参考文档