
1. 从 agent-skills 说起为什么它值得单独拿出来聊第一次看到agent-skills这个项目名的时候我下意识以为又是一个给 AI Agent 加技能包的玩具仓库。真正翻完代码和文档之后才发现它解决的是一个非常具体、也非常痛的问题怎么把散落在各个项目里的 AI coding agent 能力变成可复用、可版本化、可测试的标准化技能。说白了agent-skills是一套围绕skills CLI构建的技能管理方案核心目标是把让 AI 写代码这件事从每次都要重新调教变成一次定义、到处调用。它主要服务于三类人一是天天用Claude Code这类 AI coding agent 干活的开发者二是想把团队内部最佳实践沉淀成可执行资产的 Tech Lead三是正在做 AI 工具链集成、需要一套稳定技能抽象层的平台工程师。我自己的使用场景很典型手头同时维护着几个不同技术栈的项目前端 React、后端 Go、脚本 Python每个项目对 AI 助手的期望都不一样。以前的做法是在每个项目里塞一份CLAUDE.md或者类似的提示词文件改一处忘一处时间一长就彻底失控。agent-skills出现之后我把这些零散的约定抽成了独立技能用 CLI 统一管理配合test-driven-development的思路给技能本身写测试整个流程才算真正稳下来。这篇文章我会按实际落地的顺序来讲先拆它的整体设计思路再讲核心细节和实操要点然后是完整的搭建过程最后是我踩过的坑和排查技巧。如果你正在用或者准备用 Claude Code、VS Code 里的 AI 插件或者想给团队搭一套 AI 技能库这篇应该能帮你少走不少弯路。2. 整体设计与思路拆解为什么是技能而不是提示词2.1 从提示词堆砌到技能抽象中间差了什么大部分人用 AI coding agent 的起点都是一样的写一段提示词丢给模型看结果不满意就改提示词。这个模式在单次任务里没问题但一旦涉及我每周都要做同一类事就会暴露三个致命问题。第一是不可复用。你在 A 项目里调好的提示词搬到 B 项目基本要重写因为上下文、目录结构、依赖都不一样。第二是不可测试。提示词写得好不好全靠人肉判断没有回归测试改一个字可能就把之前调好的行为搞崩了。第三是不可组合。一个复杂任务往往需要多个步骤比如先跑测试、再改代码、再验证提示词模式下你只能把所有逻辑塞进一段话里模型稍微跑偏就全乱。agent-skills的思路是把这些提示词升级成技能skill。一个技能包含四样东西明确的触发条件、结构化的输入输出定义、可执行的步骤逻辑、以及配套的测试用例。这四样东西合在一起就形成了一个可以被 CLI 加载、被 agent 调用、被测试覆盖的独立单元。我打个比方。提示词像是你临时写给同事的一张便签技能则像是公司内部的一份标准作业程序SOP有编号、有版本、有验收标准。便签用完就扔SOP 可以一直迭代。2.2 skills CLI 在整个链路里扮演什么角色skills CLI是这个项目的入口和中枢。它做的事情可以概括为四件发现、加载、执行、验证。发现是指 CLI 会扫描指定目录找出所有符合规范的技能定义文件。加载是指把这些定义解析成运行时可以理解的结构注入到 agent 的上下文里。执行是指当 agent 判断当前任务匹配某个技能时CLI 负责把技能内容喂给模型。验证是指技能自带的测试用例可以被单独跑起来确认技能行为没有退化。为什么要有 CLI 而不是纯配置文件因为 AI coding agent 的工作流是动态的。同一个会话里agent 可能先调用代码审查技能再调用写测试技能中间还要根据结果决定下一步。纯静态配置没法处理这种动态调度CLI 可以。2.3 为什么把 test-driven-development 拉进来这是我觉得agent-skills最有意思的一个设计决策。传统上 TDD 是写业务代码的方法论这里被用到了技能本身上。具体做法是每个技能在定义的时候必须同时提供一组输入-期望输出的样例。CLI 跑测试的时候会把这些输入喂给 agent然后比对实际输出和期望输出。如果偏差超过阈值测试就失败。这个设计的好处非常直接。技能是会被人不断修改的今天你觉得某句话表述更清楚改了一下明天可能就发现 agent 的行为完全变了。有了测试这种退化能在提交前就被拦住。我自己的技能库现在有二十多个技能每次改动都会跑一遍全量测试心里踏实很多。提示技能测试不需要覆盖所有边界情况重点覆盖这个技能最核心的判断逻辑就够了。追求 100% 覆盖反而会让技能定义变得臃肿。2.4 方案选型背后的取舍有人可能会问为什么不直接用 Claude Code 自带的项目级配置非要引入一个额外的 CLI我的理解是这样项目级配置解决的是这个项目里 AI 该怎么干活agent-skills解决的是跨项目、跨团队AI 能力怎么沉淀和分发。两者不是替代关系是层次关系。另一个取舍是技能粒度。太粗一个技能包打天下复用性差太细每个技能只做一件小事调度成本高。我实践下来的经验是一个技能对应一个人能在五分钟内讲清楚的任务比较合适。比如给 Go 函数补单元测试是一个技能重构整个模块就不是后者应该拆成多个技能组合。3. 核心细节解析与实操要点技能到底长什么样3.1 技能定义文件的结构一个标准的技能定义通常包含几个部分我用一个实际例子来说明。假设我要定义一个给 Python 函数补 pytest 测试的技能结构大概是这样name: python-pytest-generator version: 1.2.0 trigger: keywords: [写测试, 补测试, pytest] file_patterns: [*.py] inputs: - name: target_function type: code_block required: true outputs: - name: test_code type: code_block steps: - 分析目标函数的输入输出和边界条件 - 生成覆盖正常路径和异常路径的测试用例 - 确保测试可以被 pytest 直接执行 constraints: - 不修改原函数 - 测试文件命名遵循 test_*.py这个结构里trigger决定技能什么时候被激活inputs和outputs定义了技能的契约steps是给 agent 的执行指引constraints是硬性约束。四者缺一不可。我特别想强调constraints这一块。很多人写技能的时候只写要做什么不写不能做什么结果 agent 经常做出意料之外的操作比如顺手把原函数也改了。把禁止项写清楚比写十条正向指引都管用。3.2 触发条件的写法直接决定技能命中率触发条件是技能能不能被正确调用的关键。写得太宽什么任务都往里套写得太窄该用的时候用不上。我的经验是分两层写关键词层和上下文层。关键词层负责快速筛选比如写测试补测试这类用户高频表达。上下文层负责精确匹配比如当前打开的文件是.py结尾、光标在某个函数内部。这里有个容易忽略的点关键词要覆盖同义表达。用户可能说写测试也可能说加单测补 case生成 test如果只写一个命中率会很低。我一般会列五到八个常见说法跑一段时间后再根据实际日志补充。注意触发条件不是越多越好。超过十个关键词之后误触发的概率会明显上升尤其是那些含义模糊的词比如优化改进最好别放进去。3.3 输入输出的类型系统agent-skills对输入输出做了简单的类型约束常见的有code_block、file_path、text、list。这个设计看起来不起眼实际用起来很关键。举个例子如果某个技能的输入类型是file_pathCLI 在调用前会先确认这个路径存在不存在就直接报错不会把无效输入丢给模型。如果类型是code_blockCLI 会确保输入是一段完整的代码而不是半截。输出类型同样重要。如果技能声明输出是code_block但模型返回了一段解释性文字CLI 会判定这次调用失败触发重试或者报错。这种契约式的设计让技能的行为变得可预测。3.4 步骤逻辑的颗粒度控制steps是技能的核心也是最难写好的部分。写得太粗agent 自由发挥空间太大结果不稳定写得太细又变成了死板的脚本失去了 AI 的灵活性。我的做法是三步原则每个技能的核心步骤控制在三到五步每步描述做什么而不是怎么做。比如分析目标函数的边界条件是做什么用 if 判断参数是否为 None就是怎么做后者不该写进技能定义。另外步骤之间要有明确的依赖关系。如果第二步依赖第一步的输出要在描述里体现出来比如基于上一步的分析结果生成测试用例。这样 agent 在执行的时候不会跳步。3.5 版本管理不能省技能是要迭代的所以版本号必须认真对待。我采用的是语义化版本修 bug 升 patch加功能升 minor改契约升 major。为什么强调这个因为技能一旦被多个项目引用改动的兼容性就变得很重要。如果某个项目依赖的是1.2.0你直接改成2.0.0把输入结构换了那个项目就会挂。有了版本号项目可以锁定自己需要的版本升级的时候也有明确的判断依据。4. 实操过程与核心环节实现从零搭一套技能库4.1 环境准备与 CLI 安装先说环境。我日常在 macOS 和 Ubuntu 上都有开发两边流程基本一致。前置依赖主要是 Node.js建议 18 以上和 Git。安装 skills CLI 的步骤# 确认 Node 版本 node -v # 全局安装 CLI npm install -g agent-skills-cli # 验证安装 skills --version如果是在 VS Code 里配合 Claude Code 使用还需要确认 Claude Code 插件已经装好并且能在终端里正常调用。这一步很多人会卡住常见原因是 Node 版本太低或者全局 bin 目录没进 PATH。排查方法很简单which skills看能不能找到可执行文件。提示如果你用的是公司内网环境npm 源可能需要换成内部镜像否则安装会超时。这个具体配置问一下团队的基础设施同事就行。4.2 初始化技能库目录CLI 装好之后第一步是初始化一个技能库。我建议单独建一个 Git 仓库来放技能不要和业务代码混在一起。mkdir my-agent-skills cd my-agent-skills skills initskills init会生成一个基础目录结构my-agent-skills/ ├── skills/ │ └── example/ │ ├── skill.yaml │ └── tests/ ├── config.yaml └── README.mdskills/目录下每个子目录就是一个技能config.yaml是全局配置主要放技能加载路径、默认模型、超时时间这些。4.3 写第一个技能以生成单元测试为例我拿最常用的生成单元测试来演示完整流程。先建目录skills create python-unit-testCLI 会生成一个模板skill.yaml然后我把它改成实际内容。这里有个细节trigger里的file_patterns一定要写对否则技能在错误的文件类型上也会被触发。写完之后用 CLI 做一次本地校验skills validate python-unit-test校验会检查 YAML 语法、必填字段、类型定义是否合法。这一步能拦掉大部分低级错误。4.4 给技能写测试用例这是agent-skills区别于普通提示词管理工具的核心环节。测试用例放在技能的tests/目录下格式是输入 期望输出特征。cases: - name: 简单函数补测试 input: target_function: | def add(a, b): return a b expect: contains: [def test_add, assert] not_contains: [def add]注意expect里我用的是包含和不包含这种特征匹配而不是精确匹配。因为 AI 生成的测试代码每次都不完全一样精确匹配会导致测试永远失败。特征匹配才是正确姿势。跑测试的命令skills test python-unit-test第一次跑大概率会失败别慌根据失败信息调整技能定义或者测试用例。我自己的经验是一个技能从写完到测试稳定通过平均要迭代三到五轮。4.5 把技能接入 Claude Code技能库准备好之后下一步是让 Claude Code 能调用它。在项目根目录的配置文件里加上技能库路径skills: paths: - /path/to/my-agent-skills/skills auto_load: trueauto_load: true表示启动时自动加载所有技能。如果技能很多可以改成按需加载只加载当前项目相关的。接入之后在 Claude Code 里输入帮我给这个函数写测试如果技能配置正确agent 应该会自动匹配到python-unit-test技能并执行。如果没反应先检查触发关键词是否匹配再看 CLI 日志里技能有没有被加载。4.6 参数选择与阈值调优技能执行过程中有几个参数值得调参数默认值建议范围说明timeout30s15-60s单次技能执行超时retry10-3失败重试次数match_threshold0.70.6-0.85触发匹配阈值max_tokens40962048-8192单次输出上限match_threshold是最需要调的。调高技能命中更精准但可能漏触发调低命中率高但容易误触发。我一般从 0.7 开始根据实际日志微调。retry不建议设太高。重试次数多了一次任务可能跑好几分钟体验很差。如果某个技能经常需要重试说明技能定义本身有问题应该去改定义而不是加重试。5. 常见问题与排查技巧实录5.1 技能不触发怎么办这是最高频的问题。排查顺序我总结成一张表现象可能原因排查方法完全没反应技能未加载看 CLI 启动日志偶尔触发关键词覆盖不足补充同义表达触发但报错输入类型不匹配检查 inputs 定义触发错误技能关键词冲突调整 match_threshold我遇到最多的是关键词覆盖不足。比如用户说补个单测我的技能里只写了写测试就匹配不上。解决办法是定期看 CLI 的调用日志把没匹配上的用户表达收集起来补进关键词列表。5.2 技能执行结果不稳定同一个技能有时候输出很好有时候一塌糊涂。这种情况通常是steps写得太模糊。我的排查方法是把失败的案例单独拎出来看 agent 在哪一步跑偏了。如果是第一步就偏说明触发条件或者输入定义有问题如果是中间步骤偏说明步骤描述不够明确如果是最后一步偏说明输出约束不够。改的时候一次只改一个地方改完立刻跑测试。同时改多处出了问题根本不知道是哪处导致的。5.3 技能之间互相干扰技能多了之后会出现该用 A 技能的时候用了 B的情况。根本原因是两个技能的触发条件有重叠。解决办法有两个一是给技能加优先级字段冲突时高优先级胜出二是把重叠的关键词从其中一个技能里移除让职责更清晰。我倾向于第二种因为优先级机制用多了会让整个系统变得难以理解。5.4 测试用例维护成本高技能多了之后测试用例的维护确实是个负担。我的做法是分层核心技能写完整测试边缘技能只写冒烟测试。另外测试用例要跟着技能一起版本化。技能升 minor 版本的时候测试用例也要相应更新。如果发现某个测试用例长期失败又懒得修那说明这个技能可能已经没人用了该考虑下线。5.5 独家避坑技巧分享几个文档里不会写、但实际很管用的经验。第一技能命名用动词开头。generate-unit-test比unit-test-generator更好因为前者直接描述了动作agent 匹配的时候语义更清晰。第二给技能写一句反例说明。比如在约束里写不要生成依赖外部服务的测试比写十条正向要求都有效。AI 对否定指令的响应其实比想象中好。第三定期清理僵尸技能。我每季度会跑一次技能使用统计三个月没被调用过的技能直接归档。技能库不是越大越好维护成本是实打实的。第四技能库要独立 CI。每次提交自动跑全量技能测试通过才允许合并。这一步做了之后技能质量会稳定很多。6. 技能库的扩展方向与团队协作实践6.1 从个人技能库到团队共享个人用和团队用差别很大。个人用的时候技能定义可以随意一点反正只有自己看。团队用的时候技能就变成了公共资产需要考虑命名规范、文档、评审流程。我们团队现在的做法是技能提交必须走 PR至少一个人 review。review 的重点不是代码风格而是触发条件是否清晰、约束是否完整、测试是否覆盖核心逻辑。这三条过了基本就不会出大问题。另外团队技能库要有一个CONTRIBUTING.md写清楚技能定义的模板、命名规范、测试要求。新人照着模板写能省掉大量沟通成本。6.2 技能组合与工作流编排单个技能解决单点问题多个技能组合起来才能解决复杂任务。agent-skills支持在配置里定义工作流把多个技能串起来。比如提交前检查这个工作流可以串三个技能先跑代码风格检查再跑生成缺失的测试最后跑生成 commit message。每个技能独立定义、独立测试组合起来就是一个完整流程。这种设计的好处是任何一个环节出问题只需要改对应的技能不影响其他环节。而且技能可以被不同工作流复用比如生成测试这个技能既可以用在提交前检查也可以用在代码审查流程里。6.3 与不同 AI 模型的适配agent-skills的技能定义是模型无关的但实际执行效果会因模型而异。同一个技能在不同模型上的表现可能差别很大。我的经验是技能定义里不要写死模型相关的细节比如用某个特定格式输出。这些应该放在配置层针对不同模型做适配。技能本身只描述做什么怎么做交给模型和配置。如果团队里同时用多个模型建议给每个模型单独跑一遍技能测试记录通过率。通过率低的技能可能需要针对该模型做专门的适配版本。6.4 技能库的度量与优化技能库不是建完就完事了需要持续度量。我关注的指标主要有四个触发准确率、执行成功率、平均耗时、复用次数。触发准确率反映技能定义的质量低于 80% 就要优化触发条件。执行成功率反映技能的稳定性低于 90% 要检查步骤逻辑。平均耗时影响体验超过 30 秒的技能要考虑拆分。复用次数反映技能的价值长期为零的技能该考虑下线。这些指标可以从 CLI 的日志里统计出来我一般写个简单的脚本每周跑一次生成一份报告。数据驱动的好处是优化方向很明确不用凭感觉。6.5 我个人的一些体会用agent-skills这套东西大半年下来最大的感受是AI 能力的沉淀本质上和代码资产的沉淀是一回事。都需要抽象、需要测试、需要版本管理、需要持续维护。那些指望写个好提示词就一劳永逸的想法最后都会在规模上来之后崩掉。另一个体会是技能库的价值不在于数量而在于质量。我见过有人一口气写了五十个技能结果常用的就三五个剩下的全是维护负担。与其铺量不如把最常用的那几个技能打磨到极致让它们真正成为团队日常工作流的一部分。最后分享一个小技巧每次发现自己在重复某个操作就停下来想一想这个操作能不能变成一个技能。这个习惯坚持下来技能库会自然生长而且长出来的都是真正有用的东西。