news 2026/10/28 6:34:50

agent-skills 实战:用 TDD 技能包让 Claude Code 更懂你的项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
agent-skills 实战:用 TDD 技能包让 Claude Code 更懂你的项目

1. 从“agent-skills”说起:为什么它值得单独拿出来聊

第一次看到agent-skills这个项目名,我脑子里蹦出来的不是某个具体工具,而是一类正在快速成型的东西——给 AI coding agent 用的技能包。你可以把它理解成一套“插件化的能力说明书”:把常见的开发动作,比如写测试、跑测试、重构、生成文档、做代码审查,拆成一个个独立、可复用、可组合的 skill,然后让 agent 按需加载。

这件事为什么重要?因为过去一年我用 Claude Code、Cursor、各种 CLI agent 写代码,最大的痛点从来不是“模型不够聪明”,而是它不知道我团队的规矩。你让它写个函数,它写得挺漂亮,但测试框架用的是 Jest 而你们用的是 Vitest;你让它改个 bug,它顺手把不相关的代码也重构了;你让它跑测试,它压根不知道你们项目里测试命令是pnpm test:unit而不是npm test。每次都要在 prompt 里重复交代,累。

agent-skills这类项目解决的就是这个“重复交代”的问题。它把领域知识、操作流程、约束条件固化下来,变成 agent 可以自动发现和调用的技能。热搜词里出现的test-driven-development、skills CLI、Claude Code这几个词,其实已经把这个项目的定位说得很清楚了:围绕 AI coding agent 构建一套以 TDD 为代表的技能体系,并提供 CLI 来管理这些技能。

这篇文章适合谁看?三类人。第一类是把 Claude Code 当日常主力工具、想让它更“懂自己项目”的开发者;第二类是团队里负责工程效能、想统一 AI 编码规范的人;第三类是对 agent 架构感兴趣、想自己写 skill 的技术人。不管你是刚装完 Claude Code 的新手,还是已经在用cc switch接第三方模型的老手,这套思路都能直接用上。

我下面会从设计思路、核心机制、实操落地、踩坑排查四个层面,把agent-skills这类项目彻底拆开讲。内容里涉及 Claude Code 的部分,都是基于公开的常见实践补充的,具体命令以你本地版本为准。

2. 整体设计思路:为什么是“技能”而不是“提示词”

2.1 提示词工程的瓶颈在哪里

先说清楚一个背景。早期大家用 AI 写代码,靠的是把要求写进 prompt。项目根目录放一个CLAUDE.md或者.cursorrules,把规范塞进去。这招在项目小的时候管用,但很快会遇到三个问题。

第一个是上下文膨胀。你把所有规范都塞进系统提示,token 消耗大不说,模型注意力还会被稀释。一份 3000 字的规范文档,模型真正用上的可能就那几条,剩下的全是噪音。

第二个是无法按需加载。写测试的时候你不需要知道部署流程,改前端的时候你不需要知道数据库迁移规范。但提示词是一股脑全给的,没法根据当前任务动态切换。

第三个是不可组合、不可测试。提示词是一坨文本,你没法说“这个技能依赖那个技能”,也没法给技能写单元测试。团队协作时,谁改了哪条规范、为什么改,全靠 git diff 看文本,非常原始。

agent-skills的核心设计,就是把这坨文本结构化、模块化、可发现化。每个 skill 是一个独立单元,有自己的名字、描述、触发条件、执行步骤。Agent 在干活时,先看有哪些 skill 可用,再根据当前任务决定加载哪个。

2.2 技能包的三层结构

我研究下来,这类项目的 skill 通常包含三层信息,缺一不可。

第一层是元数据(metadata)。包括 skill 的名字、一句话描述、适用场景、依赖关系。这一层的作用是让 agent 能“扫一眼就知道这个技能是干嘛的”,不需要加载全部内容。这就像图书馆的书脊,你先看书名决定要不要抽出来。

第二层是执行指令(instructions)。这是 skill 的主体,告诉 agent 具体怎么做。比如 TDD 技能里会写:先写一个失败的测试,运行确认它失败,再写最小实现让它通过,最后重构。每一步都有明确的动作和判断标准。

