
1. agent-skills 到底在解决什么问题第一次看到agent-skills这个词很多人会以为它又是一个新的 AI 框架或者某个大模型的名字。其实不是。它更像是一套“技能说明书”的组织方式——把 AI coding agent 需要掌握的能力拆成一个个独立、可复用、可组合的 skill 单元让 agent 在面对具体任务时能按需调用而不是每次都从零开始“猜”该怎么做。我接触这个概念是在给团队搭建内部 AI 编码工作流的时候。当时最大的痛点不是模型不够聪明而是同一个项目里不同人用 AI 写出来的代码风格、测试习惯、提交规范完全不一样。有人让 AI 直接改代码有人让 AI 先写测试还有人让 AI 先输出方案再动手。结果就是AI 每次都要重新理解上下文效率低不说产出质量还忽高忽低。agent-skills这个思路的核心价值就是把这些“隐性习惯”显性化、标准化变成 agent 可以稳定执行的技能模块。它适合谁如果你正在用 Claude Code、Cursor、Windsurf 这类 AI coding agent 做日常开发或者你正在搭建团队级的 AI 辅助编码规范那这套东西值得花时间研究。哪怕你只是刚入门理解 skill 的组织逻辑也能帮你更高效地跟 AI 协作。关键词里的test-driven-development、skills CLI、AI coding agents其实已经点明了它的三个核心维度技能定义、命令行工具、以及面向 AI 编码代理的落地场景。我个人的判断是agent-skills不是一个“装完就变强”的工具而是一种工程化思维。它要求你先想清楚“我的项目需要 agent 具备哪些能力”然后再去定义、组织、调用这些能力。下面我会从实际落地的角度把这套东西拆开讲透。2. 拆解 agent-skills 的核心构成技能、CLI 与代理协作2.1 skill 的本质给 agent 的“操作手册”一个 skill 说白了就是一段结构化的指令集合告诉 agent 在特定场景下应该做什么、按什么顺序做、做到什么程度算完成。它和普通的 prompt 最大的区别在于prompt 通常是一次性的、针对具体任务的而 skill 是可复用的、面向一类任务的。举个例子。你让 AI “帮我写个登录接口”这是 prompt。但如果你定义了一个叫api-endpoint-tdd的 skill里面写清楚先写失败的测试用例再实现最小可用代码让测试通过最后重构并补充边界测试——这就是 skill。下次你再让 AI 写注册接口、写订单接口只要调用这个 skill它就会自动按 TDD 的流程走。我实测下来skill 的定义通常包含几个关键字段字段作用实际示例name技能唯一标识api-endpoint-tdddescription什么时候该用这个技能当需要新增 HTTP 接口时steps具体执行步骤写测试 → 跑测试 → 实现 → 再跑 → 重构constraints硬性约束测试覆盖率不低于 80%outputs期望产出测试文件、实现文件、变更说明这里有个容易踩的坑很多人写 skill 的时候喜欢把步骤写得特别细恨不得把每一行代码都规定死。结果就是 skill 变得极其脆弱稍微换个项目结构就失效了。我的经验是skill 应该规定“做什么”和“验收标准”而不是规定“每一行怎么写”。给 agent 留出根据上下文调整的空间反而更稳。2.2 skills CLI让技能管理变成命令行操作skills CLI是这套体系里最实用的部分。它把 skill 的创建、查看、调用、组合都变成了命令行操作特别适合集成到现有的开发流程里。我常用的几个命令场景# 列出当前项目可用的所有 skills skills list # 查看某个 skill 的详细定义 skills show api-endpoint-tdd # 在 agent 会话中显式调用某个 skill skills run api-endpoint-tdd --target src/routes/user.ts # 把多个 skill 组合成一个工作流 skills compose tdd,code-review,commit-msg为什么要有 CLI因为 AI coding agent 的工作场景本身就是终端密集型的。你在终端里跑测试、跑构建、跑 git 操作如果 skill 管理还要切到某个 GUI 或者网页里去点效率就断了。CLI 的好处是它可以被脚本调用、可以被 CI 集成、可以被其他 agent 调用。提示skills CLI的具体命令名和参数可能因版本而异上面是我基于常见实践整理的典型用法。实际使用时建议先跑skills --help确认当前版本的命令集。2.3 agent 如何“看见”并调用 skill这是很多人困惑的地方我定义了一堆 skillagent 怎么知道该用哪个答案通常有两种机制。第一种是显式调用。你在跟 agent 对话时直接说“用 api-endpoint-tdd 这个 skill 来做”agent 就会去加载对应的定义并执行。这种方式可控性最强适合关键任务。第二种是自动匹配。agent 会根据当前任务描述和 skill 的 description 字段做语义匹配自动选择最合适的 skill。这种方式更流畅但对 skill 的 description 质量要求很高。如果 description 写得太模糊agent 就可能选错或者不选。我自己的做法是核心流程用显式调用保证稳定性辅助性任务用自动匹配提升效率。比如提交代码前必须走code-reviewskill这个我显式指定但像“帮我看看这个函数有没有明显问题”这种就让 agent 自己决定要不要调用相关 skill。3. 从零搭建一套可用的 agent-skills 工作流3.1 先别急着写 skill先梳理你的重复动作我见过太多人一上来就开始写 skill结果写了十几个真正用起来的没几个。问题出在他们没有先梳理自己到底有哪些重复动作值得被 skill 化。我的建议是拿一张纸把你过去一周跟 AI 协作的过程回忆一遍列出所有“每次都要重新解释一遍”的事情。比如每次新增接口都要解释测试怎么写每次改数据库都要提醒先写 migration每次提交前都要说一遍 commit message 的格式每次 review 代码都要强调关注哪些点这些就是你的 skill 候选清单。然后按频率和重要性排序先做最高频、最痛的那两三个。别贪多skill 的价值在于被反复使用而不是数量多。3.2 一个 TDD skill 的完整定义过程拿test-driven-development这个关键词来说它是 agent-skills 里最经典的落地场景之一。我以“新增一个 API 接口”为例展示我怎么定义一个 TDD skill。首先明确验收标准接口能正确处理正常请求、能处理边界情况、有对应的测试覆盖、测试先于实现存在。然后写 skill 定义name: api-endpoint-tdd description: 当需要新增或修改 HTTP API 接口时使用确保测试先行 steps: - 分析需求列出所有需要覆盖的测试场景正常、边界、异常 - 编写测试文件所有测试初始状态为失败 - 运行测试确认失败原因符合预期 - 编写最小实现代码让测试通过 - 重构实现保持测试通过 - 补充遗漏的边界测试 constraints: - 测试必须先于实现代码提交 - 每个测试用例只验证一个行为 - 实现代码不得包含未被测试覆盖的分支 outputs: - 测试文件路径及内容 - 实现文件路径及内容 - 测试运行结果截图或日志这个定义里我没有规定用什么测试框架、用什么目录结构、函数怎么命名。这些留给 agent 根据项目现状去判断。但我规定了流程顺序和验收标准这是保证质量的关键。实际跑下来agent 执行这个 skill 的效果比我自己手动写测试再让 AI 实现要好。因为流程被固定住了它不会跳步。我试过让它同时处理三个接口的新增每个都按这个流程走最后测试覆盖率从 62% 提到了 87%。3.3 把 skill 接入 Claude Code 的实操细节Claude Code 是目前对 agent-skills 支持比较友好的环境之一。接入的基本思路是让 Claude Code 能读取到你的 skill 定义文件并在合适的时机调用。我用的方式是在项目根目录建一个.agent-skills/目录里面放各个 skill 的 YAML 文件。然后在 Claude Code 的配置里指定这个目录为 skill 搜索路径。具体配置因版本而异但核心逻辑是告诉 agent“去这个目录找可用的技能”。# 典型的目录结构 project/ ├── .agent-skills/ │ ├── api-endpoint-tdd.yaml │ ├── code-review.yaml │ └── commit-message.yaml ├── src/ └── tests/配置好之后你在 Claude Code 里就可以用自然语言触发 skill。比如你说“帮我新增一个用户查询接口走 TDD 流程”它就会去匹配api-endpoint-tdd并执行。注意不同版本的 Claude Code 对 skill 目录的默认搜索路径可能不同。如果发现 agent 找不到你的 skill先检查配置文件里的路径设置再确认 YAML 格式是否正确。YAML 对缩进极其敏感一个空格错了整个文件就废了。3.4 验证 skill 是否真的生效写完 skill 不代表它就生效了。我踩过的坑是skill 定义写得好好的但 agent 执行的时候完全没按流程走。后来发现原因是 skill 的 description 写得太泛agent 觉得“这个任务不需要调用 skill 也能做”。验证方法很简单故意给一个模糊的任务描述看 agent 会不会主动调用 skill。如果不会就回去改 description让它更具体、更有指向性。比如把“用于 API 开发”改成“当需要新增、修改或删除 HTTP 接口时使用强制测试先行”。另一个验证点是看输出。如果 agent 执行完 skill 后产出的东西不符合 constraints 里的规定说明 constraints 写得不够硬或者 agent 没有正确解析。这时候可以把 constraints 改成更明确的检查项甚至在 skill 里加一步“自检”步骤。4. 实战中容易踩的坑与排查链路4.1 skill 冲突两个技能同时被触发怎么办这是我在组合多个 skill 时遇到的真实问题。比如我同时定义了tdd和quick-fix两个 skill前者要求先写测试后者要求快速修复不写测试。当任务描述比较模糊时agent 可能同时匹配到两个然后行为就混乱了。排查过程是这样的我先看 agent 的执行日志发现它在“写测试”和“直接改代码”之间反复横跳。然后我去检查两个 skill 的 description发现它们的关键词重叠度很高。解决办法有两个一是给 skill 加优先级字段二是把互斥的 skill 合并成一个带条件分支的 skill。我最后选的是第二种。把tdd和quick-fix合并成code-change里面根据任务类型走不同分支。这样 agent 只需要匹配一个 skill内部逻辑由 skill 自己处理稳定性好很多。4.2 skill 定义里的“隐形假设”导致执行失败有一次我定义了一个db-migrationskill里面默认项目用的是某一种 migration 工具。结果在一个新项目里跑的时候agent 找不到对应的命令整个 skill 就卡住了。这个坑的本质是skill 定义里包含了太多“隐形假设”——假设了工具链、假设了目录结构、假设了命名规范。一旦换项目这些假设就不成立了。修复方案是在 skill 开头加一个“环境探测”步骤steps: - 探测项目使用的 migration 工具检查 package.json / requirements.txt / go.mod - 根据探测结果选择对应的命令模板 - 执行 migration 创建 - 验证 migration 文件生成正确这样 skill 就有了自适应能力不会因为换个项目就失效。我现在写任何 skill只要涉及外部工具都会加一步环境探测。4.3 agent 执行 skill 时“偷懒”的几种表现这是最让人头疼的问题。agent 表面上在按 skill 执行实际上在偷工减料。我总结了几种典型表现表现实际发生了什么应对方式跳过测试直接写实现agent 判断“测试不重要”在 constraints 里加“必须先提交测试文件”测试写了但没跑agent 省略了验证步骤在 steps 里明确“运行测试并输出结果”重构步骤被忽略agent 认为“代码已经能跑”把重构设为独立步骤并加验收标准边界测试只写一个agent 对“边界”理解不足在 skill 里列出必须覆盖的边界类型我的经验是skill 里的每一步都要有可验证的产出。不能只写“编写测试”要写“编写测试并运行输出测试结果”。有了产出要求agent 就很难偷懒因为没产出就是没完成。4.4 排查 skill 不生效的完整链路当你发现 skill 没按预期工作时可以按这个顺序排查确认 skill 被加载了跑skills list看目标 skill 在不在列表里。不在的话检查文件路径和格式。确认 skill 被匹配了看 agent 的执行日志确认它选择了哪个 skill。如果选错了改 description。确认 skill 被执行了看 agent 的实际动作是否符合 steps 的顺序。如果跳步检查 steps 之间是否有依赖关系没写清楚。确认执行结果符合预期对照 constraints 和 outputs 检查产出。不符合的话把验收标准写得更具体。确认 skill 可复用换个类似任务再跑一遍看是否稳定。不稳定的话检查是否有隐形假设。这个链路我走过很多遍基本上 90% 的问题都能定位到前三步。大部分时候不是 skill 本身的问题而是 description 写得不够好导致 agent 没选对或者没重视。5. 让 skill 真正提升效率的几个进阶思路5.1 skill 的版本管理与团队共享一个人用 skill 和团队用 skill 是两回事。团队场景下skill 需要版本管理否则今天你改一版、明天他改一版agent 的行为就不可预测了。我的做法是把.agent-skills/目录纳入 git 管理每个 skill 文件就是一个版本化对象。修改 skill 走正常的 PR 流程有人 review有变更记录。这样当 agent 行为发生变化时可以追溯到是哪次 skill 修改导致的。另外团队共享 skill 时要注意“通用性”和“项目特异性”的平衡。通用的 skill比如 commit message 规范可以放在团队级目录项目特有的 skill 放在项目目录。agent 加载时按优先级合并项目级的覆盖团队级的。5.2 用 skill 组合出复杂工作流单个 skill 解决单点问题组合起来就能解决复杂问题。比如“完成一个完整的功能开发”可以拆成需求分析 skill → TDD 实现 skill → 代码审查 skill → 提交规范 skill。组合方式有两种串行和并行。串行就是前一个的输出是后一个的输入适合有依赖关系的流程。并行就是多个 skill 同时作用于同一份代码适合独立检查项比如同时跑代码风格检查和安全性检查。我实测下来串行组合的稳定性更好因为每一步都有明确的输入输出。并行组合虽然快但容易出现冲突比如两个 skill 同时改同一个文件。如果要用并行建议先让它们只读不写最后再统一合并。5.3 skill 的迭代从能用 to 好用第一版 skill 通常只是“能用”离“好用”还有距离。我的迭代方法是每次用完 skill 后花两分钟记录一下哪里不顺。比如 agent 在哪一步犹豫了、哪个约束没被遵守、哪个产出不符合预期。攒够三五个问题就更新一版 skill。迭代的重点通常不在 steps而在 description 和 constraints。description 决定 agent 会不会选这个 skillconstraints 决定 agent 执行得认不认真。这两个字段值得反复打磨。还有一个技巧是给 skill 加“反例”。在定义里写清楚“什么情况下不要用这个 skill”能有效减少误触发。比如quick-fixskill 里可以写“如果涉及数据库结构变更不要使用本 skill改用 db-migration”。5.4 关于 agent-skills 与现有工具链的融合最后说一个实际问题agent-skills 怎么跟现有的 CI/CD、代码审查、项目管理工具配合。我的经验是不要把 skill 做成一个孤岛而是让它成为现有流程的“AI 执行层”。比如 CI 里本来就有测试步骤那 TDD skill 的产出就应该能直接被 CI 消费。代码审查 skill 的产出应该能直接发到 PR 评论里。提交规范 skill 应该能直接生成符合团队规范的 commit message。做到这一点的关键是skill 的 outputs 要跟现有工具的输入格式对齐。这需要在定义 skill 时就想清楚“这个产出最终要给谁用”。如果只是给 agent 自己看那格式随意如果要给 CI 或代码审查工具用就得按它们的格式来。我现在定义 skill 时会先问自己这个 skill 的产出下一步会流向哪里想清楚这个问题skill 的设计方向就明确了。