☰
agent-skills 实战:用 skills CLI 为 Claude Code 构建 TDD 技能库
2026/10/8 5:10:58 网站建设 项目流程

1. 从 agent-skills 说起:为什么我们需要给 AI 编程助手装上"技能包"

第一次看到agent-skills这个项目名的时候,我脑子里蹦出来的第一个念头是:这不就是给 AI coding agents 做的一套"外挂技能库"吗?后来翻了一圈资料、自己动手跑了几轮,发现这个理解方向是对的,但远不止这么简单。它本质上是一套围绕skills CLI构建的、面向 AI 编程代理的能力扩展体系,核心目标是让 Claude Code 这类工具从"能写代码"进化到"知道该怎么写、按什么流程写、写完怎么验证"。

说白了,现在用 Claude Code 的人越来越多,从安装 Claude Code、在 VSCode 里配置 Claude Code,到 Ubuntu 上折腾 Claude Code 环境,入门门槛其实已经降得很低了。但真正用起来你会发现一个尴尬的事实:模型本身很聪明,可它不知道你的项目规范、不知道你团队的测试流程、不知道你希望它先写测试再写实现。你每次都得在 prompt 里重复交代一遍,累不累?agent-skills要解决的就是这个问题——把那些重复的、有固定套路的工程实践,封装成可复用、可组合的"技能",让 AI agent 按需调用。

这篇文章适合谁看?如果你已经在用 Claude Code,或者正在研究 AI coding agents 的工程化落地,尤其是对test-driven-development这类流程自动化感兴趣,那接下来的内容应该能帮你少走不少弯路。我会从整体设计思路讲到具体实操,包括 skills CLI 的用法、技能怎么组织、TDD 流程怎么串起来,以及我在实际配置中踩过的坑。

2. agent-skills 的整体设计与核心思路拆解

2.1 为什么是"技能"而不是"提示词模板"

很多人第一反应是:这不就是高级一点的 prompt template 吗?我一开始也这么想,但用下来发现区别很大。提示词模板是静态的、扁平的,你塞一段文字进去,模型读完就完了。而agent-skills里的"技能"是有结构的——它包含触发条件、执行步骤、依赖工具、验证标准这几个维度。

打个比方,prompt template 像是给厨师一张菜谱纸条,而 skill 像是给厨师一套完整的厨房 SOP:什么情况下做这道菜、需要哪些食材、几步完成、做完怎么检查味道。这个差异在简单任务上看不出来,但一旦涉及多步骤的工程流程,比如 test-driven-development,差距就非常明显了。

从工程角度看,这种设计的好处是可组合性。一个 skill 可以调用另一个 skill,就像函数调用一样。你可以有一个"写测试"的 skill,一个"跑测试"的 skill,一个"根据失败信息修复"的 skill,然后编排成一个完整的 TDD 循环。这种模块化思路,是agent-skills区别于普通提示词管理的核心价值。

2.2 skills CLI 的定位与选型考量

skills CLI是这个体系里的命令行入口,负责技能的安装、管理、调用和版本控制。为什么要有 CLI?因为 AI coding agents 的工作场景天然是终端驱动的。你在 Claude Code 里让它执行终端命令,它需要一个稳定的、可脚本化的接口来操作技能库。

我试过几种不同的组织方式:纯文件目录、配置文件驱动、以及 CLI 管理。实测下来 CLI 方案在几个维度上胜出。第一是发现性,skills list一敲,当前可用的技能一目了然;第二是隔离性,不同项目可以挂载不同的技能集,不会互相污染;第三是可升级性,技能库更新了直接skills update就行,不用手动同步文件。

这里有个选型上的细节值得说:为什么不用 npm 或者 pip 那种包管理思路?因为技能的粒度比包小得多,而且很多技能是项目私有的、不适合公开发布。CLI 方案更轻,本地目录加一个清单文件就能跑起来,不需要注册中心那一套重资产。

2.3 与 Claude Code 的协作模式

Claude Code 本身是一个 agent 运行时,它负责理解你的意图、规划步骤、调用工具。agent-skills扮演的角色是"知识供给方"——当 Claude Code 判断当前任务需要某个技能时,它通过 skills CLI 拉取对应的技能定义,然后按照技能里描述的步骤去执行。

这个协作模式有个关键点:技能不是硬编码进 agent 的,而是运行时动态加载的。这意味着你可以随时给 agent 增加新能力,不用改 agent 本身的代码。我在 Ubuntu 上配置 Claude Code 的时候特意验证过这一点,把技能目录指向一个 Git 仓库,改完 push,下次 agent 调用就是新版本,非常顺滑。