第三层是资源与约束(resources & constraints)。包括这个技能会用到的模板文件、参考文档、禁止事项。比如“生成测试时禁止 mock 数据库”这种硬约束,就放在这一层。

为什么这么分?因为 agent 的上下文窗口是稀缺资源。元数据常驻,指令按需加载,资源用到才读。这套分层让一个项目可以挂几十个 skill 而不炸上下文。

2.3 为什么选 TDD 作为标杆技能

热搜词里test-driven-development排在很前面,这不是偶然。TDD 是检验一套 agent skill 体系好不好用的最佳试金石,原因有三个。

其一,TDD 流程步骤明确、有强顺序。红-绿-重构,每一步都有可验证的产出。如果 agent 能严格按这个流程走,说明 skill 的指令设计是有效的。

其二,TDD 对上下文依赖极强。它需要知道项目的测试框架、测试文件放哪、怎么跑单个测试、断言库用哪个。这些信息正好是 skill 要固化的东西。

其三,TDD 天然抗幻觉。测试跑没跑过、红还是绿,是客观事实,agent 没法糊弄。这让它成为验证 skill 执行质量的硬指标。

所以一个成熟的 agent-skills 项目,往往把 TDD 作为第一个打磨到位的技能,其他技能都参照它的结构来写。

2.4 和 Claude Code 的关系

Claude Code 本身是一个 agent 运行时,它负责理解你的自然语言、调用工具、读写文件、执行命令。但它默认不知道你的项目规范。agent-skills扮演的是能力供给层:它定义技能,Claude Code 负责执行技能。

热搜里那一堆claude code 安装、vscode 配置 claude code、ubuntu 配置 claude code,说明很多人卡在环境这一步。但环境搭好只是起点,真正决定效率的是你有没有一套好用的 skill。装好 Claude Code 只是买了台好车,agent-skills是给你配的导航和驾驶手册。

3. 核心机制拆解:skill 是怎么被 agent 发现和调用的

3.1 技能的发现机制

Agent 怎么知道有哪些 skill 可用?常见做法是在项目里放一个约定目录,比如.agent/skills/或者skills/,每个 skill 一个子目录或一个文件。启动时,agent 扫描这个目录,读取每个 skill 的元数据,形成一份“技能清单”注入上下文。

这份清单通常长这样:

可用技能: - tdd: 测试驱动开发流程,适用于新功能开发和 bug 修复 - code-review: 代码审查清单,适用于提交前自查 - doc-gen: 根据代码生成 API 文档 - refactor: 安全重构流程,强调小步提交

注意这里只列名字和描述,不列具体步骤。Agent 看到清单后,判断当前任务需要哪个技能,再去加载对应的完整指令。这就是前面说的“按需加载”。

我实测下来,这份清单控制在 10 到 20 个技能比较合适。太少了覆盖不全,太多了模型选择困难,反而容易选错。

3.2 技能的触发方式

触发分两种:显式触发和隐式触发。

显式触发就是你直接说“用 TDD 技能来写这个功能”。这种方式确定性强,适合你对流程有明确要求的时候。

隐式触发是 agent 根据任务自动匹配。比如你说“帮我加一个用户登录接口”,agent 看到这属于新功能开发,自动加载 tdd 技能。这种方式省事,但对 skill 的描述质量要求高——描述写得不清楚,agent 就匹配不上。

我的经验是两者结合:关键流程用显式触发保证不出错,日常小任务靠隐式触发提效率。在 skill 的元数据里,可以加一个triggers字段,列出触发关键词,帮助 agent 匹配。

3.3 技能之间的依赖与组合

真实开发任务很少只用一个技能。比如“修复一个 bug”可能涉及:先加载 tdd 写复现测试,再加载 debug 技能定位问题,最后加载 code-review 自查。这就涉及技能组合。

好的 skill 体系会定义依赖关系。比如 tdd 技能声明“依赖 test-runner 技能”,因为 TDD 需要跑测试。Agent 加载 tdd 时,会自动把 test-runner 也带上。

还有一种组合是流水线式的。比如定义一个feature-development技能,内部按顺序调用 tdd、code-review、doc-gen。这种高层技能适合标准化整个开发流程。

3.4 skills CLI 的角色

