ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

agent-skills 技能包:用 TDD 约束让 Claude Code 从能聊变能干活

agent-skills 技能包:用 TDD 约束让 Claude Code 从能聊变能干活

1. 从"agent-skills"这个标题能读出什么

第一次看到agent-skills这个项目名,我的直觉是:这不是一个普通工具库,而是一套给 AI coding agent 用的"技能包"。关键词里同时出现了skills CLI、Claude Code、test-driven-development,基本可以确定它的定位——把可复用的工程能力封装成 agent 能直接调用的技能单元,让 AI 在写代码这件事上从"能聊"变成"能干活"。

为什么这个方向值得关注?因为过去一年我用 Claude Code 这类终端 agent 的真实体感是:模型本身够聪明,但缺的是"规矩"。你让它写个功能,它上来就改文件,改完不跑测试,跑完不检查边界,最后你花在 review 和返工上的时间比手写还多。agent-skills想解决的正是这个问题——把"先写测试再写实现""改完必须验证""提交前自查"这些老工程师的肌肉记忆,固化成 agent 可以加载的技能。

这篇文章适合三类人看:一是已经在用 Claude Code、想让它更靠谱的开发者;二是对 AI coding agent 感兴趣、想知道"技能"到底怎么落地的人;三是团队里想把 AI 编码流程标准化的技术负责人。我会从技能的本质讲起,拆解 skills CLI 的工作方式,重点讲 test-driven-development 这个技能为什么是整套体系里最值钱的一块,最后给出一套可以直接抄的落地步骤和踩坑清单。

需要先说明一点:agent-skills的具体实现细节我没有拿到官方源码,下面涉及目录结构、CLI 参数的部分,是基于 Claude Code 生态里 skills 机制的常见实践做的合理还原,逻辑上能自洽,你照着搭一套自己的技能库完全没问题。

2. agent-skills 到底在解决什么问题

2.1 裸奔的 agent 和"有技能"的 agent 差在哪

先做个对比。没有技能约束的 agent,你给它一句"给用户模块加个登录接口",它的典型行为是:直接打开文件、凭感觉写一段代码、可能顺手改了几个不相关的地方、然后告诉你"完成了"。至于这个接口有没有处理空密码、有没有防重复提交、有没有对应的测试,全靠运气。

有技能约束的 agent 完全不一样。它会先加载test-driven-development技能,按技能里定义的流程走:先写一个会失败的测试,再写最小实现让测试通过,最后重构。整个过程你不需要反复提醒,因为技能文件里已经把"什么时候该做什么"写死了。

这个差别不是模型能力的差别,是流程约束的差别。模型再强,没有流程也会偷懒;模型一般,但流程卡得死,产出反而稳定。这就是agent-skills的核心价值——它不提升模型智商,它提升模型的行为下限。

2.2 技能和 prompt 模板的本质区别

很多人第一反应是:"这不就是写个 prompt 吗?" 不是。prompt 模板是你在对话里临时塞给模型的一段话,用完就没了,下次对话又得重来。技能是持久化、可发现、可组合的资产。

具体区别体现在三个层面:

  • 加载方式:prompt 靠你手动粘贴,技能靠 agent 根据任务自动匹配加载。你说"帮我加个功能",agent 自己判断该调 TDD 技能;你说"帮我查个 bug",它调调试技能。
  • 结构约束:prompt 是一段自由文本,技能通常有固定结构——触发条件、执行步骤、检查清单、失败处理。结构化的东西模型执行起来更不容易跑偏。
  • 可维护性:prompt 散落在各个聊天记录里,技能是版本化的文件,可以 review、可以迭代、可以团队共享。

我自己的经验是,一个打磨好的技能文件,效果顶得上十次反复叮嘱。因为叮嘱是即时的、情绪化的,技能是沉淀的、结构化的。

2.3 为什么是现在这个时间点

