2026年3月27日,来腾讯会议(限30人)了解掌握如何用Openclaw构建企业AI生产力
免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

谷歌 ADK 的 5 类 Agent Skill 设计模式

发布日期:2026-03-19 14:48:03 浏览次数: 1555
作者:Machi

微信搜一搜,关注“Machi”

推荐语

谷歌ADK开发者必知的5种Agent Skill设计模式,深入解析源码实现与框架保障。

核心内容:
1. 五种Agent Skill设计模式的详细解析
2. SkillToolset的三层按需加载架构实现
3. 源码中框架级保障与提示词实现的对比分析

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

TL;DR:结合 adk-python 源码,讨论下 Google Cloud Tech 发布的 5 类 Agent Skill 设计模式。

1. Agent Skill 设计讨论

2026 年 3 月 18 日,Google Cloud Tech 官方推文发布了一篇长文: "5 Agent Skill design patterns every ADK developer should know" ,by @Saboo_Shubham_ 和 @lavinigam。48 小时内收获 99 万+查看、2800+ 点赞。文章提出了五种设计模式:

  1. Tool Wrapper:让 Agent 按需加载某个库的最佳实践
  2. Generator:用模板驱动结构化文档生成
  3. Reviewer:用外部 checklist 对代码进行分级评审
  4. Inversion:Agent 先采访你,再执行
  5. Pipeline:多步骤工作流 + 检查点

这五个模式确实概括了 SKILL.md 的主流用法。但一个关键问题被忽略了:这些"模式"在 adk-python 的源码中到底实现了多少?哪些有框架级保障,哪些只是靠提示词"许愿"?

2. SkillToolset 的三层按需加载架构

ADK 的 skills 体系围绕 SkillToolset 类构建,实现了一套三层 progressive disclosure(渐进式披露):

层级
工具
加载内容
token 成本
L1
list_skills
仅 frontmatter(name + description)
极低
L2
load_skill
SKILL.md 的 instructions 全文
中等
L3
load_skill_resource
references/assets/scripts 中的具体文件
按需

核心初始化代码(skill_toolset.py):

class SkillToolset(BaseToolset):
    def __init__(
        self,
        skills: list[models.Skill],
        *,
        code_executor: Optional[BaseCodeExecutor] = None,
        script_timeout: int = 300,
        additional_tools: list[ToolUnion] | None = None,
    )
:

        # 去重校验:同名 skill 直接 raise ValueError
        self._skills = {skill.name: skill for skill in skills}

process_llm_request 方法在每次大模型调用前注入 system instruction 和可用 skills 的 XML 摘要:

async def process_llm_request(self, tool_context, llm_request):
    # 注入默认 system instruction(告知大模型如何使用 skills)
    llm_request.config.system_instruction += _DEFAULT_SKILL_SYSTEM_INSTRUCTION
    # 注入 <available_skills> XML(仅 name + description)
    llm_request.config.system_instruction += format_skills_as_xml(skills)

这套设计的核心价值在于:Agent 在对话开始时只"看到" skill 的名字和描述(L1),只有当大模型判断需要某个 skill 时才加载完整指令(L2),再按需加载具体资源(L3)。这确实能有效控制上下文消耗。

3. 逐一拆解:5 个 Pattern 的源码

3.1 Tool Wrapper:references/ 按需加载——最扎实的 Pattern ✅

Tool Wrapper 是五个模式中实现最完整的。它的核心是 LoadSkillResourceTool

# skill_toolset.py - LoadSkillResourceTool.run_async()
async def run_async(self, *, args, tool_context):
    path = args["path"]
    if path.startswith("references/"):
        content = skill.resources.get_reference(rel_path)
    elif path.startswith("assets/"):
        content = skill.resources.get_asset(rel_path)
    elif path.startswith("scripts/"):
        content = skill.resources.get_script(rel_path)

当 SKILL.md 中写着 Load 'references/conventions.md',LLM 会调用 load_skill_resource(skill_name="api-expert", path="references/conventions.md"),触发上述代码加载对应文件。

官方示例 contributing/samples/skills_agent/ 中的 weather-skill 完整演示了这个模式:

