首页 / 文章

运用ADK开发技能构建端到端AI智能体

具备 Google ADK 开发技能的端到端 AI 智能体:这些技能是什么,有哪些现有的技能,以及它们如何覆盖智能体的构建、测试、CI/CD 和可观测性功能。

发布者:REACTAPP.TOP阅读约 14 分钟3331 词

来源: Building End to End AI Agents with ADK Dev Skills

以下笔记为“运用ADK开发技能构建端到端AI智能体”提供了实用路径。重点在于契约、校验机制以及可直接插入的代码占位符,而非激励性表述。

引言

在完成引言阶段时,首先明确契约内容:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续代码修改的透明度。 将此阶段视为输入与经过验证的输出之间的契约。为相关成果命名,定义成功校验标准,并杜绝无声的半完成状态。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。

什么是ADK开发技能?

在处理“ADK Dev阶段是什么”这一环节时,首先需写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及代币或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。 在耗时较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次收取相同的LLM调用费用。

可用技能

在处理“可用技能”阶段时,首先写下相关契约:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新执行后续节点时,恢复流程不应再次计费相同的大型语言模型调用。

兼容性

在处理兼容性阶段时,首先写下相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个后续节点时,恢复流程不应再次调用相同的大型语言模型。

前提条件

在完成前置条件阶段时,首先需明确相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。 在完成前置条件阶段时,首先需明确相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。

# Required tools
- Node.js (for npx)
- Python 3.10+
- uv package manager (pip install uv)
- Google Cloud SDK (gcloud)
- An active GCP project with billing enabled
gcloud config set project YOUR_PROJECT_ID
gcloud auth application-default login

步骤1:安装ADK开发工具

将“步骤1:安装ADK”视为可度量的工作环节会更为高效。在扩大范围之前,需记录一份成功的运行示例、一个故障案例以及回滚说明。 配置应与应用程序代码分开存放。环境文件、密钥存储和功能标志应集中于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 保持系统状态的结构化与类型化。嵌套的数据结构会掩盖具体是哪个节点设置了哪个字段,且在中断后会导致系统无法继续正常运行。

npx skills add google/adk-docs/skills -y -g
npx skills list

步骤2:明确需求

将“第二步:定义你的阶段”视为一个可度量的框架来使用效果最佳。在扩大范围之前,先记录一份理想的流程示例、一个失败案例以及回滚说明。同时记录正常流程与恢复流程的细节。重试机制、人工审核环节以及错误处理方式都是产品本身的一部分,而非后续需要补充的内容。保持图表状态简洁且类型明确,嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在流程中断后导致无法继续执行。

I need to build a Retail Returns multiagent system using ADK.

Requirements:
- Check order status by order ID
- Process refunds for delivered orders
- Multi-agent architecture with routing
- Production deployment to Agent Engine

第三步:生成项目框架

将“第3步:生成项目”阶段视为可度量的对象来处理效果最佳。在扩大范围之前,需记录一份理想的执行日志、一个故障案例以及回滚说明。 相比庞大的脚本,应优先选择小型且可测试的单元。当某一步骤出现故障时,故障原因应能明确指向某个具体责任方,而非复杂的流程链。 保持图表状态简洁且具有类型定义。嵌套的数据结构会掩盖哪个节点修改了哪个字段的信息,还会在流程中断后导致无法继续执行。 将“第3步:生成项目”阶段视为可度量的对象来处理效果最佳。在扩大范围之前,需记录一份理想的执行日志、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外费用。