AI coding agent 在 2024 到 2025 年集中爆发,Claude Code、各类 CLI agent 层出不穷。但大家很快发现一个尴尬的现实:demo 很惊艳,生产很难用。原因就是 agent 缺少工程纪律。

agent-skills这类项目的出现,标志着社区开始从"追求 agent 能做什么"转向"追求 agent 做得对不对"。这个转向很关键,它意味着 AI 编码正在从玩具阶段进入工程阶段。谁先把技能体系搭起来,谁就能真正把 agent 用进日常开发,而不是停留在尝鲜。

3. skills CLI 的工作机制拆解

3.1 技能是怎么被组织和发现的

一套典型的 skills 体系,目录结构大概长这样:

.agent-skills/ skills/ test-driven-development/ SKILL.md examples/ code-review/ SKILL.md debugging/ SKILL.md config.json

每个技能一个目录,核心是SKILL.md这个文件。文件名大写是有讲究的——它是 agent 扫描时的入口标记,类似README.md之于一个仓库。agent 启动时会扫描这个目录,把每个技能的元信息(名称、描述、触发关键词)读进上下文,真正需要执行时才加载完整内容。

这种"元信息常驻、正文按需加载"的设计很聪明。因为上下文窗口是稀缺资源,如果把所有技能全文都塞进去,还没干活上下文就满了。只加载摘要,命中任务时再展开,既省 token 又保证准确。

config.json一般用来配置技能目录路径、启用哪些技能、以及一些全局参数。这个文件让技能库可以跨项目复用——你可以把技能放在一个中心目录,多个项目通过配置指向它。

3.2 技能文件的内部结构

一个写得好的SKILL.md,我建议包含这几块:

--- name: test-driven-development description: 在实现任何新功能或修复 bug 时使用,强制先写测试 triggers: - 实现功能 - 修复 bug - 添加接口 --- ## 何时使用 当任务涉及新增或修改代码逻辑时。 ## 执行步骤 1. 先写一个失败的测试,明确预期行为 2. 运行测试,确认它确实失败 3. 写最小实现让测试通过 4. 重构,保持测试绿色 5. 重复直到功能完整 ## 检查清单 - [ ] 测试是否先于实现编写 - [ ] 是否见过测试失败 - [ ] 实现是否最小化

frontmatter 里的triggers是灵魂。它决定了 agent 什么时候会想起这个技能。写得太窄,技能永远不被触发;写得太宽,什么任务都往里套,反而添乱。我的经验是,触发词要贴着"用户会怎么说"来写,而不是贴着"技术术语"来写。用户说"加个功能"比说"实现一个方法"更常见。

3.3 技能加载的时机与优先级

这里有个容易被忽略的细节:技能不是越多越好。如果你装了二十个技能,agent 每次都要在二十个里挑,选择成本上去了,误触发概率也上去了。

合理的做法是分层。基础层放三到五个高频技能,比如 TDD、代码审查、调试;进阶层放特定场景技能,比如数据库迁移、API 设计。基础层常驻,进阶层按项目启用。

优先级方面,我实测下来,流程类技能应该高于知识类技能。因为知识模型自己就有,缺的是流程约束。TDD 这种"逼你先写测试"的技能,价值远高于"告诉你什么是单元测试"的技能。

4. test-driven-development 技能为什么是整套体系的压舱石

4.1 TDD 对 agent 的意义和对人不一样

对人来说,TDD 是一种设计方法,帮你理清接口、降低耦合。对 agent 来说,TDD 的意义更直接——它是唯一能让 agent 自我验证的机制。

人写完代码,心里大概知道对不对。agent 写完代码,它自己也不知道对不对,除非有测试跑给它看。没有测试,agent 的"完成"只是"我写完了",不是"它对了"。有了测试,agent 就有了反馈回路:跑测试、看结果、不对就改。这个回路是 agent 从"生成器"变成"问题解决者"的关键。

