
1. 从agent-skills这个标题能读出什么第一次看到agent-skills这个仓库名我的直觉是这不是又一个提示词大全而是一套把 AI coding agent 当新同事来管理的工程化方案。关键词里同时出现了skills CLI、Claude Code、test-driven-development这三个词放在一起指向的其实是一件很具体的事——如何把可复用的工作方法封装成 agent 能稳定调用的技能单元并且用测试驱动的方式验证它真的有效。大多数人用 AI coding agent 的方式还停留在聊天框里许愿打开 Claude Code敲一段需求等它吐代码跑一下报错了再贴回去。这种方式在一次性脚本上够用但只要项目超过几百行、涉及多个模块、需要遵守团队规范就会立刻崩掉——因为 agent 每次都在重新理解你的项目它没有沉淀下来的技能。agent-skills想解决的就是这个沉淀问题。它把怎么让 agent 做某类任务这件事从散落在对话历史里的临时指令变成仓库里可版本管理、可测试、可组合的技能包。适合谁来参考三类人一是已经在用 Claude Code 或类似 AI coding agent 做日常开发、但觉得效率没质变的工程师二是想给团队搭一套统一 AI 协作规范的 tech lead三是单纯好奇skills CLI 到底是个什么东西的探索者。我下面要拆的不是官方 README 的复述而是这套东西背后的设计逻辑、实际落地时会遇到的坑以及我自己在类似方案上踩过的经验。文中涉及的具体命令和目录结构部分是基于同类工具常见实践的合理推断我会明确标注哪些是推断、哪些是通用做法。2. skills CLI 到底在解决什么工程问题2.1 从提示词到技能包的认知转变先厘清一个概念。提示词prompt是一次性的你写完发出去任务结束它就死了。技能skill是可复用的它包含触发条件、执行步骤、依赖工具、验证标准甚至失败后的回退策略。打个比方提示词像是你临时给同事口头交代一件事帮我把这个 CSV 转成 JSON技能像是你写了一份 SOP 文档放进公司知识库凡是遇到 CSV 转 JSON 的需求按这个流程走注意编码问题、注意空值处理、完成后用这个脚本校验。skills CLI的价值就在于它提供了管理这些 SOP 的命令行入口。典型的能力包括初始化一个技能目录、按模板生成技能骨架、本地校验技能格式、把技能注册到 agent 的可见范围、列出当前可用的技能。这些操作听起来平淡但它是技能能被工程化管理的前提——没有 CLI技能就只是一堆散落的 markdown 文件没人知道哪个是最新的、哪个还在用。2.2 为什么必须是 CLI 而不是 GUI有人会问搞个图形界面点点不香吗我的经验是AI coding agent 的工作流天然在终端里。你在 Claude Code 里干活本来就在敲命令、看 diff、跑测试。如果技能管理要切到浏览器上下文就断了。CLI 的另一个好处是可脚本化你可以在 CI 里跑一条命令校验所有技能格式可以在 pre-commit hook 里检查技能有没有引用不存在的工具这些用 GUI 都很难做。提示如果你之前没接触过这类工具别急着装。先在纸上画出你日常重复度最高的 3 类任务看看它们是否值得封装成技能。封装成本不低只做一次的任务不值得。2.3 技能包的典型目录结构基于同类工具的常见设计一个技能包通常长这样skills/ csv-to-json/ SKILL.md # 技能说明何时触发、做什么、怎么验证 scripts/ convert.py # 实际执行脚本 tests/ test_convert.py # 验证脚本正确性 examples/ input.csv expected.json这个结构里最关键的是SKILL.md和tests/。前者告诉 agent什么时候该用我后者告诉人类我怎么知道它没坏。很多团队做技能管理只做了前者结果技能越攒越多没人敢用因为不知道哪个还能跑通。测试目录就是解药。3. 把 TDD 思路搬到 agent 技能开发上3.1 为什么技能也需要测试驱动test-driven-development出现在关键词里不是偶然。技能的本质是一段会被反复执行的逻辑只要是被反复执行的逻辑就符合 TDD 的适用场景。传统 TDD 是先写测试再写实现。技能开发的 TDD 稍微变形一下先写清楚这个技能在什么输入下应该产出什么输出再写技能实现。这个输入-输出的约定就是技能的测试用例。我见过太多技能是这样写出来的作者凭感觉写了一段提示词自己试了一次觉得不错就提交了。三个月后别人用同样的技能输入稍微变一点输出就完全跑偏因为没人定义过边界。TDD 强迫你在写之前就想清楚边界。3.2 技能测试的三个层次不是所有技能都值得写完整测试。我一般分三层层次测什么成本适用场景L1 冒烟测试技能能否被加载、依赖是否齐全极低所有技能必做L2 行为测试给定输入输出是否符合预期结构中等有明确输入输出的技能L3 回归测试修改技能后历史用例是否仍通过较高核心技能、多人协作L1 其实就是一个校验脚本检查SKILL.md的 frontmatter 字段是否完整、引用的脚本文件是否存在。这个用skills CLI的校验命令就能覆盖。L2 需要你为技能准备样例输入和期望输出跑一遍对比。L3 是把 L2 的用例攒起来每次改动都全量跑。3.3 一个具体的技能测试写法假设我们有个把日志文件按错误级别分类的技能。测试可以这样写Python 示例实际用什么语言取决于你的技能实现import subprocess import json def test_classify_logs_by_level(): result subprocess.run( [python, scripts/classify.py, examples/sample.log], capture_outputTrue, textTrue ) output json.loads(result.stdout) assert ERROR in output assert WARN in output assert len(output[ERROR]) 3 # 样例里恰好3条错误这个测试的价值不在于它多复杂而在于它把技能应该做什么变成了可执行的断言。以后有人改了这个技能跑一下测试就知道有没有破坏原有行为。注意技能的测试和普通代码测试有个关键区别——技能可能依赖 LLM 的非确定性输出。如果你的技能核心是调模型测试就不能断言精确字符串而要断言结构比如输出必须是合法 JSON或范围比如分类结果必须属于预定义类别。这一点很多人第一次做会踩坑。4. 在 Claude Code 里落地技能的实际路径4.1 环境准备阶段最容易忽略的事热词里大量出现claude code 安装、vscode配置claude code、ubuntu配置claude code说明很多人卡在第一步。我这里不重复安装步骤只讲几个文档里通常不写、但实际会卡住你的点。第一Node 版本。Claude Code 这类工具对 Node 版本有要求Ubuntu 上系统自带的 Node 往往偏旧。我建议用版本管理工具装一个 LTS 版本别用apt install nodejs直接装。第二终端环境。如果你在 VS Code 里用集成终端注意 shell 配置可能和系统终端不一致导致命令找不到。第三权限。技能脚本如果要读写文件注意运行 agent 的用户对这些路径有没有权限这个在容器或远程开发环境里特别容易出问题。4.2 技能注册到 agent 的可见范围技能写好了怎么让 agent 知道它存在这是skills CLI的核心功能之一。常见做法有两种一种是目录约定。把技能放在 agent 默认扫描的目录下比如项目根目录的skills/或用户配置目录下的skills/agent 启动时自动加载。这种方式简单但技能多了会拖慢启动而且不好控制哪些技能对哪些项目可见。另一种是显式注册。通过 CLI 命令把技能注册到某个配置文件里agent 读配置决定加载哪些。这种方式可控性强适合团队协作但多了一步操作。我的建议是个人项目用目录约定团队项目用显式注册。团队项目里技能是共享资产需要 review、需要版本控制显式注册能让谁在什么时候加了什么技能变得可追溯。4.3 技能触发时机的设计这是最容易被低估的部分。技能写得好不好一半看实现一半看触发条件描述得准不准。SKILL.md里通常有一段描述什么时候用这个技能。这段描述是给 agent 看的agent 会根据当前任务和这段描述做匹配。如果描述太宽泛比如处理数据agent 会在不该用的时候用它如果太窄比如处理 UTF-8 编码的、字段用逗号分隔的、行尾是 LF 的 CSVagent 又匹配不上。我的经验是触发描述要包含三个要素任务类型 输入特征 预期产出。比如当用户需要把结构化表格数据转换为 JSON 格式且输入是本地 CSV 文件时使用本技能产出为 JSON 文件。这样 agent 匹配起来准确率高很多。5. 技能组合与依赖管理的坑5.1 技能之间会互相调用当技能攒到十几个你会发现有些技能天然依赖另一些。比如生成 API 文档的技能可能依赖解析代码注释的技能。这时候就出现了依赖管理问题。最朴素的做法是在SKILL.md里写一句本技能依赖 xxx 技能。但这只是文档约定agent 不一定遵守。更可靠的做法是在技能实现里显式调用依赖技能或者用 CLI 的依赖声明功能如果工具支持。我踩过的坑是两个技能各自实现了一遍读取配置文件的逻辑后来配置文件格式变了只改了一个另一个就坏了。能抽公共逻辑就抽出来做成基础技能这是血泪教训。5.2 技能版本冲突团队协作时A 同学升级了代码格式化技能B 同学的项目还在用旧版结果 B 的 agent 加载了新技能格式化规则变了把 B 的代码改得面目全非。解决办法是给技能加版本号并且在项目里锁定技能版本。这跟 npm 锁版本是一个道理。skills CLI如果支持 lockfile 机制一定要用起来。如果不支持就在项目里维护一个技能清单文件记录每个技能的版本。5.3 技能失效的静默问题最危险的情况是技能悄悄失效了。比如技能依赖的外部 API 改了返回格式技能还能跑但输出是错的而且不报错。这种问题靠人工发现几乎不可能。我的做法是给关键技能加输出校验技能执行完后用一个独立的校验脚本检查输出是否符合预期结构。校验失败就报警。这个校验脚本本身也可以是一个技能形成执行技能 校验技能的组合。6. 从个人效率到团队资产的演进6.1 个人阶段先跑通一个技能别一上来就设计一套技能体系。先挑一个你每天都要做的重复任务把它封装成一个技能跑通全流程写SKILL.md、写实现、写测试、注册、实际用一周。这一周里你会暴露出一堆设计问题比空想强一百倍。我第一个技能是把散落的会议记录整理成结构化待办。听起来简单但实际做的时候发现会议记录格式千奇百怪、待办的优先级判断标准模糊、输出格式要跟任务管理工具对齐。这些问题不实际跑一遍根本想不到。6.2 团队阶段技能评审与共享当技能要共享给团队就需要评审机制。评审看什么我看四点触发描述是否准确、实现是否有测试、依赖是否清晰、是否有失败回退方案。这四点过了技能才能进共享库。共享库还要有发现机制。新人怎么知道有哪些技能可用一个维护良好的技能索引可以是自动生成的 README比什么都重要。索引里至少要有技能名、一句话说明、触发场景、维护人。6.3 技能的生命周期管理技能会过时。业务变了、工具升级了、依赖下线了技能就该退役。但退役比新增难因为没人愿意承认自己写的技能没用了。我的做法是给技能加最后验证时间字段。超过一定时间没被验证过的技能在索引里标记为待确认。用的人看到标记要么去验证一下要么就别用。这样能自然淘汰掉僵尸技能。7. 几个高频问题的实测回答7.1 技能和普通脚本有什么区别经常有人问我直接写个 shell 脚本不就行了为什么要搞技能区别在于技能是给 agent 看的脚本是给人看的。脚本需要你知道它存在、知道怎么调、知道参数是什么。技能通过SKILL.md的描述让 agent 自己判断什么时候该调用它。这是本质区别。当然技能内部可以调用脚本。脚本是技能的手SKILL.md是技能的嘴负责跟 agent 沟通。7.2 技能会不会让 agent 变慢会但通常值得。agent 启动时要加载技能描述技能越多加载越慢匹配时也要花更多推理。我的经验是单个项目的活跃技能控制在 20 个以内超过就要考虑分组或按需加载。如果发现 agent 响应明显变慢先检查是不是加载了一堆用不上的技能。7.3 没有测试的技能能不能用能用但风险自担。我的底线是个人临时用的技能可以没测试进共享库的技能必须有 L1 测试。L1 测试成本极低就是校验一下文件完整性连这个都不做的技能不值得信任。7.4 技能描述用中文还是英文看你的 agent 和团队。如果团队都用中文交流技能描述用中文没问题agent 对中文的理解已经足够好。但如果技能要跨团队共享或者你用的模型对英文更敏感建议用英文写核心描述中文写补充说明。我自己的做法是SKILL.md的 frontmatter 用英文字段名和值正文说明用中文兼顾机器解析和人类阅读。8. 我在这套方案上踩过的真实坑第一个坑是过度封装。刚开始做技能时我把每个小操作都封装成技能结果技能数量爆炸agent 匹配时经常选错。后来我改成一个技能解决一类问题数量降下来准确率反而上去了。第二个坑是忽略技能的失败路径。技能执行失败时怎么办是重试、是回退到人工、还是报错终止我早期写的技能都没考虑这个失败就静默退出agent 以为成功了继续往下走最后产出错误结果。现在我的每个技能都会明确写失败处理逻辑。第三个坑是技能和项目耦合太紧。有个技能我写死了项目里的某个路径后来项目重构路径变了技能就废了。教训是技能里的路径、配置、常量能参数化就参数化能读环境变量就读环境变量。第四个坑是测试用例太少。我有个技能只写了一个测试用例跑通了就上线。结果遇到一个边界输入空文件技能直接崩溃。后来我强制自己每个技能至少写三个用例正常输入、边界输入、异常输入。9. 给准备入手的你几条实在建议如果你现在想动手我的建议是按这个顺序来先花半天时间把 Claude Code 或你用的 agent 跑通确保基础环境没问题然后挑一个你本周重复做了三次以上的任务把它写成第一个技能写完别急着优化先用一周记录每次用的时候哪里别扭一周后根据记录改一版这时候再考虑加测试、加依赖管理。技能体系这东西先有再用再谈优化。我见过太多人卡在设计阶段想设计一套完美的技能架构结果一个技能都没落地。技能的价值在于被使用不在于设计得多漂亮。另外别把技能当成一劳永逸的东西。业务在变技能就得跟着变。把技能当成活的资产来维护定期回顾、定期清理它才能真正帮你省时间而不是变成新的技术债。