
1. 从“skills”这个标题说起它到底指什么第一次看到“skills”这个标题很多人会以为是某个泛泛而谈的能力清单或者一份简历上的技能罗列。但结合热搜词里的 Agent Skills、Google Cloud、GKE、Genkit、codex skills、claude agent skills 这些词来看这里的 skills 显然不是指人类的能力而是指给 AI Agent 使用的技能包——一种把特定任务能力封装起来、让智能体可以按需调用的模块化单元。我最早接触这个概念是在做自动化工作流的时候。当时想让一个 Agent 帮我完成“从 GitHub 仓库拉取 issue、分类、生成周报、推送到指定频道”这一整条链路结果发现每次都要把全部逻辑塞进一个巨大的提示词里维护起来非常痛苦。后来看到有人把每个环节拆成独立的 skill比如“读取 issue 列表”“按标签分类”“生成 Markdown 周报”每个 skill 只做一件事Agent 根据任务自动选择调用哪个。那一刻确实有“打开新世界”的感觉。所以这篇内容我想聊的就是围绕Agent Skills 的设计、开发、安装、调试和实际落地把我在这个方向上踩过的坑、总结的方法、以及可以直接抄作业的步骤完整分享出来。不管你是刚听说 skills 这个概念的新手还是已经在用 codex skills、claude agent skills 做自动化的人应该都能从中找到对自己有用的部分。核心关键词会自然分布在各个章节里包括 skills 开发、skills 安装、skills 推荐、agent skills 测试等。2. Agent Skills 的整体设计与核心思路拆解2.1 为什么要把能力拆成 skill 而不是写一个大提示词这是理解 skills 价值的起点。假设你要做一个“自动挖洞”的 Agent如果把所有逻辑写在一个提示词里大概会是这样先扫描目标、再识别指纹、再匹配漏洞库、再生成报告。听起来没问题但实际运行时会遇到几个致命问题。第一上下文窗口被撑爆。每个环节的详细规则、参数、示例都塞在一起提示词动辄几千 token模型注意力被稀释后面步骤的指令容易被忽略。第二无法复用。你下次想做“自动生成分镜”的 Agent虽然也需要“扫描素材”这一步但没法直接拿来用只能复制粘贴再改。第三调试困难。整条链路出错时你很难定位是哪个环节的指令有问题。拆成 skill 之后每个 skill 是一个独立单元有自己的描述、输入输出定义、执行逻辑。Agent 在运行时根据当前任务动态选择加载哪个 skill。这就像从“一个人把所有活干完”变成“一个团队各司其职”效率和可维护性完全不是一个量级。2.2 skill 的基本结构描述、参数、执行体一个标准的 skill 通常包含三部分。描述部分告诉 Agent 这个 skill 是干什么的、什么时候该用它这部分写得越精准Agent 选错 skill 的概率越低。参数部分定义输入输出的格式比如一个“查询天气”的 skill 需要城市名作为输入返回温度、湿度、风力。执行体部分是真正干活的代码或提示词模板可以是一段 Python 函数、一个 API 调用、或者一段结构化的指令。我自己的习惯是给每个 skill 写一个skill.yaml或skill.json作为元数据描述里面包含 name、description、version、input_schema、output_schema、tags。执行体单独放在handler.py或prompt.md里。这样结构清晰也方便后续做 agent skills 测试时单独验证每个 skill。2.3 选型考量自建 skill 还是用现成的热搜词里有“skills 推荐”“skills 大全”“skills 下载平台有哪些”说明很多人想直接找现成的用。我的建议是分情况。如果是通用能力比如“读取网页内容”“发送邮件”“查询数据库”优先找现成的社区里已经有很多经过验证的实现没必要重复造轮子。但如果是跟你的业务强相关的比如“按照公司模板生成周报”“识别特定格式的工单”那必须自己开发因为现成 skill 不可能覆盖你的私有逻辑。另外要注意不同平台对 skill 的格式要求不一样。Google Cloud 生态下的 Agent Skills 可能跟 Genkit 配合使用而 codex skills 和 claude agent skills 各有自己的目录结构和加载方式。选型时要先确认你的 Agent 运行在哪个框架上再决定 skill 的写法。我见过有人把为 A 平台写的 skill 直接丢到 B 平台结果加载失败排查半天才发现是元数据字段名不匹配。3. 核心细节解析与实操要点3.1 skill 描述怎么写才能让 Agent 选对这是最容易被低估的环节。很多人写 skill 描述就一句话“处理数据”结果 Agent 面对“清洗 CSV”和“处理数据”两个 skill 时完全不知道该选哪个。好的描述应该包含三个要素动作、对象、场景。举个例子差的描述是“生成报告”。好的描述是“根据输入的 JSON 数据生成 Markdown 格式的周报适用于项目进度汇总场景输出包含标题、日期、完成事项、待办事项四个部分”。这样 Agent 在匹配任务时能明确知道这个 skill 的边界在哪里。还有一个技巧是给描述加上“不适用场景”。比如“本 skill 不处理 PDF 输入不生成图表”。这能进一步缩小匹配范围减少误调用。我在实际项目里做过对比加了不适用场景说明之后skill 选错的概率从大概三成降到了一成以下。3.2 参数设计输入输出要严格约束skill 的参数定义越严格运行时越稳定。我一般用 JSON Schema 来定义输入输出明确每个字段的类型、是否必填、取值范围。比如一个“查询订单”的 skill输入里 order_id 必须是字符串且长度固定输出里 status 只能是 pending、shipped、delivered 三个值之一。这样做的好处是Agent 在调用 skill 之前会先校验参数不符合就直接报错而不是带着错误参数执行到一半才失败。另外输出格式固定之后下游 skill 可以直接消费不需要再做额外的解析和清洗。这一点在串联多个 skill 时特别重要能省掉大量胶水代码。注意不要为了灵活性把参数设计得太宽松。我见过有人把所有输入都定义成 string 类型结果 Agent 传进来一个 JSON 字符串skill 内部还要判断是纯文本还是结构化数据逻辑变得非常复杂。宁可多定义几个 skill也不要让一个 skill 承担太多职责。3.3 执行体的实现方式选择执行体可以是代码也可以是提示词模板。怎么选我的经验是确定性任务用代码创造性任务用提示词。比如“计算两个日期之间的天数”“格式化电话号码”“调用某个 API”这些有明确规则的任务用 Python 函数实现最稳定不会出现模型幻觉。而“根据会议记录生成摘要”“把技术文档改写成通俗版本”这类需要语言理解的任务用提示词模板更合适。还有一种混合模式代码负责数据获取和预处理提示词负责内容生成。比如一个“生成竞品分析”的 skill先用代码从数据库拉取竞品数据再把数据填入提示词模板让模型生成分析文本。这样既保证了数据准确性又发挥了模型的语言能力。3.4 版本管理与依赖处理skill 多了之后版本管理是个大问题。我建议每个 skill 都带版本号并且在元数据里声明它依赖的其他 skill 或外部服务。比如“生成周报”这个 skill 依赖“读取 issue 列表”和“分类 issue”两个 skill如果后两者升级了接口前者需要同步更新。实际操作中我会在项目根目录放一个skills.lock文件记录每个 skill 的版本和依赖关系。部署时先检查依赖是否满足不满足就拒绝加载。这个做法借鉴了包管理器的思路虽然前期麻烦一点但能避免很多运行时才发现的兼容性问题。4. 实操过程与核心环节实现4.1 环境准备与目录结构假设我们要从零搭建一个支持 Agent Skills 的项目。首先确定目录结构我习惯这样组织project/ skills/ read_issues/ skill.yaml handler.py classify_issues/ skill.yaml handler.py generate_report/ skill.yaml prompt.md skills.lock agent.py每个 skill 一个文件夹文件夹名就是 skill 的标识符。skill.yaml放元数据handler.py或prompt.md放执行体。skills.lock记录版本和依赖。agent.py是主入口负责加载 skills 并根据任务调度。环境方面Python 3.10 以上安装必要的依赖比如pyyaml、jsonschema、以及你所用 Agent 框架的 SDK。如果跑在 Google Cloud 上可能还需要配置 GKE 集群和 Genkit 相关的工具链。这部分根据实际平台调整核心是保证 skill 加载器能正确读取元数据并注册到 Agent 的可用技能列表里。4.2 编写第一个 skill读取 issue 列表以“读取 GitHub issue 列表”为例。skill.yaml内容如下name: read_issues version: 1.0.0 description: 从指定 GitHub 仓库读取未关闭的 issue 列表返回标题、编号、标签、创建时间。适用于需要获取待处理任务的场景。不处理已关闭 issue不读取评论内容。 input_schema: type: object properties: repo: type: string description: 仓库全名格式为 owner/repo limit: type: integer default: 50 description: 最多返回多少条 required: - repo output_schema: type: array items: type: object properties: number: type: integer title: type: string labels: type: array items: type: string created_at: type: stringhandler.py里实现具体逻辑调用 GitHub API 获取数据按 schema 返回。注意异常处理比如仓库不存在、API 限流等情况要返回明确的错误信息方便 Agent 判断是否需要重试或换其他 skill。4.3 编写第二个 skill按标签分类这个 skill 的输入是上一个 skill 的输出输出是分类后的结构。skill.yaml里描述写清楚“根据 issue 的 labels 字段将其归入 bug、feature、question 三类无标签的归入 other”。执行体可以用代码实现因为分类规则是确定的。这里有个细节如果标签体系很复杂比如一个 issue 同时有 bug 和 urgent 两个标签归到哪类我的做法是在描述里明确优先级urgent 优先于 bugbug 优先于 feature。这样 Agent 调用时不会产生歧义。实际运行中这种边界情况的处理规则一定要提前定义好否则不同批次的分类结果会不一致。4.4 编写第三个 skill生成周报这个 skill 用提示词模板实现。prompt.md里写清楚输入格式和输出要求你是一个项目周报生成助手。输入是分类后的 issue 列表包含 bug、feature、question、other 四类。 请生成一份 Markdown 格式的周报包含以下部分 1. 标题项目名 周报 日期范围 2. 完成事项从 feature 类中提取已完成的条目 3. 待办事项从 bug 和 question 类中提取未完成的条目 4. 风险提示如果有 urgent 标签的 issue单独列出 输出只包含 Markdown 内容不要额外解释。skill.yaml里声明这个 skill 依赖前两个 skill 的输出格式。这样 Agent 在调度时会先确保前两个 skill 执行成功再把结果传给这个 skill。4.5 串联测试与 agent skills 测试方法三个 skill 写完后需要做端到端测试。我的测试方法是分三层。第一层是单元测试单独调用每个 skill传入模拟数据验证输出是否符合 schema。第二层是集成测试按顺序调用三个 skill检查数据流转是否正确。第三层是 Agent 调度测试给 Agent 一个自然语言任务“帮我生成本周项目周报”看它是否能自动选择正确的 skill 组合。第三层最容易出问题。常见情况是 Agent 跳过了分类 skill直接把原始 issue 列表传给周报 skill导致输出格式不对。排查时先看 Agent 的调度日志确认它选了哪些 skill、按什么顺序。如果选错了回去优化 skill 的描述让边界更清晰。我一般会反复调整描述措辞直到 Agent 在十次测试中至少九次能选对。提示agent skills 测试时建议准备一组标准任务集每次修改 skill 后都跑一遍观察通过率变化。这比凭感觉判断“应该没问题”可靠得多。5. 常见问题与排查技巧实录5.1 skill 加载失败从元数据查起最常见的问题是 skill 加载时报错。排查顺序是先看skill.yaml格式是否正确YAML 对缩进非常敏感一个空格错位就可能导致解析失败。再看必填字段是否齐全name、version、description、input_schema、output_schema 这五个字段缺一不可。最后看执行体文件是否存在、路径是否正确。我遇到过一种情况是 skill 文件夹名和 yaml 里的 name 不一致加载器按文件夹名查找但注册时用 yaml 里的 name导致调用时找不到。统一两者之后问题解决。所以建议文件夹名和 name 字段保持一致减少混淆。5.2 Agent 选错 skill描述优化与负样本Agent 选错 skill 的原因通常是描述不够区分度。解决办法有两个。一是给每个 skill 加“不适用场景”明确排除某些情况。二是提供负样本在描述里写“当用户要求 X 时不要使用本 skill应该使用 Y skill”。这听起来有点笨但实际效果很好。另外如果两个 skill 功能相近考虑合并成一个用参数区分不同模式。比如“读取 issue”和“读取 pull request”可以合并成“读取仓库条目”用 type 参数区分。这样能减少 Agent 的选择困难。5.3 执行超时或返回异常设置合理的超时与重试skill 执行体如果涉及网络请求一定要设置超时。我一般设 10 秒超过就返回超时错误。Agent 收到错误后可以选择重试或换其他 skill。重试次数建议不超过 3 次避免无限循环。还有一种情况是 skill 返回了不符合 schema 的数据。这通常是执行体内部逻辑有 bug比如返回了 None 而不是空数组。排查时先在本地单独运行执行体打印实际输出跟 schema 对比。如果执行体没问题那就是 Agent 传参有问题检查输入是否符合 schema 定义。5.4 常见问题速查表问题现象可能原因排查方向解决建议skill 加载失败yaml 格式错误检查缩进和字段名用 yaml 校验工具验证Agent 不调用 skill描述不清晰查看调度日志优化描述加不适用场景执行超时网络请求无超时检查执行体代码设置 10 秒超时输出格式错误schema 不匹配对比实际输出与定义修正执行体或放宽 schema依赖 skill 未执行依赖声明缺失检查 skills.lock补充依赖关系版本冲突多个 skill 依赖不同版本查看加载日志统一版本或做兼容层5.5 独家避坑技巧第一个技巧给 skill 加日志。每个 skill 在执行开始和结束时打印一条日志包含 skill 名、输入摘要、输出摘要、耗时。这样出问题时能快速定位是哪个环节慢了或错了。日志级别用 DEBUG生产环境可以关掉。第二个技巧skill 描述里加示例。比如“输入示例{repo: owner/repo, limit: 10}输出示例[{number: 1, title: ...}]”。Agent 看到具体示例后匹配准确率会明显提升。这招在 codex skills 和 claude agent skills 上都验证过效果稳定。第三个技巧定期清理无用 skill。项目跑久了总会积累一些不再使用的 skill。它们不仅占用加载时间还会干扰 Agent 的选择。我一般每个月 review 一次把最近 30 天没有被调用过的 skill 标记为 deprecated再过一个月还没用就删除。6. 进阶扩展从单机到云端与多 Agent 协作6.1 在 Google Cloud 上部署 skill 服务如果 skill 需要被多个 Agent 共享可以考虑部署成独立服务。在 GKE 上跑一个 skill registry每个 skill 作为一个微服务通过 HTTP 或 gRPC 暴露接口。Agent 启动时从 registry 拉取可用 skill 列表运行时按需调用。这样 skill 的更新和扩缩容都独立于 Agent运维更方便。Genkit 在这个场景下可以帮忙做流程编排和可观测性。把 skill 调用链路接入 Genkit 的追踪系统能看到每个 skill 的输入输出和耗时排查问题比看日志直观得多。不过这套方案复杂度较高建议先把单机版跑通再考虑上云。6.2 多 Agent 共享 skill 的权限与隔离多个 Agent 共用一套 skill 时要考虑权限问题。比如“删除数据”这种危险 skill不应该让所有 Agent 都能调用。我的做法是在 skill 元数据里加allowed_agents字段加载时校验当前 Agent 是否在允许列表里。不在列表里的 Agent 看不到这个 skill自然也不会调用。隔离方面每个 Agent 可以有自己私有的 skill 目录加上共享的公共 skill 目录。加载时先加载私有再加载公共同名 skill 私有覆盖公共。这样既能复用通用能力又能保留个性化逻辑。6.3 skill 的自动化测试与持续集成skill 多了之后手动测试不现实。我建议搭一个 CI 流程每次提交代码后自动运行所有 skill 的单元测试再跑一遍集成测试和 Agent 调度测试。测试不通过就阻止合并。测试用例放在tests/目录下跟 skill 一一对应。调度测试可以用固定的一组自然语言任务断言 Agent 选择的 skill 序列是否符合预期。比如任务“生成本周周报”应该触发 read_issues → classify_issues → generate_report 这个序列。如果实际序列不同测试失败提示可能某个 skill 的描述需要调整。6.4 从 skills 到 superpower skills 的演进思路热搜词里有个“superpower skills”我理解是指能力特别强、覆盖面特别广的 skill。但我的经验是与其做一个大而全的 superpower skill不如做多个小而精的 skill 再组合。大 skill 的问题是内部逻辑复杂调试困难而且一旦某个环节出错整个 skill 都不可用。小 skill 可以独立测试、独立替换组合起来反而更灵活。如果确实需要“超级能力”可以用一个编排 skill 来调度多个子 skill。编排 skill 本身不干活只负责按顺序调用子 skill 并处理它们之间的数据传递。这样既有了超级能力又保持了每个子 skill 的简洁性。7. 一些实际体会我在多个项目里用 Agent Skills 做自动化最大的感受是skill 的质量比数量重要得多。一开始我贪多写了三四十个 skill结果 Agent 选择困难经常调错。后来砍到十几个每个都精心打磨描述和参数整体成功率反而上去了。另一个体会是不要指望 Agent 一次就选对 skill。把它当成一个需要调教的助手通过日志观察它的选择逻辑发现偏差就调整描述。这个过程可能需要反复几轮但一旦调好后续运行就非常稳定。最后分享一个小技巧给每个 skill 写一句“一句话说明”放在描述的最前面。Agent 在快速筛选时先看这句话匹配上了再看详细描述。这能显著加快调度速度尤其是在 skill 数量较多的时候。我实测下来加了这句话之后Agent 的响应时间大概缩短了两成。