热搜词里的skills CLI值得单独说。手动管理一堆 skill 目录很麻烦,CLI 就是来解决这个的。常见功能包括:

  • skills list:列出当前项目所有可用技能
  • skills add <name>:从仓库安装一个技能
  • skills remove <name>:移除技能
  • skills validate:检查技能定义是否符合规范
  • skills test <name>:对技能做冒烟测试

为什么需要 CLI?因为技能会越来越多,靠手动复制文件迟早乱套。CLI 让技能像 npm 包一样可安装、可版本管理、可共享。团队里一个人写好 TDD 技能,其他人一条命令就能用上。

提示:CLI 的具体命令名各项目不一样,用之前先看项目的 README。别照着网上的命令硬敲,版本对不上会报错。

3.5 技能定义的格式选择

技能用什么格式写?主流有两种:Markdown + Frontmatter和YAML/JSON。

Markdown 方案的好处是可读性强,人能直接看懂,也方便写大段说明。Frontmatter 放元数据,正文放指令。这是目前最流行的做法,Claude Code 生态里很多技能都是这个格式。

YAML/JSON 方案的好处是结构化强,程序好解析,适合做复杂的依赖和条件逻辑。但人写起来累,大段说明塞进 YAML 很别扭。

我的建议是元数据用 YAML frontmatter,指令用 Markdown 正文,兼顾两者。下面是一个 TDD 技能的示例结构:

--- name: tdd description: 测试驱动开发流程,适用于新功能和 bug 修复 triggers: [新功能, 加接口, 修bug, 写测试] depends: [test-runner] --- ## 执行步骤 1. 先写一个失败的测试,明确预期行为 2. 运行测试,确认它失败(红) 3. 写最小实现让测试通过(绿) 4. 重构,保持测试通过 5. 重复直到功能完成 ## 约束 - 禁止先写实现再补测试 - 每次只处理一个测试用例 - 测试必须能独立运行

这个结构清晰、可读、可解析,是我目前最推荐的写法。

4. 实操落地:从零搭一套可用的 agent-skills

4.1 环境准备与目录规划

动手之前先把环境理清楚。你需要一个能跑 agent 的环境,Claude Code 是常见选择。安装方式各平台不同,Mac、Ubuntu、Windows 都有对应流程,VSCode 里也有插件形态。这块网上教程很多,我不展开,重点说装完之后的事。

目录规划是关键。我推荐这样的结构:

project-root/ ├── .agent/ │ ├── skills/ │ │ ├── tdd/ │ │ │ ├── SKILL.md │ │ │ └── templates/ │ │ ├── code-review/ │ │ │ └── SKILL.md │ │ └── test-runner/ │ │ └── SKILL.md │ └── config.yaml ├── src/ └── tests/

为什么把技能放在.agent/skills/而不是项目根目录?因为这样能和其他配置隔离,也方便 gitignore 掉个人技能。config.yaml放全局配置,比如默认加载哪些技能、技能搜索路径等。

每个技能一个目录,而不是一个文件,是为了给技能留出放模板、示例、参考文档的空间。TDD 技能可能需要一个测试文件模板,code-review 可能需要一个检查清单模板,这些放同目录下,加载时一起读。

4.2 写第一个技能:以 TDD 为例

我们完整走一遍写 TDD 技能的过程。假设项目用 Vitest 做测试,测试文件放在tests/下,命名规则是*.test.ts。

第一步,确定元数据。名字叫tdd,描述要写清楚适用场景,触发词列全,依赖声明上 test-runner。

第二步,写执行步骤。这里有个技巧:步骤要写成 agent 能执行的动作,而不是抽象原则。比如不要写“遵循 TDD 原则”,而要写“运行pnpm test <file>确认测试失败”。前者模型理解不了,后者它能直接执行。

第三步,写约束。约束是防止 agent 偷懒或跑偏的。比如“禁止跳过失败验证直接写实现”“禁止一次写多个测试用例”。这些约束要具体、可检查。

第四步,附上模板。给一个测试文件模板,agent 生成测试时照着填,能保证风格统一。

写完之后,用skills validate检查格式,再用skills test tdd跑个冒烟测试,看 agent 能不能正确加载并执行。