skills/weather-skill/
├── SKILL.md           # 指令:按步骤加载 references 和执行 scripts
├── references/
│   └── weather_info.md  # 天气相关的知识文档
└── scripts/
    └── get_humidity.py   # 可执行脚本

评价:有框架级代码支撑。references/ 的按需加载是 LoadSkillResourceTool 的核心路径,经过测试。企业可以放心使用。

3.2 Generator:assets/ 模板引擎——有基础,缺校验 ✅

Generator 模式在源码中同样由 LoadSkillResourceTool 支撑——path.startswith("assets/") 分发到 get_asset()。SKILL.md 中写 Load 'assets/report-template.md',Agent 就能拿到模板。

但关键差距在于:模板"填充"逻辑完全由大模型执行 instructions 完成。框架不会校验输出是否包含模板中的所有 section,也不会检查格式一致性。

SKILL.md 写的:        "Every section in the template must be present"
源码做的:              把 assets/report-template.md 的文本返回给 LLM,然后...就没了

评价:资源加载有代码支撑,但输出质量保障依赖大模型的指令遵循度。对于格式要求严格的企业场景(如合规报告),建议在 skill 外层加 Pydantic 校验。

3.3 Reviewer:checklist 即 references——同一机制的语义变体 ✅

Reviewer 模式在源码层面与 Tool Wrapper 完全共享同一套代码references/review-checklist.md 被加载的方式和 references/conventions.md 一模一样。

区别仅在于 SKILL.md 的 instructions 赋予了不同语义:

  • Tool Wrapper:「按 conventions 写代码」
  • Reviewer:「按 checklist 逐条评分」

评分逻辑(error/warning/info 分级)、结构化输出(Summary/Findings/Score)——这些全部由 instructions 中的自然语言驱动,源码不参与。

评价:和 Tool Wrapper 一样可靠。但企业若需要稳定的 JSON 格式评审结果,请在 Agent 外层加 output parser。

3.4 Inversion:多轮门控——框架级空白 ⚠️

这是第一个需要警惕的 Pattern。

文章中 Inversion 的核心是"阶段门控":

"DO NOT start building until all phases are complete"

但在 adk-python 源码中,没有任何代码实现阶段状态管理或门控逻辑。我们搜索了整个 skills 模块和 SkillToolset:

  • 无 phase 或 stage 状态
  • 无 "gate" 或 "checkpoint" 拦截器
  • tool_context.state 中唯一与 skill 相关的 key 是 _adk_activated_skill_{agent_name},仅记录哪个 skill 被激活,不记录执行到哪个阶段

这意味着 "DO NOT proceed" 的约束完全依赖大模型对自然语言的遵守。实测表明:

  • GPT-4 级别模型在 3-5 轮内通常能遵守
  • 但 5-10 轮后注意力稀释,可能跳过阶段
  • 上下文窗口越长,风险越大

不过值得注意的是,ADK 的 before_tool_callback 机制提供了一条补救路径:你可以在回调中检查 tool_context.state 中的阶段标记,在大模型试图跳阶段时拦截工具调用。但这需要开发者自行实现,SkillToolset 本身不会自动解析 SKILL.md 中的阶段约束。

评价:SkillToolset 层面仅约定,无保障。但 ADK 的 callback 机制提供了自定义门控的扩展点。在 PoC 演示中可以直接用 SKILL.md 约定,在生产中必须用 before_tool_callback + session state 补位

3.5 Pipeline:多步检查点——最大的承诺与最弱的保障 ⚠️

Pipeline 是五个 Pattern 中承诺最大("严格多步骤工作流 + 检查点")但实现最弱的。

文章的示例要求:

"Do NOT proceed to Step 3 until the user confirms."

源码中:SkillToolset 本身没有 checkpoint 机制、没有步骤状态机、没有步骤校验

但 DeepWiki 的交叉验证揭示了一个关键补充:ADK 的 FunctionTool 支持 require_confirmation=True 参数,配合 SequentialAgent 可以实现人机交互检查点。当工具被标记为需要确认时,Runner 会暂停执行并发送确认请求,等用户响应后才继续。这意味着你可以把 Pipeline 的每个步骤拆成独立的 Agent + Tool,用 SequentialAgent 编排,在关键步骤插入 require_confirmation 门控。