注意:技能加载是有优先级的。项目级技能会覆盖全局技能,同名技能以项目级为准。这个设计在团队协作里很实用,但如果你不小心在项目里放了个半成品技能,可能会覆盖掉全局的好用版本,排查起来容易懵。

3. 核心细节解析与实操要点

3.1 技能目录结构怎么组织才不乱

一个技能的最小单元通常包含这几个文件:SKILL.md(技能描述和步骤)、config.json(元数据和触发条件)、以及可选的scripts/目录(辅助脚本)。我见过有人把所有技能平铺在一个目录里,十几个技能之后就开始找不着北了。推荐按领域分层:

skills/ testing/ tdd-cycle/ coverage-check/ refactor/ extract-function/ docs/ api-doc-gen/

这样组织的好处是,skills list输出的时候天然带分组,而且批量启用/禁用某个领域很方便。我在实际项目里还会加一个_local/目录放实验性技能,跟稳定技能隔离开,避免误触发。

3.2 触发条件的设计:让 agent 知道"什么时候该用"

这是整个体系里最容易被低估的部分。技能写得再好,如果 agent 不知道什么时候该调用它,等于白搭。触发条件一般写在config.json里,支持几种匹配方式:关键词匹配、文件类型匹配、任务类型匹配。

举个例子,一个 TDD 技能的触发条件可能是这样的:

{ "name": "tdd-cycle", "triggers": { "keywords": ["实现", "新功能", "feature", "implement"], "filePatterns": ["*.py", "*.ts", "*.go"], "taskTypes": ["coding"] }, "priority": 10 }

这里priority是个关键参数。当多个技能同时匹配时,优先级高的先执行。我一般把流程性技能(比如 TDD)设高优先级,工具性技能(比如格式化)设低优先级,这样 agent 会先走流程再调工具。

实操心得:触发关键词不要设太宽泛。我一开始把"写"设成触发词,结果 agent 连"写个注释"都要走一遍完整 TDD 流程,烦得不行。后来改成"实现""新增功能"这类明确的开发意图词,误触发率大幅下降。

3.3 技能之间的依赖与编排

单个技能能做的事有限,真正的威力在于编排。agent-skills支持在技能里声明依赖,比如 TDD 技能依赖"生成测试骨架"和"运行测试"两个子技能。声明方式是在SKILL.md的 frontmatter 里写:

--- name: tdd-cycle depends_on: - test-scaffold - test-runner - failure-analyzer ---

运行时,skills CLI 会先解析依赖树,确保所有依赖技能都已加载,然后按拓扑顺序执行。这个机制在复杂流程里特别有用,但也带来一个坑:循环依赖会导致加载失败。我踩过一次,A 依赖 B,B 又依赖 A,CLI 直接报错退出,排查了半天才发现是技能设计上的逻辑闭环问题。

4. 实操过程与核心环节实现

4.1 环境准备:从零把 skills CLI 跑起来

假设你已经在 Ubuntu 或者 macOS 上装好了 Claude Code,接下来装 skills CLI。我实测下来最稳的方式是通过包管理器安装,避免手动编译带来的依赖问题。

# 以 npm 全局安装为例 npm install -g @agent-skills/cli # 验证安装 skills --version

装完之后初始化一个技能工作区:

skills init my-skills cd my-skills

这个命令会生成一个标准的目录骨架,包括skills/、config.yaml和一个示例技能。我建议先别急着删示例,跑一遍skills list确认 CLI 能正确识别,再开始加自己的技能。

如果你是在 VSCode 里配合 Claude Code 使用,还需要在 VSCode 的设置里把 skills CLI 的路径加到环境变量,否则 Claude Code 调用终端命令时可能找不到skills这个可执行文件。这个细节官方文档里提得不多,但实际配置中很容易卡住。

4.2 写第一个技能:以 test-driven-development 为例

TDD 是agent-skills最典型的应用场景,因为它流程固定、步骤明确、验证标准清晰。一个完整的 TDD 技能应该包含三个阶段:红(写失败测试)、绿(写最小实现让测试通过)、重构(优化代码保持测试通过)。

先写SKILL.md:

--- name: tdd-cycle description: 按测试驱动开发流程实现新功能 depends_on: - test-scaffold - test-runner --- ## 执行步骤 1. 分析需求,识别需要测试的行为边界 2. 调用 test-scaffold 生成测试文件骨架 3. 编写至少一个会失败的测试用例 4. 调用 test-runner 运行测试,确认测试失败(红) 5. 编写最小实现代码,让测试通过(绿) 6. 运行全部测试,确认无回归 7. 在测试保护下重构代码 8. 重复 3-7 直到需求完成

这里的关键设计是强制验证失败。很多 AI agent 会跳过"确认测试失败"这一步,直接写实现,结果测试到底有没有真正覆盖到逻辑根本不知道。技能里明确写死这一步,agent 就必须执行。

然后是test-scaffold技能,负责根据语言和框架生成测试文件:

{ "name": "test-scaffold", "language": "auto-detect", "frameworks": { "python": "pytest", "javascript": "jest", "go": "testing" } }

test-runner则封装了运行命令和结果解析逻辑,把测试输出转成 agent 能理解的结构化信息。

4.3 参数计算与选择:测试覆盖率阈值怎么定

TDD 流程里有个绕不开的参数:覆盖率阈值。设太高,agent 会为了凑覆盖率写一堆无意义的测试;设太低,又起不到保护作用。我的经验是按项目阶段分档:

项目阶段建议行覆盖率建议分支覆盖率说明
原型验证40%30%快速迭代优先,别被测试拖死
功能开发70%60%核心逻辑必须覆盖
生产维护85%75%回归风险高,测试要扎实
核心库95%90%对外接口,容错空间极小

这个阈值不是拍脑袋定的。行覆盖率 70% 大致对应"每个函数至少被调用一次",分支覆盖率 60% 对应"主要条件分支都有覆盖"。再往上每提升 5%,边际成本会明显上升,因为要覆盖的都是异常路径和边界条件,写起来费劲。

在技能配置里,这个阈值作为参数传给test-runner:

test-runner: coverage: line: 70 branch: 60 failOnThreshold: true

failOnThreshold: true意味着覆盖率不达标时测试直接判失败,agent 必须补测试。这个开关我建议在功能开发阶段打开,原型阶段关掉。

4.4 实操现场:一次完整的 TDD 循环记录

我拿一个真实的小需求跑了一遍:给一个 Python 工具函数加输入校验。下面是实际的过程记录。

第一步,agent 识别到"新增功能"关键词,触发tdd-cycle技能。它先调用test-scaffold,在tests/test_validator.py里生成了骨架:

import pytest from validator import validate_input def test_validate_input_rejects_empty(): # TODO: 实现测试 pass

第二步,agent 填充测试用例:

def test_validate_input_rejects_empty(): with pytest.raises(ValueError): validate_input("") def test_validate_input_accepts_normal_string(): assert validate_input("hello") == "hello"

第三步,调用test-runner跑测试。因为validate_input还不存在,测试报 ImportError,符合"红"的预期。agent 记录下失败信息。

第四步,写最小实现:

def validate_input(value): if not value: raise ValueError("input cannot be empty") return value

第五步,再跑测试,两个用例都通过,进入"绿"状态。第六步,agent 检查是否有重构空间,发现逻辑已经足够简洁,结束循环。

整个过程大概花了 40 秒,比我手动写快不少,而且测试是先写的,覆盖有保证。这个流程跑顺之后,我基本把新功能的实现都交给它了。

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

5.1 技能不触发怎么办

这是最高频的问题。agent 该用技能的时候没用,八成是触发条件没匹配上。排查顺序是这样的:先skills list --verbose看技能是否加载成功;再用skills match "你的任务描述"手动测试匹配结果;如果匹配为空,检查关键词是否覆盖了你的表达方式。

我遇到过一个典型案例:技能里配的关键词是"重构",但我习惯说"优化这段代码",结果死活不触发。后来在关键词列表里补了"优化""整理""清理",问题解决。所以关键词要覆盖同义词,别只写一个。

5.2 技能执行到一半卡住

这种情况通常是依赖技能缺失或者外部命令超时。先看skills doctor的输出,它会检查所有技能的依赖完整性和命令可用性。如果是超时,调整config.json里的timeout参数,默认是 30 秒,跑大型测试套件可能不够,我一般设成 120 秒。

还有一种卡住是 agent 在等用户确认。有些技能步骤设计成了需要人工介入,如果你希望全自动,得在技能里把requireConfirmation设成false。但我要提醒一句,涉及删除文件、修改数据库这类危险操作,还是保留确认步骤比较稳妥。

5.3 常见问题速查表

