微信扫码
添加专属顾问
我要投稿
谷歌ADK开发者必知的5种Agent Skill设计模式,深入解析源码实现与框架保障。 核心内容: 1. 五种Agent Skill设计模式的详细解析 2. SkillToolset的三层按需加载架构实现 3. 源码中框架级保障与提示词实现的对比分析
TL;DR:结合 adk-python 源码,讨论下 Google Cloud Tech 发布的 5 类 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+ 点赞。文章提出了五种设计模式:
这五个模式确实概括了 SKILL.md 的主流用法。但一个关键问题被忽略了:这些"模式"在 adk-python 的源码中到底实现了多少?哪些有框架级保障,哪些只是靠提示词"许愿"?
ADK 的 skills 体系围绕 SkillToolset 类构建,实现了一套三层 progressive disclosure(渐进式披露):
list_skills | |||
load_skill | |||
load_skill_resource |
核心初始化代码(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)。这确实能有效控制上下文消耗。
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 的核心路径,经过测试。企业可以放心使用。
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 校验。
Reviewer 模式在源码层面与 Tool Wrapper 完全共享同一套代码。references/review-checklist.md 被加载的方式和 references/conventions.md 一模一样。
区别仅在于 SKILL.md 的 instructions 赋予了不同语义:
评分逻辑(error/warning/info 分级)、结构化输出(Summary/Findings/Score)——这些全部由 instructions 中的自然语言驱动,源码不参与。
评价:和 Tool Wrapper 一样可靠。但企业若需要稳定的 JSON 格式评审结果,请在 Agent 外层加 output parser。
这是第一个需要警惕的 Pattern。
文章中 Inversion 的核心是"阶段门控":
"DO NOT start building until all phases are complete"
但在 adk-python 源码中,没有任何代码实现阶段状态管理或门控逻辑。我们搜索了整个 skills 模块和 SkillToolset:
phase 或 stage 状态tool_context.state 中唯一与 skill 相关的 key 是 _adk_activated_skill_{agent_name},仅记录哪个 skill 被激活,不记录执行到哪个阶段这意味着 "DO NOT proceed" 的约束完全依赖大模型对自然语言的遵守。实测表明:
不过值得注意的是,ADK 的 before_tool_callback 机制提供了一条补救路径:你可以在回调中检查 tool_context.state 中的阶段标记,在大模型试图跳阶段时拦截工具调用。但这需要开发者自行实现,SkillToolset 本身不会自动解析 SKILL.md 中的阶段约束。
评价:SkillToolset 层面仅约定,无保障。但 ADK 的 callback 机制提供了自定义门控的扩展点。在 PoC 演示中可以直接用 SKILL.md 约定,在生产中必须用 before_tool_callback + session state 补位。
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 不会解析这段话并自动挂载确认门控。
与成熟的工作流编排框架对比(修正版):
有require_confirmation) | |||||
评价:SkillToolset 层面仅约定。但 ADK 自身的 Agent 编排层(SequentialAgent + require_confirmation)已经具备了 Pipeline 的基本能力。务实做法是:不要在单个 SKILL.md 中定义 Pipeline,而是把每个步骤拆成独立 Skill,用 SequentialAgent 编排 + require_confirmation 做门控。
三层按需加载是个好设计,但实现中有性能问题:
load_skill_resource 都从 skill.resources 读取,同一个 reference 被多次加载时无 LRU 缓存_list_skills_in_gcs_dir 逐个下载每个 skill 的 SKILL.md,10 个 skill 就是 10 次串行网络请求RunSkillScriptTool 将整个 skill 的 references/assets/scripts 打包进执行环境,大型 skill 可能触发 _MAX_SKILL_PAYLOAD_BYTES 限制adk-python 的 src/google/adk/skills/README.md 明确写着:
"This is experimental"
此外:
SkillToolset 未出现在 tools/__init__.py 的 lazy mapping 中llms.txt(ADK 的官方能力描述文件)完全没有提及 skills这些信号表明:skills 目前在 ADK 中是二等公民。API 可能在后续版本发生 breaking change。
社区反馈的一个共识:SKILL.md 的 description 字段比 instructions 更重要。因为 description 决定了大模型是否会激活这个 skill——如果 description 写得不够精准,skill 可能永远不会被调用,或者被错误地调用。
这带来一个反直觉的问题:你花 80% 精力写的 instructions 可能白费,因为前置的 description 就没写对。
不要依赖 "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 内部。
有两条路径,根据团队技术栈选择:
路径 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:
核心原则不变:ADK Skill 定义知识,编排机制(无论原生还是外部)控制流程。
在 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 并发拉取,替代当前的串行遍历。
对 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 重新格式化
...
deprecated: true,list_skills 时标记 |
before_tool_callback + state 门控 | ||||
SequentialAgent + require_confirmation |
核心建议:
before_tool_callback、SequentialAgent、require_confirmation,ADK 自身就能补位。53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-03-19
写 skill 全靠感觉?新版 skill-creator 用数据说话
2026-03-19
10个必装的Claude Skills,装上之后,Claude才算真正发挥威力!
2026-03-19
“MCP已死,CLI当立”的真相是什么?
2026-03-18
skills将成为未来个人生产力资产 | Claude Cowork核心人员对话实录
2026-03-18
Claude Code 实践经验:Skills 的用法与设计心得
2026-03-18
「必读」新鲜出炉,全都看过来:Claude code团队内部skill构建踩坑经验大全来了
2026-03-18
24/7云端“小龙虾”SkyClaw携六大神级Skills重新定义AI生产力
2026-03-18
从openclaw与clawhub出发,一个Skill系统真正要解决的4个工程问题
2026-03-10
2026-03-04
2026-03-03
2026-03-05
2026-03-04
2026-03-05
2026-03-03
2026-03-05
2026-03-02
2026-03-11