4.3 让技能真正跑起来:一次完整的 TDD 实操

光写技能不够,得验证它真能用。我拿一个真实场景走一遍:给一个 Express 项目加一个/health接口。

第一步,触发技能。我在 Claude Code 里说:“用 tdd 技能给项目加一个 /health 接口,返回{status: 'ok'}。”

第二步,agent 加载技能。它读取 tdd 的 SKILL.md,同时因为依赖关系加载了 test-runner,知道了测试命令是pnpm test。

第三步,写失败测试。Agent 在tests/health.test.ts里写:

import { describe, it, expect } from 'vitest'; import request from 'supertest'; import app from '../src/app'; describe('GET /health', () => { it('返回 status ok', async () => { const res = await request(app).get('/health'); expect(res.status).toBe(200); expect(res.body).toEqual({ status: 'ok' }); }); });

第四步,运行确认失败。Agent 执行pnpm test tests/health.test.ts,因为接口还没写,测试报 404,确认是红的。这一步很关键,很多 agent 会跳过,但 tdd 技能的约束强制它必须跑。

第五步,写最小实现。Agent 在src/app.ts里加:

app.get('/health', (req, res) => { res.json({ status: 'ok' }); });

第六步,再跑测试。这次绿了。Agent 报告测试通过。

第七步,重构。这个例子太简单没什么可重构的,agent 会判断跳过。

整个过程 agent 没有问我“测试框架是什么”“测试放哪”,因为这些信息都在技能里固化了。这就是 skill 的价值。

4.4 技能参数化:让一个技能适配多个项目

上面那个 TDD 技能是写死 Vitest 的。如果换个项目用 Jest 呢?总不能复制一份改改吧。这就需要参数化。

做法是在技能里用占位符,配置里填实际值。比如:

## 执行步骤 1. 运行 `{{testCommand}} {{testFile}}` 确认测试失败

然后在config.yaml里定义:

variables: testCommand: pnpm test testDir: tests testSuffix: .test.ts

Agent 加载技能时,把占位符替换成实际值。这样同一个技能能适配不同项目,只需要改配置。

参数化还有个好处是降低技能数量。不用为每个框架写一个技能,一个技能加不同配置就够了。维护成本大幅下降。

4.5 技能的版本管理与团队共享

技能写好了,怎么让团队都用上?靠 git。把.agent/skills/提交到仓库,所有人拉下来就能用。但这里有个坑:个人偏好和团队规范要分开。

我的做法是分两层:团队技能放.agent/skills/,提交到 git;个人技能放~/.agent/skills/,不进仓库。加载时团队技能优先,个人技能补充。这样既保证规范统一,又允许个人定制。

版本管理上,技能也要打 tag。比如tdd@1.2.0。当技能有破坏性变更时,升大版本,避免团队成员拉到不兼容的版本。

5. 常见问题与排查技巧实录

5.1 技能加载失败怎么办

最常见的报错是“技能未找到”或“技能格式错误”。排查顺序如下。

先看目录结构对不对。技能必须在约定的搜索路径下,目录名和技能名要一致。我见过有人把技能放在skills/tdd.md,但项目约定是skills/tdd/SKILL.md,结果加载不到。

再看 frontmatter 格式。YAML 对缩进敏感,一个空格错了就解析失败。用skills validate能快速定位。常见错误是冒号后面没空格、列表缩进不一致、特殊字符没转义。

最后看权限。如果技能目录没有读权限,agent 也加载不了。Linux 和 Mac 上尤其注意。

5.2 Agent 不按技能流程走

这是最让人头疼的问题。你写了详细的 TDD 步骤,agent 却直接写实现,跳过测试。原因通常有三个。

一是技能描述不够强。如果描述写得含糊,agent 可能觉得这个技能不适用。把触发词写全,描述写具体,能改善匹配。

二是约束不够硬。光写“建议先写测试”没用,要写“禁止在测试失败前写实现”。用禁止性语言,模型更当回事。

三是上下文里有冲突指令。如果项目根目录的CLAUDE.md里写了“优先快速实现”,和 TDD 技能冲突,agent 会犯迷糊。检查一下有没有互相矛盾的指令。