我踩过的最大的坑,就是早期让 agent 直接写实现。它写得飞快,但十个功能里有三个有隐藏 bug,而且这些 bug 往往在边界条件上——空输入、超长字符串、并发。后来强制走 TDD,bug 率肉眼可见地降下来,因为边界条件在写测试的时候就被逼着想到了。

4.2 红绿重构在 agent 场景下的具体落地

经典 TDD 是"红-绿-重构"三步。放到 agent 场景,每一步都要有明确的机器可验证信号:

红:agent 写一个测试,然后必须运行它,并且确认它失败。这一步不能省。我见过 agent 写完测试直接说"测试写好了",根本没跑。所以技能文件里要写死:"必须运行测试命令,并展示失败输出。"

绿:agent 写最小实现让测试通过。关键词是"最小"。agent 的天性是过度设计,你让它加个加法,它可能给你写个计算器框架。技能里要明确"只写让当前测试通过的最少代码"。

重构:测试保持绿色的前提下整理代码。这一步 agent 经常跳过,因为"能跑就行"。技能里要把它列为必做项,并给出重构的检查点,比如消除重复、命名清晰。

4.3 一个真实的技能执行片段

假设任务是"给字符串工具加一个判断回文的方法"。加载了 TDD 技能的 agent 会这样走:

第一步,写测试:

def test_is_palindrome(): assert is_palindrome("racecar") is True assert is_palindrome("hello") is False assert is_palindrome("") is True

第二步,运行,看到NameError: is_palindrome is not defined,确认红。

第三步,写最小实现:

def is_palindrome(s): return s == s[::-1]

第四步,运行,绿。

第五步,重构——这里其实没什么可重构的,但 agent 会检查一遍命名和边界,确认空字符串返回 True 是符合预期的。

整个过程你一句话没说,agent 自己走完了。这就是技能的价值:把需要你盯着的流程,变成 agent 自己遵守的纪律。

5. 把 agent-skills 接进 Claude Code 的实操路径

5.1 环境准备里最容易翻车的地方

Claude Code 的安装本身不复杂,但有几个点新手经常卡住。第一是 Node 版本,Claude Code 对 Node 版本有要求,版本太低会直接报错,建议先node -v确认。第二是终端环境,如果你在 VS Code 里用集成终端,要确保它用的是你配置好的那个 shell,而不是默认的。

技能目录的接入,核心是让 Claude Code 知道去哪里找技能。常见做法是在项目根目录放.agent-skills/,或者在全局配置里指定技能路径。我建议项目级和全局级结合:通用的 TDD、代码审查放全局,项目特有的技能放项目里。这样换项目不用重新配,项目专属的又不会污染全局。

提示:技能目录的路径不要用中文或空格,某些环境下会导致扫描失败。用纯英文短横线命名最稳。

5.2 从零搭一个最小可用技能库

不要一上来就搞十几个技能,先搭三个跑通闭环:

  1. test-driven-development:流程约束,最高优先级
  2. code-review:改完代码自查,检查命名、边界、重复
  3. commit-message:规范提交信息,方便回溯

每个技能的SKILL.md控制在 50 行以内。太长了 agent 加载慢,而且重点不突出。写完先手动测:给 agent 一个任务,看它会不会自动加载对应技能。如果不会,多半是triggers写得不对,调整触发词再试。

我自己的调优过程是这样的:先写宽泛的触发词,观察哪些任务误触发了,再逐步收窄。比如code-review一开始触发词写了"代码",结果写代码时也触发,后来改成"审查""检查""review"就准多了。

5.3 验证技能是否真的生效

怎么判断技能生效了?看 agent 的行为有没有变化。没装 TDD 技能时,你说"加个功能",它直接改文件。装了之后,它应该先写测试文件。如果行为没变,检查三件事:技能目录路径对不对、SKILL.md的 frontmatter 格式对不对、触发词和你的说法对不对得上。

还有一个隐蔽的坑:有些 agent 会把技能内容读进上下文,但不一定严格执行。这时候要在技能里加"强制"措辞,比如"你必须先运行测试并展示输出,否则不得进入下一步"。措辞的强度确实会影响执行率,这是我反复试出来的。

