ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用 Skills 给 Agent 立规矩:统一团队代码规范与测试流程的落地实践

用 Skills 给 Agent 立规矩:统一团队代码规范与测试流程的落地实践 最近大半年我一直在折腾 Agent 辅助开发这件事模型能力早就不是瓶颈了真正让我头疼的是同一个 Agent在 A 项目里表现得像个懂行的老同事换到 B 项目就开始自由发挥——缩进风格换了、变量命名随心所欲、连提交信息的格式都能给你整出三种花样。后来我把团队规范做成了 Skills给全项目统一适配之后这种情况才真正好转。这篇文章就把我完整的落地过程写出来Skill 到底是什么、和 Agent 是什么关系、为什么能解决会写代码但不懂规矩的问题、以及我在前端规范、测试用例、代码审查几个高频场景里是怎么写 Skill 的。适合正在带团队用 Claude Code、Codex 这类 Agent 工具的人也适合刚听说 Skills 但不知道从哪下手的同学。我会尽量把步骤说细把踩过的坑也一并交代清楚。1. 整体思路Agent 负责执行Skill 负责立规矩1.1 先讲清楚 Skill 和 Agent 的分工很多人把 Agent 和 Skill 混在一起一上来就问Skill 是不是另一个 Agent其实完全不是一回事。Agent 是一个能够自行规划、调用工具、执行代码的智能体它负责做什么Skill 更像是一份给 Agent 看的操作手册负责怎么做。我常用的类比是Agent 是一个新来的开发Skill 就是公司给他准备的工作手册。工作手册里不会告诉他你是一个程序员那是模型本身的能力但会告诉他提交代码必须按 Conventional Commits 格式写组件必须用 Vue3 的 setup 语法测试覆盖率不能低于 80%。没有这份手册新人只能靠猜有了手册新人立刻懂规矩。在技术实现上Skill 通常是一个目录里面放一份 Markdown 文档有些还会带脚本、模板、参考文件。当 Agent 接到的任务和某个 Skill 的描述匹配时它就会把这个文档加载进上下文然后按照文档里的步骤和规则去执行。这个机制看起来不起眼但它解决了 Agent 落地最痛的问题模型能力再强也默认不知道你们团队的特殊规范。1.2 为什么不能靠多写几句提示词解决有人会说规范我知道每次让 Agent 干活时把规范贴在提示词里不就行了我一开始也是这么干的后来发现这条路走不通。第一一次性提示词没法复用。你今天写了一段前端规范二十条贴进对话明天换了个任务又要重新贴一遍。如果项目里有五个 Agent 在工作每个人都要维护一遍同一份规范迟早会出现版本不一致的情况。第二提示词会被任务指令稀释。你让 Agent 写一个登录页面同时在提示词里塞了五十条规范Agent 的注意力可能全在登录页面怎么实现上规范反而被忽略。Skill 则不同它是按任务类型触发的一旦触发就会被当作必读文件优先级远高于对话里顺带一提的要求。第三规范本身是会变的。如果规范写死在提示词里每次变更你都要通知所有人做成 Skill 之后你只需要改一个文件所有 Agent 下一次执行时都会读到新版本。这其实就是把代码里的函数和到处拷贝的魔法值做了一次重构。1.3 全项目 Skill 适配的完整闭环明白了 Skill 的价值之后我给自己定了一套流程这里先展示整体框架后面几节再展开细节盘点项目里的隐性规范代码风格、目录结构、提交信息、测试要求、命名规则、架构约束。把规范拆成一个个 Skill 文件每个 Skill 聚焦一个任务类型不贪多。把 Skill 放进项目目录让 Agent 在执行任务时能自动发现并加载。在真实任务里观察 Agent 的表现凡是它反复犯的错、反复问的问题都回去补进对应 Skill。定期评审 Skill 文件本身确保它和最新规范保持一致。说到这里你会发现Skill 适配不是一个一次性工程它更像是在给 Agent做入职培训并且这个培训材料会随着项目演化持续更新。2. 落地设计Skill 应该放在哪、长什么样、怎么迭代2.1 目录结构设计先把技能仓库建好我第一次接触 Skills 时最困惑的问题就是这玩意儿到底该放哪后来我对比了 Claude Code、Codex 等几套工具之后总结出一套比较通用的做法在项目根目录下建一个专门放 Skills 的文件夹不同工具读取的目录名不太一样Claude Code 读取.claude/skills/Codex 读取codex/skills/之类但核心逻辑是一致的——每个 Skill 自成一个子目录子目录的名字就是 Skill 的名字里面再放SKILL.md主文件以及可选的参考文件、示例代码、脚本等。我自己的标准结构是这样的your-project/ ├── .claude/ │ └── skills/ │ ├── frontend-component/ │ │ ├── SKILL.md │ │ └── examples/component.vue │ ├── test-case-writer/ │ │ ├── SKILL.md │ │ └── templates/test.spec.ts │ └── git-commit-message/ │ └── SKILL.md └── codex/ └── skills/ └── ...同理每个 Skill 目录内部我强烈建议用SKILL.md做统一入口不要一会儿叫README.md一会儿叫index.md。因为 Agent 在发现 Skill 时通常会先找固定的入口文件文件名不统一会导致加载失败。目录名和文件名都尽量用中划线或下划线连接避免空格这也是我从失败案例里总结出来的教训。2.2 一份优质 Skill 文件的内容拆解SKILL.md的内容结构比想象中要讲究。我见过太多写得不好的 Skill要么是一大段废话要么是几个要点就草草结束。实际效果最好的 Skill通常会包含几部分内容头部元信息、职责边界、执行步骤、禁忌事项、检查清单、示例。头部元信息是给 Agent 判断什么时候用这个 Skill的关键。它通常是一个 YAML 格式的 frontmatter包含name和description两个字段。description尤其重要因为 Agent 是通过语义匹配来决定是否加载 Skill 的如果你的描述写得过于宽泛比如处理前端任务那几乎什么任务都会匹配上Skill 反而失去了针对性。职责边界这一段很多人会漏掉但它非常关键。你应该明确告诉 Agent什么时候必须用这个 Skill什么时候绝对不要用。比如前端组件 Skill 里可以写本 Skill 仅在新建或修改 Vue 组件时使用不适用于页面路由配置这样能防止 Agent 在无关任务上浪费上下文。执行步骤是 Skill 的核心。这里不要求你写得像代码一样精确但一定要有先后顺序。不是做好组件这种笼统描述而是先判断组件属于通用组件还是私有组件再决定目录位置创建文件后先写 props 类型定义再写业务逻辑。把经验变成流程Agent 才能真正稳定产出。2.3 从单点 Skill 扩展到全项目一开始不用急着把所有规范都做成 Skill那样工作量太大而且大概率做出来的东西又臭又长。我建议走最小可用路线先挑三个最高频的痛点场景比如代码风格、提交信息、测试生成各写一份精简版 Skill跑通流程后再慢慢补充。我自己的节奏是第一周只做前端组件开发和Git 提交信息两个 Skill一边用一边改第二周再加测试用例生成和代码审查检查单一个月后根据 Agent 在真实任务里的失误记录补上了数据请求规范和错误处理规范两个 Skill。这种做法让我不用一次性搞定所有事同时每份 Skill 都经过真实任务检验质量和实用性要高得多。另外一定要把 Skill 纳入版本管理并且在团队里指定一个人或者轮流当规范维护者。因为 Agent 的 Skill 本质上也是代码资产如果每个人都可以随意改动最后规范会变得不稳定。我们的做法是 Skill 变更必须走 MR 评审和普通代码一样处理。3. 实操从零写一份能用的 Skill并用在真实场景里3.1 实战一前端开发 Skills把组件规范固化下来先拿最常用的前端组件开发举例。我们的前端项目是 Vue3 TypeScript团队里最大的痛点是不同人包括 Agent写出来的组件风格差异巨大。我写了一个frontend-componentSkill核心内容如下节选--- name: frontend-component description: 在 Vue3 TypeScript 项目中创建或修改组件时使用包含命名、目录、语法和样式规范 --- # 职责范围 仅用于新建或修改 Vue 组件。页面路由配置、状态管理逻辑请交给其他 Skill 处理。 # 执行步骤 1. 判断组件性质通用组件放入 src/components/ 下页面私有组件放入对应页面目录下的 components/ 子目录。 2. 组件命名用 PascalCase目录命名与组件名一致。 3. 使用 script setup langts 写法禁止使用 Options API。 4. 所有 props 必须定义类型和默认值禁止使用 any。 5. 涉及的接口数据请求统一调用 src/api/ 下封装好的方法不允许在组件内直接写 fetch。 6. 样式必须使用 scoped避免全局污染颜色、间距优先使用设计令牌变量。 # 完成检查清单 - [ ] 组件目录和文件名是否符合命名规范 - [ ] 是否遗漏 props 类型定义 - [ ] 有没有在组件内直接发请求 - [ ] 样式是否加了 scoped写完之后我让 Agent 新建了一个用户信息卡片组件它的产出明显比之前规矩目录放在了正确位置props 带上了 interface 定义请求走的是 api 封装样式也用了设计变量。最关键的是我没有在提示词里再重复这些规范Agent 因为加载了 Skill全程自己就守住了规矩。3.2 实测可控性把测试用例生成做成固定流程第二个高频场景是测试用例生成。以前 Agent 写完业务代码我让它顺便补个测试它经常用统一的模板套出来一堆假测试断言又弱又空覆盖率根本没意义。于是我做了一个test-case-writerSkill关键点在于先读取被测文件再列出测试计划最后才写代码--- name: test-case-writer description: 为 TypeScript 模块或 Vue 组件生成单元测试必须遵循团队测试规范 --- # 执行步骤 1. 先阅读被测源文件识别所有输入参数、边界条件和分支逻辑。 2. 在生成测试文件前先输出简短的测试计划包括用例名称、期望行为、覆盖分支。 3. 测试文件使用 Vitest路径与被测文件保持 src/__tests__/ 镜像结构。 4. 每个用例必须包含明确的 expect 断言禁止为了覆盖率而写空转用例。 5. 接口请求类逻辑使用 mock 数据不允许在测试中发起真实请求。 6. 边界情况至少覆盖空值、超长输入、异常分支。 # 检查清单 - [ ] 测试计划是否先行输出 - [ ] 是否覆盖了边界条件和异常分支 - [ ] 是否使用了真实的外部请求这个 Skill 的效果非常明显。Agent 不再直接甩出一个空白模板而是先列出测试计划给我确认再生成代码。虽然流程多了一步但测试质量提升了一个档次review 时间反而缩短了。3.3 把工程规范变成完整闭环还有哪些值得固化的 Skill除了前面两个我在项目里还会长期维护这几个 SkillGit 提交信息规范、代码审查检查单、数据请求层规范、错误处理规范。以 Git 提交信息为例它的 Skill 内容可以简单到只有十来行核心就几条规则格式必须是type(scope): subjecttype 限定为 feat/fix/refactor/docs/test/choresubject 保持动词开头且不超过 50 个字符有破坏性变更时必须在 footer 里写BREAKING CHANGE。数据请求层规范和错误处理规范也很有意思。前者规定所有 HTTP 请求必须走统一封装错误码要在业务层先做映射后者规定捕获异常后必须记录上下文信息不允许直接吞掉错误。这两个 Skill 让 Agent 写出来的代码在架构层面更加一致而不是散落着各种独立的实现。做这些 Skill 的时候我的体会是宁可每份短小而聚焦也不要整一个超大 Skill 把所有规则都塞进去。Agent 的上下文窗口是有限的一个任务如果同时触发十份 Skill光规范就把上下文占满了反而没空间思考具体实现。3.4 涉及多工具时的 Skill 加载差异如果你团队里同时用 Claude Code、Codex甚至其他 Agent 框架要注意不同工具对 Skill 的目录约定和触发机制不完全一样。但核心原则是一致的让 Skill 描述尽量具体、职责尽量单一。这样无论哪套工具来做语义匹配都能更准确地在正确场景触发。另一个差异在于有些工具支持在任务进行中通过搜索技能库动态加载 Skill有些则只在任务开始时做一次初始扫描。如果你的项目很大、Skill 数量很多建议把高频使用的 Skill 放到团队级或项目级目录的显眼位置低频的放到按需搜索的目录里。具体到某个工具的加载细节建议直接翻对应官方文档因为更新很快我在这里就不展开写了避免误导。4. 常见问题与排查技巧实录4.1 Agent 执行报错execution terminated due to error这条报错我用 Agent 开发时遇见的频率不低尤其是引入 Skill 之后的一段时间。多数情况下execution terminated due to error 并不是某一类特定错误它更像是 Agent 执行过程中抛出的异常被框架统一拦截后的通用提示。真正的问题可能在好几个地方。我的排查顺序是先打开该任务的执行日志看是哪一步报错——是 Skill 文件本身格式有问题比如 YAML 语法错误导致解析失败还是 Skill 里给了 Agent 某个命令但命令在当前环境里不存在或者是 Agent 在执行过程中产生了大量输出把上下文窗口挤爆了导致后续步骤失败。如果是格式问题就用本地工具检查一下 YAML 和 Markdown 文档的语法。如果是命令环境问题把 Skill 里写死的命令改成让 Agent先检测命令是否存在再执行的写法。如果纯粹是上下文太长那就把 Skill 文件精简拆掉冗余内容。总之这个报错是一个症状不是病因一定要顺着日志去找到每一步的真实执行情况。4.2 Skill 加载不了或者不生效我遇到过的 Skill 不生效原因主要有三类。第一类是描述写得和实际任务对不上任务关键词根本没出现在 description 里Agent 自然匹配不到。解决办法就是回看几个历史任务看它们是怎么描述的然后把常见的同义词写进 description。第二类是目录结构不对文件名不是工具约定的入口名或者 Skill 目录嵌套层级太深。这里建议遵循最小的目录深度比如.claude/skills/name/SKILL.md不要额外套一层。第三类是多个 Skill 之间的描述互相覆盖。比如我一开始有frontend和vue-component两个 Skill 描述都涉及前端组件导致 Agent 随机加载其中一个。后来我把职责边界写得更清晰一个负责全项目前端代码规范另一个只负责新建或修改组件两个 Skill 就不会抢任务了。4.3 Skill 和 MCP 工具怎么配合很多刚接触 Skills 的人会把 Skill 和 MCP 搞混或者认为有了 MCP 就不需要 Skill。实际上二者解决的问题不同MCP 是给 Agent 提供实时数据获取能力比如连数据库、调搜索、访问内部系统Skill 是给 Agent 提供做事的方法和规范。我常用的配合方式是在 Skill 里写清楚当需要查询用户数据时调用 MCP 工具 user-db 的 query 方法拿到数据后按本 Skill 的格式输出。这样 Agent 既有了数据来源又有了输出标准两者各司其职。如果发现 Agent 明明有 MCP 工具却不去调问题往往出在 Skill 里没有明确写明调用路径。Agent 默认会比较保守你不告诉它可以调哪个工具它就倾向自己写个假数据硬撑。所以 Skill 里涉及外部能力的地方一定要指名道姓用哪个工具、传什么参数、期望什么返回。4.4 安全和权限控制Skill 也不是万能的Skills 本质上是一段会注入到 Agent 上下文里的内容它可能包含指令也可能包含让 Agent 执行命令的引导。如果我们允许 Agent读取项目内任意 Skill 并执行其中的操作那就必须考虑一个问题项目里的 Skill 文件本身会不会被恶意修改我的建议是不要把密钥、密码、内部敏感信息写进任何 Skill 文件因为 Skill 可能被 Agent 带出上下文进入对话历史也不要让 Skill 里的指令自动获得过高权限比如无条件执行所有 bash 命令。更好做法是在 Skill 里声明它需要的工具权限然后在 Agent 配置层面对这些权限做限制。比如某个 Skill 只需要读写前端目录就不要赋予它删除整个项目的权限。另外定期 review Skill 内容也很重要。Agent 项目有时会自动生成或更新 Skill这些改动如果没有经过审核可能引入不符合团队意图的规则。我们团队现在规定所有 Skill 变更必须过 MR禁止直接往主分支里提交 Skill 修改。5. 最后的实操心得如果你问我做全项目 Skills 适配最值得投入的部分是什么我的答案不是写规范文件本身而是建立从 Agent 错误中持续迭代 Skill的机制。每次 Agent 在真实任务里犯了规范类错误都是一次绝佳的补充素材。我一般会记录下错误类型然后每周集中把这些错误改成 Skill 规则。几周下来Agent 的规范类错误率会肉眼可见地下降。另外一个很容易被忽略的小技巧是在每个 Skill 末尾放一个验收清单。不要小看这几行 Markdown 复选框它相当于给 Agent 增加了一个写完自查的强制步骤。很多误操作都是在自查阶段被拦下来的。最后建议你从最简单的场景开始比如先做一个 Git 提交信息规范 Skill跑通一次文件入库-触发-执行-生效的完整链路再逐步扩展。这个内容后续还可以往文档生成、项目管理、数据分析等领域延伸思路完全一致把你们团队的隐性经验变成 Agent 能读懂的显性规则。
返回列表