我的经验是,关键约束要重复出现。在技能开头说一遍,在步骤里再说一遍,在约束区再强调一遍。重要的事说三遍,对模型也适用。

5.3 技能太多导致选择困难

技能超过 20 个之后,agent 选错技能的概率明显上升。解决办法是分层。

把技能分成核心技能和扩展技能。核心技能常驻清单,比如 tdd、code-review、test-runner。扩展技能按需加载,比如部署、性能优化、安全审计。在配置里声明哪些是核心,哪些是扩展。

另一个办法是给技能打标签。比如#testing、#review、#deploy。Agent 根据任务类型先筛标签,再在标签内选技能,选择范围小很多。

5.4 技能执行到一半卡住

有时候 agent 加载了技能,执行到某一步就停了,不往下走。常见原因是某一步的产出无法验证。比如技能里写“确认测试失败”,但 agent 跑完测试看到一堆输出,不知道算不算失败。

解决办法是给每一步定义明确的成功标准。不要写“确认测试失败”,要写“测试命令返回非零退出码,且输出包含 'failed' 字样”。这样 agent 有明确的判断依据,不会卡住。

5.5 常见问题速查表

问题现象可能原因排查方法解决方向
技能未找到路径不对/目录名不符检查搜索路径和目录结构按约定调整目录
格式解析失败YAML 缩进错误运行 validate 命令修正 frontmatter
Agent 不按流程走描述弱/约束软/指令冲突检查技能定义和全局配置强化描述和约束
选错技能技能过多/描述重叠查看技能清单分层+打标签
执行卡住步骤无明确成功标准复现执行过程补充判断依据
参数没替换变量名拼写错/配置缺失检查占位符和配置对齐变量名

5.6 几个我踩过的坑

第一个坑是技能里写了绝对路径。我在技能里写了/Users/myname/project/tests,结果同事拉下来全报错。技能里永远用相对路径或变量,别写死绝对路径。

第二个坑是技能依赖没声明。tdd 技能需要跑测试,但我没声明依赖 test-runner,导致 agent 不知道测试命令,卡在第一步。依赖一定要显式声明。

第三个坑是技能更新后没通知团队。我改了一个技能的约束,但同事本地还是旧版本,行为不一致。后来我们约定技能变更必须发通知,并在 CI 里检查技能版本。

第四个坑是把技能当文档写。一开始我写了几千字的技能,结果 agent 加载慢、理解差。后来精简到几百字,只留可执行的动作和硬约束,效果好很多。技能不是给人读的文档,是给 agent 执行的指令,要精炼。

6. 技能体系的扩展方向与个人体会

6.1 从单技能到技能生态

一套技能体系跑通之后,自然会想扩展。我目前看到几个有价值的扩展方向。

跨项目共享。把通用技能抽出来,做成可安装的包。新项目一条命令装上一整套,不用从零写。这需要 skills CLI 支持从远程仓库安装。

技能市场。社区里有人写好用的技能,可以发布出来给别人用。比如“React 组件测试技能”“Go 错误处理技能”。这会让整个生态快速丰富起来。

技能组合模板。把常用技能组合固化成模板,比如“新功能开发模板”包含 tdd + code-review + doc-gen,“bug 修复模板”包含 tdd + debug + regression-test。一键加载整套流程。

技能效果度量。记录每个技能被调用的次数、成功率、平均耗时,用数据指导技能优化。哪个技能老出错,就重点改它。

6.2 和第三方模型配合的注意点

热搜里提到用cc switch接第三方模型,比如 DeepSeek、Qwen、GLM。这里有个现实问题:不同模型对技能指令的遵循度不一样。

我实测下来,指令遵循强的模型,技能写简洁点就行;遵循弱的模型,约束要写得更硬、更重复。同一个技能,换个模型可能要调整措辞。

另外,第三方模型的上下文窗口大小不同。技能清单如果太长,小窗口模型会截断。这时候分层加载就更重要了,核心技能常驻,扩展技能按需。

还有一点,不同模型对 Markdown 格式的解析能力有差异。有的模型对 frontmatter 支持好,有的需要纯文本。写技能时尽量用通用格式,别依赖某个模型的特殊语法。

6.3 我个人在实际操作中的体会

用了大半年 agent-skills 这套东西,最大的体会是:技能的质量比数量重要得多。