问题现象可能原因排查方法解决方案
技能不触发关键词不匹配skills match "描述"补充同义词到 triggers
加载失败循环依赖skills doctor打破依赖环,抽公共技能
执行超时timeout 太短查看日志时间戳调大 timeout 参数
覆盖率不达标阈值过高查看覆盖率报告分阶段调整阈值
技能版本混乱项目级覆盖全局skills list --scope明确技能作用域
命令找不到PATH 未配置which skills配置环境变量

5.4 几个我踩过的坑

第一个坑是技能命名冲突。我在全局和项目里各放了一个叫format的技能,结果项目级的那个功能不全,把全局的好版本覆盖了,格式化出来的代码风格乱七八糟。后来养成习惯,项目级技能一律加前缀,比如proj-format,避免撞名。

第二个坑是过度自动化。一开始我恨不得把所有操作都做成技能,连"读文件"都想封装。结果技能库膨胀到几十个,agent 每次匹配都要遍历一遍,响应变慢,而且很多技能根本用不上。后来砍到十几个核心技能,反而更高效。技能不是越多越好,够用就行。

第三个坑是忽略技能的可测试性。技能本身也是代码,也需要测试。我现在的做法是给每个技能写一个最小的验证用例,放在tests/目录下,改完技能跑一遍,确保没改坏。这个习惯帮我避免了好几次"改一个技能,崩三个流程"的惨剧。

6. 技能库的维护与团队协作实践

6.1 版本管理:技能也要走 Git

技能库本质上是代码资产,必须纳入版本控制。我的做法是每个技能一个目录,整个技能库一个 Git 仓库,用分支管理不同环境的技能集。main分支放稳定技能,dev分支放实验性技能,通过 CI 自动跑技能验证用例。

这里有个细节:技能的config.json里可以声明minCliVersion,指定最低兼容的 CLI 版本。这样当团队里有人 CLI 版本太老时,加载技能会直接报错提示升级,而不是莫名其妙地行为异常。这个字段在团队协作里特别有用,能避免"我这儿好好的,你那儿怎么不行"的扯皮。

6.2 团队共享:怎么让技能库不变成个人玩具

一个人用技能库和一群人用,完全是两码事。团队共享最大的挑战是约定统一。比如 TDD 技能里"测试失败确认"这一步,有人觉得必要,有人觉得浪费时间。这种分歧必须在技能设计阶段就解决,否则技能库会分裂成好几套。

我的经验是搞一个技能评审会,每个新技能上线前过一遍,重点看三件事:触发条件是否明确、步骤是否可复现、验证标准是否客观。评审通过的技能才能进main分支。这个过程一开始有点重,但跑顺之后,技能库的质量会明显高于各自为战的方案。

6.3 与 Claude Code 的深度集成技巧

Claude Code 支持通过配置文件挂载外部技能库。在项目根目录的.claude/config.json里加上:

{ "skills": { "path": "./skills", "autoLoad": true, "cliPath": "/usr/local/bin/skills" } }

autoLoad: true意味着 Claude Code 启动时自动加载技能库,不用每次手动初始化。cliPath指定 CLI 的绝对路径,避免 PATH 问题。

还有一个进阶技巧:把技能库和项目的 CI 打通。每次 push 代码时,CI 自动跑一遍技能验证用例,确保技能和代码同步演进。我在一个项目里这么做了之后,技能失效的情况基本绝迹了。

提示:如果你在 VSCode 里用 Claude Code 插件,记得在插件设置里也配一遍技能路径。插件和 CLI 是两套配置,容易漏掉一个。

7. 我对 agent-skills 这套东西的真实看法

用了一段时间之后,我的整体判断是:agent-skills解决的是 AI coding agents 从"能用"到"好用"之间的那道坎。模型能力本身在快速进步,但工程流程的规范化、可复用化,是模型自己搞不定的,必须靠外部体系来补。技能库就是这个补丁。

它不适合所有人。如果你只是偶尔用 Claude Code 写个小脚本,配技能库的投入产出比不高。但如果你在团队里推 AI 辅助开发,或者有大量重复性的工程流程需要固化,那这套东西的价值就体现出来了。尤其是 test-driven-development 这种流程,一旦封装成技能,整个团队的开发节奏都会被带起来。

后续我打算探索的方向是把技能库和代码审查流程结合,让 agent 在提交前自动跑一遍技能检查,把常见问题拦在 CI 之前。这个想法还在验证阶段,等跑通了再单独写一篇。如果你也在折腾类似的东西,欢迎交流踩坑经验,这类工程化的细节,一个人摸索太慢了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询