ADK-Python 如何用 SKILL.md 的 frontmatter 编写 Agent Skill 并接入 SkillToolset 按需加载
发布时间:2026/9/14 6:42:47 作者:尧图编辑部 阅读量:1,286

ADK-Python 如何用 SKILL.md 的 frontmatter 编写 Agent Skill 并接入 SkillToolset 按需加载【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python如果你把 Agent 可能用到的所有指令都塞进 system prompt每一轮对话都要为其中大部分无用的内容支付 token 成本。ADK-PythonAgent Development Kit的 Skills 机制用来解决这个问题把每套指令拆成一个独立的 skill 目录模型只先看到每个 skill 的 name 和 description确认相关后才加载完整指令和配套资源。本文的任务是按SKILL.md的格式规范编写一个 skill 目录用google.adk.skills的 loader 加载它再交给SkillToolset挂到 Agent 上让模型在需要时才拉取指令和资源。以下内容以docs/guides/skills/skill/index.md为主要依据注意 skills 包目前标记为 experimentalAPI 可能随时变化见 src/google/adk/skills/README.md 的警告。Skill 的三个层级与目录结构一个 skill 在磁盘上就是一个目录目录名即 skill 名。loader 只认目录根部的SKILL.md其余都是可选的只有三个子目录名会被 loader 读取weather-skill/ SKILL.md # required references/ # optional weather_info.md assets/ # optional station_codes.csv scripts/ # optional get_humidity.py资源按“按需取用”分成三个层级模型按顺序逐层深入frontmattername 加一段 description是模型一开始就能看到的唯一部分且对所有已安装 skill 都可见instructionsSKILL.md的正文只有模型根据 description 判断该 skill 相关后才读取resources参考文档、数据文件、可执行脚本每个文件由模型按名字单独取用且仅在指令要求时才取。加载完成后这些内容进入内存中的Skill对象结构正好对应三部分frontmatter、instructions、resources。仓库中的完整示例见 contributing/samples/environment_and_skills/skills/skills/weather-skill/SKILL.md其 frontmatter 为--- name: weather-skill description: A skill that provides weather information based on reference data and scripts. metadata: adk_additional_tools: - get_wind_speed ---编写 SKILL.mdfrontmatter 格式与校验规则SKILL.md由 YAML frontmatter 和 markdown 正文两半组成。解析器要求依据 src/google/adk/skills/_utils.py 与文档文件必须以---开头且必须有第二个---闭合 frontmatter否则抛ValueErrorfrontmatter 必须能解析为 YAML mappingname和description都是必填项name必须是 lowercase kebab-casea-z、0-9、单个连字符无首尾或连续连字符最长 64 字符loader 会先做 Unicode NFKC 归一化再校验。下划线只有在启用SNAKE_CASE_SKILL_NAMEfeature 时才允许且开启后也不允许混用连字符和下划线name必须等于目录名weather-skill/SKILL.md里写name: weather会直接抛ValueError。重命名 skill 永远是两处改动目录名 name字段description非空最长 1024 字符compatibility如果用到最长 500 字符。loader 对这些规则是严格报错而不是警告拼写或格式错误会在加载时以ValueError暴露而不是在运行时表现为奇怪的行为。文件名可以写成SKILL.md或skill.mdSKILL.md优先被检查。闭合---之后的所有内容去掉首尾空白成为skill.instructions正文没有固定模板loader 不要求任何结构——写成模型执行任务所需的步骤即可资源引用使用相对 skill 目录的路径。frontmatter 中未知的顶层键会被保留而不是拒绝这使得为其他 agent runtime 写的 skill 文件夹通常可以原样加载skills 遵循 Agent Skills 约定。frontmatter 字段字段类型默认说明namestr必填kebab-case 标识符最长 64 字符必须与目录名一致descriptionstr必填这个 skill 做什么、何时使用最长 1024 字符licensestr \| NoneNoneskill 内容的许可证ADK 不解释compatibilitystr \| NoneNone自由文本最长 500 字符ADK 不解释allowed_toolsstr \| NoneNone空格分隔的预批准工具列表也接受 YAML 键allowed-toolsmetadatadict[str, Any]{}客户端相关属性ADK 读其中两个键见下两个决定运行行为的要点description决定 skill 是否被使用。它是模型选择 skill 时唯一的依据应写成“做什么 何时用”而不是标题。文档指出只用了 1024 字符上限一小部分的 description往往会在竞争中被写得更充分的描述击败。metadata.adk_additional_tools是工具名列表模型激活该 skill 时SkillToolset会在你传入的additional_tools里按名字查找匹配项并把命中项加入后续对话的工具列表。这样工具只在 skill 激活时出现而不是每轮都占着工具列表。注意值是列表写成裸字符串会触发校验错误名字与任何已提供工具都对不上的会被静默跳过、没有任何警告——如果 skill 承诺的工具一直没出现对照你的 Python 函数名检查拼写。另一个副作用如果 App 上启用了context_cache_config工具声明是缓存前缀的一部分skill 激活工具会改动工具列表导致该次之后的请求缓存未命中、按全价付费前缀。不声明 additional tools 的 skill 则没有这个成本因为其指令作为工具响应返回不触碰前缀。metadata.adk_inject_state必须是布尔值。设为true后skill 正文在模型调用load_skill时经过inject_session_state渲染把{dev_name}替换为当时 session state 中的dev_name值写成{var?}则在 key 缺失时替换为空字符串而不是抛错——skill 常在它提到的所有 key 设置之前加载所以这通常是想要的行为。加载 skill 并检查加载结果最直接的加载方式是对 skill 目录调用一次 loader。以仓库示例 contributing/samples/environment_and_skills/skills/agent.py 中的 weather-skill 为例加载并接入 Agent 的完整代码来自 docs/guides/skills/skill/index.mdimport pathlib from google.adk.agents import Agent from google.adk.skills import load_skill_from_dir from google.adk.tools.skill_toolset import SkillToolset def get_wind_speed(location: str) - str: Returns the current wind speed for a given location. return fThe wind speed in {location} is 10 mph. weather_skill load_skill_from_dir( pathlib.Path(__file__).parent / skills / weather-skill ) root_agent Agent( nameweather_agent, descriptionAn agent that answers weather questions., tools[ SkillToolset( skills[weather_skill], additional_tools[get_wind_speed], ) ], )get_wind_speed作为 additional tool 传入正是因为 frontmatter 的metadata.adk_additional_tools按名字引用了它。想确认 loader 实际生成了什么Skill对象直接暴露三个层级这就是本地验证方式weather_skill.name # weather-skill weather_skill.description # the description line weather_skill.instructions # the markdown body weather_skill.resources.list_references() # [weather_info.md] weather_skill.resources.get_script(get_humidity.py).src # the script sourcelist_references返回[weather_info.md]、src返回脚本源码是文档给出的示例结果。get_reference、get_asset、get_script对缺失的 key 返回None而不是抛异常Script的__str__直接返回其src可以原样放进 prompt。加载多个 skill 的可选路径load_skills_from_dir按排序顺序遍历直接子目录加载每个包含SKILL.md的目录。没有SKILL.md的子目录被静默跳过但任何一个有SKILL.md的目录校验失败会让整个调用抛异常——一个坏掉的 skill 导致全部加载失败list_skills_in_dir只读 frontmatter返回dict[str, Frontmatter]比前者宽容得多无效 skill 被记录并跳过基础路径不是目录时只产生警告和空 dict每个 loader 都有_async变体如load_skill_from_dir_async在 worker 线程中运行阻塞版本参数和返回值与同步版一致适合在 async handler 内调用以免阻塞事件循环。SkillToolset 如何向模型暴露按需加载skill 进入SkillToolset后toolset 向模型发布四个工具list_skills、load_skill、load_skill_resource、run_skill_script配置了 registry 时会出现第五个search_skills接口细节见 docs/guides/skills/skill_registry/index.md。模型按顺序调用它们完成三层渐进披露list_skills返回所有已安装 skill 的 name 和 description第 1 层load_skill返回所选 skill 的正文第 2 层load_skill_resource或run_skill_script取单个文件或脚本第 3 层。每次调用都以工具响应形式返回答案所以 skill 正文是进入对话而不是写进 system instruction。两点与运行直接相关的行为脚本必须有地方执行。带scripts/目录的 skill 在任何地方都能加载但模型只有在SkillToolset收到了code_executor或environment或 Agent 本身有code_executor时才能真正执行脚本否则run_skill_script向模型返回NO_CODE_EXECUTOR错误。仓库示例 agent 使用了UnsafeLocalCodeExecutor()源码注释明确提醒它有安全隐患、不应在生产环境使用。资源路径的约定references/放预期被当作散文阅读的文档assets/放预期被当作数据查阅的文件schema、模板、示例。这个区分是约定而非机制同一个工具取两者没有任何东西强制区分放在对下一个读文件夹的人更合理的位置即可。常见问题与限制目录名是契约的一部分重命名 skill 必须同时改文件夹和name字段否则加载失败。allowed_tools是惰性的ADK 解析并保留它但不用它做任何限制。它来自 Agent Skills 规范保留它只是为了让 skill 文件夹经过 ADK 后能原样往返。非 UTF-8 脚本会被丢弃scripts/下的二进制文件被跳过并记录日志警告不会出现在resources.scripts里同样的文件在references/或assets/下会作为bytes保留。状态注入是 opt-in 且只在加载时发生没有metadata.adk_inject_state: true时正文里的{placeholder}会原样传给模型开启后替换发生在模型调用load_skill那一刻之后 session state 的变化不会重新渲染已加载的 skill。snake_case 名字需要开 feature默认只接受 kebab-casesnake_case 需启用SNAKE_CASE_SKILL_NAMEfeature见 feature registry 指南。从google.adk.skills导入DEFAULT_SKILL_SYSTEM_INSTRUCTION已弃用会发DeprecationWarning应从google.adk.tools.skill_toolset导入。下一步完整可运行示例contributing/samples/environment_and_skills/skills目录加载的 skill 与 Python 定义的 skill 合并在一个 toolset其 agent.py 展示了两种定义方式并存完全由 skill 驱动的 agentcontributing/samples/environment_and_skills/skills_agent从 GCS bucket 加载 skillload_skill_from_gcs_dir/list_skills_in_gcs_dir与本地函数对应需要可选的google-cloud-storage包缺失时抛带安装提示的ImportError示例contributing/samples/environment_and_skills/skills_agent_gcsskill 正文从 session state 个性化contributing/samples/environment_and_skills/skills_inject_stateskill 目录较多或需要跨 agent 共享目录时实现SkillRegistry接入search_skills见 SkillRegistry 指南。【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考