但这不是 SkillToolset 的能力,而是 ADK Agent 编排层的能力。 SKILL.md 中写的 "Do NOT proceed to Step 3 until the user confirms" 仍然只是自然语言约定,SkillToolset 不会解析这段话并自动挂载确认门控。

与成熟的工作流编排框架对比(修正版):

能力
ADK SkillToolset
ADK Agent 编排层
LangGraph
CrewAI
Temporal
步骤定义
SKILL.md 自然语言
SequentialAgent 显式定义
DAG 节点
Task 链
Workflow 函数
条件分支
LlmAgent 动态路由
人机交互检查点
require_confirmation
human-in-the-loop
步骤回退/重试
LoopAgent(有限)
状态持久化
无步骤粒度
Session state
持久化引擎

评价:SkillToolset 层面仅约定。但 ADK 自身的 Agent 编排层(SequentialAgent + require_confirmation)已经具备了 Pipeline 的基本能力。务实做法是:不要在单个 SKILL.md 中定义 Pipeline,而是把每个步骤拆成独立 Skill,用 SequentialAgent 编排 + require_confirmation 做门控

4. 去魅:被高估的三个点

4.1 "Progressive Disclosure" 的隐藏成本

三层按需加载是个好设计,但实现中有性能问题:

  • 无缓存:每次 load_skill_resource 都从 skill.resources 读取,同一个 reference 被多次加载时无 LRU 缓存
  • GCS 串行遍历_list_skills_in_gcs_dir 逐个下载每个 skill 的 SKILL.md,10 个 skill 就是 10 次串行网络请求
  • 16MB 上限RunSkillScriptTool 将整个 skill 的 references/assets/scripts 打包进执行环境,大型 skill 可能触发 _MAX_SKILL_PAYLOAD_BYTES 限制

4.2 "实验性" 标记的含义

adk-python 的 src/google/adk/skills/README.md 明确写着:

"This is experimental"

此外:

  • SkillToolset 未出现在 tools/__init__.py 的 lazy mapping 中
  • llms.txt(ADK 的官方能力描述文件)完全没有提及 skills
  • skills 模块未出现在 AGENTS.md 的源码结构说明中

这些信号表明:skills 目前在 ADK 中是二等公民。API 可能在后续版本发生 breaking change。

4.3 SKILL.md 的 "描述优先" 陷阱

社区反馈的一个共识:SKILL.md 的 description 字段比 instructions 更重要。因为 description 决定了大模型是否会激活这个 skill——如果 description 写得不够精准,skill 可能永远不会被调用,或者被错误地调用。

这带来一个反直觉的问题:你花 80% 精力写的 instructions 可能白费,因为前置的 description 就没写对。

5. 企业级落地修正建议

5.1 Inversion 的修正:显式状态机

不要依赖 "DO NOT proceed" 的自然语言约束。ADK 原生的 before_tool_callback 是最佳扩展点:

PHASES = ["discovery""constraints""synthesis"]

async def phase_gate_callback(tool, args, tool_context):
    """before_tool_callback:在工具执行前检查阶段门控"""
    required_phase = args.get("_required_phase")
    if not required_phase:
        return None  # 非门控工具,放行
    
    current = tool_context.state.get("_skill_phase""discovery")
    if PHASES.index(current) < PHASES.index(required_phase):
        # 返回字典会直接作为工具结果,阻止实际执行
        return {"error"f"阶段 {required_phase} 未解锁。当前:{current}"}
    return None  # 放行

agent = Agent(
    model="gemini-2.5-flash",
    tools=[my_skill_toolset],
    before_tool_callback=phase_gate_callback,
)

核心思路:利用 ADK 原生的 before_tool_callback 而非继承 SkillToolset,在 tool_context.state 中维护 _skill_phase,每个阶段完成后显式推进。这把"约定"变成了"代码",且不需要侵入 SkillToolset 内部

5.2 Pipeline 的修正:外部编排 + Skill 组合

有两条路径,根据团队技术栈选择:

路径 A:ADK 原生方案(可优先尝试)

利用 SequentialAgent + require_confirmation 实现 Pipeline,不引入外部框架:

from google.adk import Agent
from google.adk.agents import SequentialAgent
from google.adk.tools import FunctionTool

# 每个步骤是独立 Agent + Skill
step1_agent = Agent(name="parser", tools=[skill_toolset_step1])
step2_agent = Agent(name="docgen", tools=[skill_toolset_step2])

# 关键步骤的工具标记 require_confirmation
confirm_tool = FunctionTool(
    func=submit_docstrings,
    require_confirmation=True  # Runner 会暂停,等用户确认
)
step2_agent_with_gate = Agent(name="docgen_gated", tools=[skill_toolset_step2, confirm_tool])

# SequentialAgent 编排
pipeline = SequentialAgent(
    name="doc-pipeline",
    sub_agents=[step1_agent, step2_agent_with_gate, step3_agent]
)

路径 B:外部编排框架(复杂 Pipeline 场景)

当 Pipeline 需要条件分支、并行扇出/扇入、跨服务编排时,引入 LangGraph / Prefect / Temporal:

职责
工具选型
编排层
步骤顺序、条件分支、回退
LangGraph / Prefect / Temporal
执行层
每个步骤的 Agent 逻辑
ADK Agent + SkillToolset
知识层
每个步骤的 references/assets
ADK Skill(SKILL.md)

核心原则不变:ADK Skill 定义知识,编排机制(无论原生还是外部)控制流程

5.3 缓存与性能修正

在 SkillToolset 外层加缓存,避免重复加载:

from functools import lru_cache

class CachedSkillToolset(SkillToolset):
    @lru_cache(maxsize=64)
    def _cached_resource(self, skill_name: str, path: str) -> str:
        skill = self._get_skill(skill_name)
        if path.startswith("references/"):
            return skill.resources.get_reference(path.removeprefix("references/"))
        elif path.startswith("assets/"):
            return skill.resources.get_asset(path.removeprefix("assets/"))

GCS 模式建议用 asyncio.gather 并发拉取,替代当前的串行遍历。

5.4 输出校验修正

对 Generator 和 Reviewer 的输出加结构化校验:

from pydantic import BaseModel

class ReviewOutput(BaseModel):
    summary: str
    findings: list[dict]  # {severity, location, message, fix}
    score: int  # 1-10
    top_recommendations: list[str]

# 在 Agent 回复后校验
try:
    result = ReviewOutput.model_validate_json(agent_response)
except ValidationError as e:
    # 要求 Agent 重新格式化
    ...

5.5 技能治理:企业级 Skill Registry

治理维度
建议方案
版本管理
Git 仓库 + 语义化版本(skill 目录名含版本号)
权限控制
GCS IAM 或 Git 分支保护规则
发布审核
PR 审查 + SKILL.md lint(校验 frontmatter 格式、description 质量)
使用审计
在 SkillToolset 的 load_skill 中埋点,记录激活次数和 token 消耗
退役管理
frontmatter 中加 deprecated: true,list_skills 时标记

6. 总结

Pattern
SkillToolset 支持
ADK 整体支持
企业可用性
落地建议
Tool Wrapper
✅ 完全
✅ 完全
直接使用
Generator
✅ 完全
✅ 完全
中高
加 Pydantic 输出校验
Reviewer
✅ 完全
✅ 完全
中高
加结构化输出 parser
Inversion
⚠️ 仅约定
🔧 可补位
用 before_tool_callback + state 门控
Pipeline
⚠️ 仅约定
🔧 可补位
用 SequentialAgent + require_confirmation

核心建议

  1. ADK Skill 定义知识,ADK Agent 编排层(或外部框架)编排流程。这是最务实的分工。
  2. 不要把 SKILL.md 当万能药。它是一种优秀的知识封装格式,但不是工作流引擎。
  3. Inversion 和 Pipeline 不是"不能用",而是"不能只用 SKILL.md" 。结合 before_tool_callbackSequentialAgentrequire_confirmation,ADK 自身就能补位。
  4. skills 模块仍是实验性的。在选型时要有 Plan B,密切关注 API 变更。
  5. description 写得比 instructions 重要。企业应该建立 skill 的 description 评审机制。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询