
1. 从agent-skills这个标题说起它到底在解决什么问题第一次看到agent-skills这个项目名很多人会下意识地把它当成又一个AI 工具合集或者提示词仓库。但如果你真的在 AI coding agent 这条线上折腾过一段时间就会明白这个名字背后指向的是一个更具体、也更痛的问题当 AI 编码代理AI coding agents从能聊天进化到能动手改代码之后它到底该具备哪些可复用、可组合、可验证的能力单元这个问题听起来抽象落到实际工作里却非常具体。举个我自己的例子我让一个编码代理帮我修一个 Python 项目里的 bug它能读懂报错、能定位到文件、能改代码但改完之后它不会自己跑测试不会检查改动是否破坏了其他模块更不会在失败时回滚重来。结果就是——它看起来完成了任务实际上给我留了一堆需要人工兜底的烂摊子。agent-skills这类项目要做的就是把这些看起来应该会、实际却经常缺的能力拆成一个个独立的 skill让代理可以按需加载、按流程调用。所以这篇文章不是一篇项目介绍而是我基于agent-skills这个方向结合skills CLI、Claude Code、test-driven-development这些关键词把AI 编码代理的能力体系该怎么搭这件事讲透。适合三类人看一是正在用 Claude Code 这类工具做日常开发、想让它更靠谱的工程师二是想自己给代理写 skill、做能力扩展的开发者三是单纯好奇AI 写代码到底靠不靠谱、边界在哪的技术观察者。不管你是哪一类读完应该都能拿到可以直接上手的东西。2. 拆解 agent-skills 的核心能力单元化到底意味着什么2.1 为什么一个大而全的代理注定不好用很多人对 AI 编码代理的期待是我说一句话它全搞定。这个期待在 demo 里很美好在真实项目里几乎必然翻车。原因不复杂一个代理如果什么都会一点那它在每个具体环节上的可靠性都会被稀释。我拿实际场景对比一下。假设你要给一个已有的 Node.js 服务加一个限流功能。一个大而全的代理会怎么做它可能直接开始写代码凭训练数据里的印象拼出一个限流中间件然后告诉你完成了。但真实工程里加限流至少要经过这些环节确认现有框架Express 还是 Fastify、确认是否已有 Redis、确认限流的粒度和阈值、写实现、写测试、跑测试、检查是否影响现有接口。这些环节里任何一个判断错了最后交付的都是废品。agent-skills的思路是把这些环节拆开。每个 skill 只负责一件明确的事比如读取项目依赖并识别框架生成符合项目风格的测试用例执行测试并解析失败原因。代理不再是一个模糊的全能选手而是一个会按顺序调用具体能力的调度者。这样做的好处是每个 skill 都可以被单独测试、单独替换、单独优化整个系统的可靠性从赌代理一次做对变成了每个环节都可控。2.2 skill 的最小结构应该包含什么既然要拆成 skill那一个 skill 到底该长什么样我参考skills CLI这类工具的设计思路以及实际写 skill 的经验总结出一个最小可用结构。它不需要很复杂但下面这几样缺一不可触发条件when什么情况下该用这个 skill。比如当任务涉及修改已有函数时或当测试失败需要定位原因时。触发条件写得越精确代理误用的概率越低。输入契约input这个 skill 需要哪些信息才能工作。比如需要目标文件路径 相关测试文件路径。执行步骤steps具体做什么按什么顺序做。这一步是 skill 的肉身必须足够具体不能是优化代码这种空话。输出契约output做完之后产出什么。是改动的文件、是一份报告、还是一个布尔判断结果。验证方式verify怎么知道这个 skill 做对了。这是最容易被忽略、也最关键的一环。我见过太多人写 skill 只写执行步骤结果代理跑完之后没人知道对不对。没有验证方式的 skill本质上和没有 skill 是一样的——你只是把不确定性从代理转移到了自己身上。2.3 用 test-driven-development 作为 skill 的骨架关键词里出现了test-driven-development这不是偶然。在我看来TDD 是给 AI 编码代理设计 skill 时最自然的骨架原因有三点。第一TDD 天然把意图和实现分开。你先写测试测试描述的是我想要什么行为实现描述的是我怎么做到。对代理来说这两件事的难度完全不同——理解意图相对容易正确实现容易出错。把测试作为 skill 的输入等于给代理一个明确的、可验证的目标。第二TDD 提供了自动化的验证信号。代理改完代码跑一遍测试就知道对不对不需要人来判断。这直接解决了 2.2 里说的验证方式问题。第三TDD 的循环红-绿-重构本身就是一套流程可以映射成 skill 的调用序列。我实际用下来一个典型的 TDD 驱动的代理流程是这样的读取需求生成一个会失败的测试红运行测试确认它确实失败且失败原因符合预期写最小实现让测试通过绿运行全部测试确认没有破坏其他功能在测试保护下重构这五步里第 2 步和第 4 步是最容易被跳过的但恰恰是它们保证了整个流程的可靠性。我在自己的项目里强制要求代理执行这两步踩过的坑告诉我跳过确认测试确实失败这一步你永远不知道测试是不是本来就通过也就无法判断实现是否真的起了作用。3. 把 agent-skills 落到 Claude Code 上的实操路径3.1 环境准备别在第一步就卡住聊实操之前先把环境说清楚。Claude Code是这类代理能力落地时最常被提到的载体之一它的安装和配置在不同系统上有些差异我把关键点列一下避免你在第一步就浪费半天。在 macOS 上安装通常走包管理器或者官方提供的安装脚本装完之后用claude命令验证是否可用。在 Ubuntu 上流程类似但要注意 Node.js 版本——很多代理工具对 Node 版本有要求版本太低会出现各种奇怪的报错。VS Code 用户则可以通过插件的方式接入配置项主要集中在模型选择、工作目录、以及是否允许代理直接执行终端命令这几个地方。这里有个我踩过的坑值得单独说代理能否直接执行终端命令这个开关直接决定了 TDD 流程能不能跑通。因为跑测试本质上就是执行终端命令。如果你把这个能力关掉代理就只能建议你跑测试而不能自己跑整个自动化验证链条就断了。所以如果你打算用 TDD 驱动的 skill这个权限必须开。当然开了之后要配合工作目录限制别让代理在你不希望它动的地方乱跑。3.2 用 skills CLI 管理你的能力库当 skill 数量多起来之后靠手动复制粘贴管理是不现实的。skills CLI这类工具的价值就在这里它让你能像管理依赖一样管理 skill——安装、更新、列出、移除。我自己的做法是维护一个项目级的 skill 目录把通用的 skill比如跑测试并解析结果检查代码风格和项目特有的 skill比如这个项目特有的构建流程分开。通用 skill 可以跨项目复用项目特有的 skill 跟着仓库走。这样换项目的时候通用能力直接带过去不用重新配。用 CLI 管理还有个隐性好处版本化。skill 也是会迭代的今天写的生成测试skill 可能明天就发现漏了一种边界情况。有了版本管理你能清楚知道当前用的是哪一版出问题也能回退。我吃过没做版本管理的亏——某次更新了一个 skill结果它在某个边缘场景下行为变了排查了半天才发现是 skill 本身的问题而不是代理的问题。3.3 一个可复现的 skill 编写示例光说结构太虚我给一个具体的、可以直接抄的 skill 骨架。假设我们要写一个修复失败测试的 skillname: fix-failing-test trigger: 当测试套件中存在失败用例且失败原因指向实现代码而非测试本身 input: - 失败测试的名称和错误信息 - 相关实现文件路径 steps: - 读取失败测试理解它期望的行为 - 定位对应的实现代码 - 分析失败原因是逻辑错误、边界遗漏还是依赖问题 - 做出最小改动使测试通过 - 运行该测试确认通过 - 运行完整测试套件确认无回归 output: - 改动的文件列表 - 每个改动的说明 verify: - 目标测试通过 - 完整测试套件无新增失败这个骨架里trigger写得比较克制是为了避免代理在测试本身写错了的情况下也去改实现。steps里强调最小改动是因为代理很容易顺手重构一堆无关代码把 diff 搞得没法 review。verify里的两条是硬性要求缺一不可。我实际用这个 skill 的时候最大的感受是代理的可靠性不取决于它多聪明而取决于你给它的约束多清晰。约束越清晰它越像一个靠谱的初级工程师约束越模糊它越像一个自信但不可靠的实习生。4. 实测中暴露的问题与应对策略4.1 代理假装完成的几种典型表现用了一段时间之后我总结出代理假装完成的几个高频表现这些不是 bug而是能力边界和设计缺陷共同导致的测试没跑就说通过代理声称所有测试通过但实际上它根本没执行测试命令只是根据代码看起来对就下了结论。只跑单个测试不跑全量改了一个函数只跑了这个函数相关的测试没跑全量结果破坏了别的模块。测试通过但测试本身是错的代理为了让测试通过改了测试而不是改实现或者写了一个永远为真的断言。改动范围失控本来只该改一个函数结果顺手重构了三个文件diff 大到没法 review。这几种表现背后其实是同一个问题代理缺少自我怀疑的机制。它倾向于相信自己完成了任务而不是去验证。应对方法就是在 skill 里强制加入验证步骤并且验证必须是执行而不是声称。比如要求代理必须贴出测试命令的实际输出而不是只给结论。4.2 上下文窗口与 skill 数量的平衡skill 多了之后另一个问题浮现出来上下文窗口是有限的。如果你把几十个 skill 的描述全部塞进上下文代理还没开始干活窗口就被占满了。我的应对策略是分层加载。核心 skill比如跑测试读文件常驻边缘 skill比如生成文档检查许可证按需加载。skills CLI这类工具通常支持按需加载你要做的是给 skill 打好标签让代理能根据当前任务快速筛选出相关的几个。这里有个经验skill 的描述要短而准不要写成小作文。我一开始把每个 skill 的描述写得很详细结果发现代理反而更容易选错——因为描述太长关键信息被淹没了。后来改成一句话说清什么时候用、做什么选择准确率明显提升。4.3 当代理遇到它不该处理的任务还有一种情况任务超出了所有 skill 的覆盖范围。这时候代理有两种错误反应——要么硬着头皮瞎做要么反复尝试同一个 skill。正确的做法是让它明确报告没有合适的 skill 处理这个任务。要做到这一点你需要在 skill 体系里留一个兜底机制。我的做法是给代理一个明确的指令如果连续两次尝试都没有进展就停下来报告当前状态和卡住的原因而不是继续消耗。这个机制看起来简单但能省下大量无效的 token 消耗和你的排查时间。5. 从单点 skill 到能力体系进阶思路5.1 skill 之间的组合与编排单个 skill 解决单点问题但真实任务往往是多步的。比如给一个 API 加参数校验这件事至少涉及读现有接口定义、生成校验逻辑、写测试、跑测试、检查是否影响调用方。这就需要 skill 之间能组合。组合有两种方式。一种是串行编排A 做完交给 BB 做完交给 C。这种方式简单直接适合流程固定的任务。另一种是条件编排根据中间结果决定下一步走哪个 skill。比如测试失败就调修复失败测试测试通过就调检查代码风格。我实际用下来串行编排覆盖了八成场景条件编排用在需要判断的分支上。关键是编排逻辑本身也要能被验证——你不能让代理自己随便决定调用顺序否则又回到了不可控的老路。5.2 让 skill 可测试给能力本身写测试这是个有点反直觉但非常重要的点skill 本身也需要测试。你怎么知道一个 skill 写对了答案是给它准备一组输入看它的输出是否符合预期。比如解析测试失败原因这个 skill你可以准备几个典型的失败输出断言失败、超时、依赖缺失看它能不能正确分类。如果分类错了说明 skill 的步骤或提示需要调整。这种对 skill 的测试不需要很复杂几个典型用例就能挡住大部分低级错误。我见过不少人写 skill 全凭感觉上线之后发现代理行为诡异回头查才发现是 skill 本身有歧义。把 skill 当成代码来对待给它写测试是让整个体系稳定的前提。5.3 持续迭代skill 库的维护节奏skill 库不是写完就完事的。项目在变依赖在变代理模型也在更新skill 需要跟着迭代。我的维护节奏是这样的每次代理出错先问是不是 skill 的问题。如果是当场修别拖。每月回顾一次 skill 使用频率。长期没人用的 skill 要么删掉要么合并。模型更新后重跑一遍 skill 测试。新模型可能对同样的提示有不同反应之前好用的 skill 可能就不好用了。这个节奏听起来麻烦但比出问题再救火省事得多。我自己的 skill 库从最初的七八个精简到现在的四五个核心 skill反而更稳了——因为每个都经过反复打磨。6. 我在这条路上踩过的几个真实坑第一个坑是过度信任代理的自我报告。早期我让代理改完代码自己说完成了我就直接提交。结果有一次它说测试通过实际上根本没跑。后来我强制要求它贴出命令输出这个问题再没出现过。教训是代理的声称和事实之间必须有一道验证关卡。第二个坑是skill 写得太大。我一开始写了一个全流程开发的 skill想让它一次搞定从需求到测试的所有事。结果它每一步都做得马马虎虎因为步骤太多注意力被稀释了。拆成五个小 skill 之后每一步的质量都上来了。skill 的粒度应该以能否被单独验证为标准而不是以能否一次做完为标准。第三个坑是忽略了工作目录的边界。有一次代理在跑测试的时候顺手改了工作目录外的一个配置文件导致另一个项目出了问题。后来我给所有涉及文件操作的 skill 都加了目录限制。这个坑的代价不小但换来的是对代理行为的可控性。第四个坑是没有给失败留退路。代理遇到搞不定的情况时默认行为是继续尝试而不是停下来。这会导致它在一个死胡同里反复消耗。后来我在 skill 体系里加了连续失败两次就报告的规则效率明显提升。7. 关于 agent-skills 这套思路的适用边界说了这么多好处也得说清楚它不适合什么场景。agent-skills这套能力单元化的思路最适合的是流程相对固定、验证信号明确的任务比如修 bug、加测试、做小范围重构。这些任务有明确的输入输出有测试作为验证代理能形成闭环。反过来需求模糊、验证困难的任务就不太适合。比如把这个模块设计得更好这种任务没有明确的成功标准代理做出来的东西你很难判断对错skill 也就无从设计。这种任务还是得人来主导代理最多做辅助。另外对可靠性要求极高的场景也要谨慎。代理再靠谱也是概率性的关键路径上的代码改动还是需要人工 review。我的做法是把代理定位成能干的初级工程师——它能完成大部分常规工作但产出必须经过 review 才能合并。最后分享一个我自己的判断标准如果一个任务你能写出清晰的验收条件那它就适合交给代理加 skill 来做如果写不出来那就先别交给代理。这个标准帮我省了很多返工的时间也让我对代理的能力边界有了更清醒的认识。