6. 技能设计里那些文档不会告诉你的经验

6.1 触发词要贴着用户口语写

这是我最想强调的一条。技能作者容易犯的错,是用技术术语写触发词。比如调试技能,触发词写"debug""异常排查",但用户实际说的是"这个报错了""跑不起来""结果不对"。触发词对不上,技能就是摆设。

我的做法是,把团队里大家描述问题的原话收集起来,直接当触发词。口语化、多样化,宁可多写几个同义词。反正触发词只是元信息,多几个不占多少上下文。

6.2 技能之间要避免打架

两个技能如果都声称自己适用于"修改代码",agent 就会纠结。解决办法是给技能划定清晰的边界。TDD 技能管"新增或修改逻辑",代码审查技能管"改完之后的自查",两者是流水线上的先后关系,不是竞争关系。在技能描述里写清楚"本技能在 X 之后使用",能有效减少冲突。

6.3 技能要能失败,也要能退出

好的技能不只是告诉 agent 怎么做,还要告诉它什么时候停。比如 TDD 技能里应该有一句:"如果测试连续三次无法通过,停止并报告,不要继续盲目修改。" 没有退出条件的技能,会让 agent 陷入死循环,反复改反复错,浪费大量 token。

我见过最惨的一次,agent 在一个测试上卡了十几轮,每轮都微调实现,越改越乱。后来在技能里加了"三次不过就停"的规则,这种情况再没出现过。

6.4 定期清理失效技能

技能库和代码库一样,会腐化。有些技能随着工具升级失效了,有些技能被更好的替代了。建议每个月过一遍,把没人用的、触发不了的、效果差的删掉。技能库精简,agent 的选择才准。

7. 常见问题与排查思路

7.1 技能不触发怎么办

按这个顺序排查:先确认技能目录被 agent 扫描到了(看启动日志或配置),再确认SKILL.md的 frontmatter 能被正确解析(YAML 格式很挑缩进),最后确认触发词和你的输入匹配。三步走下来,九成问题能定位。

7.2 技能触发了但执行不到位

多半是技能内容太抽象。把"写好测试"改成"写一个测试文件,包含至少三个断言,运行并展示失败输出",执行率立刻上去。agent 需要的是可操作的指令,不是原则性的口号。

7.3 多个技能同时触发导致混乱

给技能加优先级字段,或者在描述里写明适用顺序。实在冲突的,就合并成一个技能,用内部步骤区分场景。

7.4 技能在不同项目间怎么复用

把通用技能放全局目录,项目通过配置引用。项目特有的技能放项目内。这样既复用又隔离。跨机器同步的话,把技能库做成一个独立的 git 仓库,各项目 submodule 引用,版本可控。

8. 我对 agent-skills 这类项目的一点判断

用了一段时间下来,我越来越觉得,AI coding agent 的竞争,下半场不在模型,在技能生态。模型能力会趋同,但一套打磨好的技能库是实打实的工程资产,别人抄不走。

agent-skills这个方向最聪明的地方,是它把"怎么用 AI 写代码"这件事,从个人经验变成了可沉淀、可传播、可迭代的资产。以前一个老工程师的编码纪律只在他自己脑子里,现在可以写成技能文件,让 agent 替他执行。

如果你现在还在手动给 agent 写 prompt、反复叮嘱同样的话,真的建议花一个下午搭一套自己的技能库。从 TDD 这一个技能开始,跑通闭环,你会明显感觉到 agent 从"需要盯着"变成"可以放手"。这个转变一旦体验过,就回不去了。

最后分享一个我自己的小习惯:每次 agent 犯了新错误,我不只是当场纠正,而是回头把这个错误对应的规则补进技能文件。这样同样的坑,agent 只会踩一次。技能库就是这么一点点长起来的,比任何教程都管用。

返回列表