Use adk-scaffold to create this project with:
- Agent Engine deployment target
- GitHub Actions CI/CD
- No datastore needed (we'll use mock data)
retail-returns/
├── app/                    # Our agent code
├── tests/                  # Unit, integration, eval tests
├── .github/workflows/      # CI/CD pipelines
├── deployment/terraform/   # Infrastructure as code
├── notebooks/              # Jupyter notebooks
└── Makefile               # Common development commands

第4步:实现业务逻辑

在第四步“实现业务功能”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个流程即可进行审计。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。

Add tools for:
1. check_order_status(order_id: str) -> dict
2. process_refund(order_id: str) -> dict

Use mock data with 3 sample orders. Refunds only work for delivered orders.
# Mock database
ORDERS = {
    "12345": {"status": "shipped", "total": 45.99, "items": ["T-shirt"], "refunded": False},
    "67890": {"status": "delivered", "total": 120.50, "items": ["Shoes", "Socks"], "refunded": False},
}

async def check_order_status(order_id: str) -> dict:
    """Checks order status and details."""
    if order_id in ORDERS:
        return {"status": "success", "order": ORDERS[order_id]}
    return {"status": "error", "message": f"Order {order_id} not found."}
async def process_refund(order_id: str) -> dict:
    """Processes refund with validation."""
    if order_id not in ORDERS:
        return {"status": "error", "message": f"Order {order_id} not found."}
    order = ORDERS[order_id]
    if order["status"] != "delivered":
        return {"status": "error", "message": "Order must be delivered"}
    if order["refunded"]:
        return {"status": "error", "message": "Already refunded"}
    order["refunded"] = True
    return {"status": "success", "transaction_id": f"REF-{order_id}-123"}
from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.models import Gemini

def create_status_agent() -> Agent:
    return Agent(
        name="status_agent",
        model=Gemini(model="gemini-3-flash-preview"),
        instruction="Look up orders using check_order_status tool.",
        tools=[check_order_status],
    )
def create_refund_agent() -> Agent:
    return Agent(
        name="refund_agent",
        model=Gemini(model="gemini-3-flash-preview"),
        instruction="Verify order is delivered before processing refund.",
        tools=[check_order_status, process_refund],
    )
root_agent = Agent(
    name="triage_agent",
    model=Gemini(model="gemini-3-flash-preview"),
    instruction="Route requests to status_agent or refund_agent.",
    sub_agents=[create_status_agent(), create_refund_agent()],
)
app = App(name="retail_returns_app", root_agent=root_agent)

第五步:在本地进行测试

在“本地进行第5步测试”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。

Let's test this locally
cd retail-returns
make install
make playground

第6步:创建评估

在第六步“创建评估”阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。 在第六步“创建评估”阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。

...

Create an evaluation to test invalid order handling
{
  "eval_set_id": "invalid_orders",
  "eval_cases": [
    {
      "eval_id": "invalid_status_check",
      "conversation": [
        {"user_content": {"parts": [{"text": "What's the status of order #99999?"}]}}
      ],
      "expected_tool_calls": [
        {"tool_name": "check_order_status", "args": {"order_id": "99999"}}
      ]
    },
    {
      "eval_id": "invalid_refund",
      "conversation": [
        {"user_content": {"parts": [{"text": "I want a refund for order #88888"}]}}
      ]
    }
  ]
}
{
  "criteria": {
    "tool_trajectory_avg_score": {
      "threshold": 1.0,
      "match_type": "IN_ORDER"
    },
    "final_response_match_v2": {
      "threshold": 0.8,
      "judgeModelOptions": {"judgeModel": "gemini-3-flash-preview"}
    }
  }
}
make eval
Tests passed: 2
Tests failed: 0

第7步:部署到生产环境

在执行第7步“部署到测试环境”时,首先需明确相关要求:所需输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会出错。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,以便操作人员无需查看整个系统结构即可进行审计。 在成本较高的步骤之后设置检查点。当操作人员重新尝试后续节点时,恢复流程不应再次计费相同的LLM调用。

Deploy this to Agent Engine
# Export dependencies
uv export --no-hashes > app/app_utils/.requirements.txt

# Deploy to Vertex AI
uv run -m app.app_utils.deploy \
  --source-packages=./app \
  --entrypoint-module=app.agent_engine_app \
  --entrypoint-object=agent_engine \
  --requirements-file=app/app_utils/.requirements.txt
import vertexai

client = vertexai.Client(project="YOUR_PROJECT", location="us-central1")
agent = client.agent_engines.get(name="ENGINE_ID")
async for event in agent.async_stream_query(
    message="Where is order #12345?",
    user_id="test"
):
    print(event)

第8步:搭建CI/CD流程

在完成第8步“设置”阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原定方向。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个后续节点时,恢复流程不应再次调用相同的LLM接口。

Set up CI/CD with GitHub Actions

1. PR检查(.github/workflows/pr_checks.yaml)

在处理 GitHub 的“1 PR Checks”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合预期。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。 在处理 GitHub 的“1 PR Checks”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合预期。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外收费。

2. 预发布部署(.github/workflows/staging.yaml)

将“预发布部署”这一 GitHub 阶段视为可度量的对象使用效果最佳。在扩大范围之前,需记录一份标准操作流程、一个故障案例以及回滚说明。 配置应与应用程序代码分开存放。环境文件、密钥存储和功能开关应集中于一处,以便操作人员无需查看整个架构即可进行审计。 保持架构状态的简洁性与类型化。嵌套的数据结构会掩盖哪个节点修改了哪个字段的信息,且在中断后会导致无法继续执行。

3. 生产环境部署(.github/workflows/deploy-to-prod.yaml)

将“3个生产部署github阶段”视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。同时文档化正常流程与恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。保持图结构的状态简洁且具有类型定义;嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续处理。

uvx agent-starter-pack setup-cicd \
  --staging-project YOUR_STAGING_PROJECT \
  --prod-project YOUR_PROD_PROJECT \
  --repository-name YOUR_REPO \
  --repository-owner YOUR_GITHUB_USER \
  --auto-approve

第9步:可观测性

将第9步的可观测性阶段视为一个可度量的对象来处理,效果最佳。在扩大范围之前,先记录一份完美的日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤出现故障时,故障应指向单一的责任主体,而非复杂的流程链。 保持图表状态简洁且具有类型定义。嵌套的数据结构会掩盖哪个节点修改了哪个字段的信息,还会在流程中断后导致无法继续处理。 将第9步的可观测性阶段视为一个可度量的对象来处理,效果最佳。在扩大范围之前,先记录一份完美的日志、一个故障案例以及回滚说明。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外费用。

How's observability configured?

内置功能(无需配置)

对于“无需配置”的内置阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个流程即可进行审核。 对于涉及资金支出或修改生产数据的操作,需经过人工审批。编译时的连接方式并不等同于业务流程的完整性。

可选集成

在“可选集成”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品功能的一部分,而非后续需要补充的内容。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。

# Add to app/agent.py
from google.adk.plugins import BigQueryAgentAnalyticsPlugin

app = App(
    root_agent=root_agent,
    plugins=[BigQueryAgentAnalyticsPlugin(dataset="agent_analytics")]
)

步骤10:为生产环境编写测试用例

在步骤10“编写测试”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的配置并不等同于业务功能的完整性。 在步骤10“编写测试”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能测试结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。

Create integration tests that hit the deployed agent
import pytest
import requests
import subprocess

def get_access_token():
    result = subprocess.run(
        ["gcloud", "auth", "print-access-token"],
        capture_output=True, text=True
    )
    return result.stdout.strip()
@pytest.mark.integration
def test_valid_order_status():
    """Test order lookup on deployed agent."""
    token = get_access_token()
    response = requests.post(
        f"https://us-central1-aiplatform.googleapis.com/v1/projects/{PROJECT_NUM}/locations/us-central1/reasoningEngines/{ENGINE_ID}:streamQuery",
        headers={"Authorization": f"Bearer {token}"},
        json={"input": {"message": "Where is order #12345?", "user_id": "test"}}
    )
    assert response.status_code == 200
    text = "".join(event.get("text", "") for event in response.json())
    assert "shipped" in text.lower()
    assert "45.99" in text
pytest tests/integration/test_remote_agent.py

前后对比

在处理“前后对比”阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新尝试后续节点时,恢复流程不应再次对同一次大型语言模型调用收费。

无需技能

在“无技能”阶段工作时,首先写下相关契约:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个后续节点时,恢复流程不应再次调用相同的大型语言模型。

具备技能

在“具备相应技能”阶段工作时,首先需明确规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明可溯。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。 在“具备相应技能”阶段工作时,首先需明确规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明可溯。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外收费。

最佳实践与技巧

“最佳实践与技巧”阶段若被视为可度量的对象,效果会更好。在扩大范围之前,先记录一份优秀的案例、一个失败案例以及回滚说明。 将配置与应用程序代码分开。环境文件、密钥存储和功能标志应集中存放于一处,这样操作人员无需查看整个结构即可进行审计。 保持数据结构的层次简单且类型明确。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续处理。

1. 全局安装技能

将“全球范围内安装技能”这一阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份成功的案例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。 保持图表状态简洁且类型明确。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在出现中断后导致流程无法继续。

npx skills add google/adk-docs/skills -y -g

2. 提示语要具体

在“具体化”阶段,将其视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任主体,而非复杂的流程链。 为每轮及每次会话设定预算额度。智能工具会大量消耗上下文资源,设置上限可避免演示过程变成意外的费用账单。

3. 根据不同阶段选择合适的技能

4. 通过评估不断迭代

5. 审查生成的代码

6. 使用版本控制

git init
git add .
git commit -m "Initial scaffold from ADK Dev Skills"

常见问题

我们需要先学习ADK吗?

可以修改生成的代码吗?

这能在不同的AI助手上使用吗?

如果我们想部署到Cloud Run上会怎样?

可以创建自己的技能吗?

如何更新技能?

npx skills add google/adk-docs/skills -y -g

我们的成果

下一步要开发的内容

结论

联系方式

操作检查清单