ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

agent-skills 实战:用 skills CLI 为 Claude Code 构建 TDD 技能库

agent-skills 实战:用 skills CLI 为 Claude Code 构建 TDD 技能库 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 依赖 BB 又依赖 ACLI 直接报错退出排查了半天才发现是技能设计上的逻辑闭环问题。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-runnertest-runner: coverage: line: 70 branch: 60 failOnThreshold: truefailOnThreshold: 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 之前。这个想法还在验证阶段等跑通了再单独写一篇。如果你也在折腾类似的东西欢迎交流踩坑经验这类工程化的细节一个人摸索太慢了。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表