运用ADK开发技能构建端到端AI智能体
具备 Google ADK 开发技能的端到端 AI 智能体:这些技能是什么,有哪些现有的技能,以及它们如何覆盖智能体的构建、测试、CI/CD 和可观测性功能。
以下笔记为“运用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