一开始我贪多,写了三十多个技能,结果 agent 经常选错,维护也累。后来砍到十几个,每个都打磨到位,效率反而上去了。现在我的原则是:一个技能如果一个月没被调用过,就考虑删掉或合并。

第二个体会是技能要跟着项目演进。项目换了测试框架,技能里的命令要同步改;团队加了新规范,技能要补上。技能不是写完就完事,是要持续维护的活文档。

第三个体会是别指望技能解决所有问题。技能擅长固化流程和规范,但不擅长处理模糊需求。遇到没见过的任务,还是得靠人和 agent 对话探索。技能是提效工具,不是万能药。

最后分享一个小技巧:给技能写测试。就像给代码写测试一样,给技能写几个典型场景的测试用例,每次改完技能跑一遍,确保 agent 还能正确执行。这能避免改一个技能把另一个搞坏。我现在的做法是每个技能配一个test.md,列出三五个输入和预期行为,改完技能手动过一遍。虽然土,但管用。

这套东西还在快速演进,今天的最佳实践明天可能就过时了。但核心思路不会变:把重复的、有规范的、可验证的开发动作固化下来,让 agent 按需调用。抓住这个,具体用什么格式、什么 CLI、什么模型,都是可以替换的细节。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 6:33:07

Win10 64位GCC编译链V14.12.0安装与工程级配置指南

简介&#xff1a;本资源是专为Windows 10 64位系统定制的MinGW V14.12.0完整安装包&#xff0c;面向C/C初学者、嵌入式开发入门者及需在Windows下搭建轻量级GNU编译环境的开发者&#xff0c;解决原生Windows缺乏类Unix编译工具链的问题。压缩包为7z格式&#xff0c;共2000个文件…

作者头像 李华
网站建设 2026/10/28 6:32:16

现代网络对抗与关键基础设施防护技术解析

1. 网络空间对抗的现代演变最近几年&#xff0c;国际局势中的网络对抗呈现出全新态势。传统军事行动往往伴随着网络空间的隐蔽较量&#xff0c;这种新型对抗模式已经超越了早期简单的黑客攻击&#xff0c;演变为具有战略意义的数字领域博弈。从技术角度看&#xff0c;现代网络战…

作者头像 李华
网站建设 2026/10/28 6:32:01

系统集成项目风险管理实战:20个关键错误与应对策略

1. 风险管理在系统集成项目中的核心地位系统集成项目的复杂程度往往超出预期&#xff0c;一个中型系统集成项目通常涉及5-10个子系统对接、3-5家供应商协调、20技术接口规范。在这种多线程并行的环境下&#xff0c;风险管理就像项目的"免疫系统"——平时看不见摸不着…

作者头像 李华
网站建设 2026/10/28 6:32:00

信息系统仿真与数据传输仿真的核心技术解析

1. 信息系统仿真概述&#xff1a;当虚拟照进现实在深圳某通信设备制造商的实验室里&#xff0c;工程师们正在调试一套5G基站系统。令人意外的是&#xff0c;现场既没有真实的基站设备&#xff0c;也没有测试手机——所有设备都以软件形式运行在几台服务器上。这正是信息系统仿真…

作者头像 李华
网站建设 2026/10/28 6:31:46

t3code:轻量级代码片段管理与生成工具的设计与实践

前阵子在整理一个老项目&#xff0c;翻出了过去两年攒下的几十个代码片段——有的躺在微信收藏里&#xff0c;有的塞在IDE的snippet文件里&#xff0c;还有几个是临时写在笔记软件里的。当时心里就有点发毛&#xff1a;这些明明都是反复要用到的东西&#xff0c;可真到用的时候…

作者头像 李华
网站建设 2026/10/28 6:31:26

ponytail:基于AST的上下文感知代码模板工具

1. 这不是发型&#xff0c;是程序员圈里悄悄流传的“ ponytail 技能”——一个被误读却真实存在的开发辅助工具 最近在几个前端技术群和 GitHub 话题讨论区里&#xff0c;“ponytail”这个词频繁跳出来&#xff0c;有人问“ponytail 插件怎么装”&#xff0c;有人发截图说“po…

作者头像 李华