☰
agent-skills实战:用技能体系让AI编码代理像工程师一样工作
2026/10/7 4:09:03 网站建设 项目流程

1. 从"agent-skills"这个标题能读出什么

第一次看到agent-skills这个仓库名,我的直觉是:这不是又一个"提示词大全",而是一套把 AI coding agent 当"新员工"来培养的技能体系。标题里的 skills 用的是复数,说明它不是一个单点技巧,而是一组可组合、可复用、可被 agent 主动调用的能力单元。结合热搜词里高频出现的 AI coding agents、skills CLI、Claude Code、test-driven-development,基本可以判断:这个项目要解决的核心问题是——如何让一个通用大模型驱动的编码代理,在具体工程里表现得像一个懂规矩、有方法论的熟练工程师,而不是一个只会补全代码的自动补全器。

大多数人用 AI 写代码的方式还停留在"对话式":打开对话框,描述需求,复制粘贴结果,跑一下报错了再贴回去。这种方式在写几十行脚本时够用,但一旦进入真实项目——有测试、有 lint、有目录约定、有 CI——就会迅速崩盘。崩盘的原因不是模型不够聪明,而是它不知道这个项目的"规矩"。agent-skills这类项目的价值,就是把这些规矩和方法论沉淀成 agent 能读、能执行、能自我校验的技能包。

这篇文章适合三类人看:一是已经在用 Claude Code 或类似 AI coding agent、但总觉得"它不够听话"的开发者;二是想给团队搭建一套 AI 辅助开发规范的技术负责人;三是单纯好奇"skills CLI 到底是个什么东西"的探索者。我会从技能的本质讲起,拆到目录结构、CLI 用法、TDD 技能的具体设计,再聊接入不同模型时的坑,最后给一套可以直接抄的落地流程。全程按我自己的实操经验来写,不堆概念。

需要先说明一点:下面涉及的具体命令、目录命名、配置字段,凡是输入材料里没有明确给出的,都是基于这类工具常见实践做的合理补全,你在自己项目里落地时以实际版本为准。

2. 为什么"技能"比"提示词"更适合 agent

2.1 提示词是临时的,技能是沉淀的

提示词(prompt)的本质是一次性指令。你今天写了一段很长的系统提示,告诉模型"写代码前先写测试、提交前跑 lint、不要用 any 类型",明天换个会话,这些约束就没了。你得反复粘贴,或者塞进一个越来越臃肿的配置文件里。时间一长,这个配置文件会变成一坨没人敢动的"祖传提示词"。

技能(skill)的思路完全不同。它把一类任务的方法论拆成一个独立单元,每个单元有自己的触发条件、执行步骤、校验标准。agent 在遇到对应场景时,主动加载这个技能,按里面的流程走。这就像公司里的 SOP 文档:新员工不需要你每次口头交代,他自己会去翻对应的操作手册。

这个区别带来的直接好处是可维护性。测试驱动开发是一套技能,代码审查是一套技能,数据库迁移是一套技能。它们互不干扰,可以单独迭代。某个技能写错了,改那一个文件就行,不会牵动全局。

2.2 技能让 agent 有了"工作流意识"

普通 agent 的工作模式是"你问我答",缺乏流程感。你让它实现一个功能,它可能直接开始写业务代码,测试最后补,边界条件靠你提醒。而带技能的 agent 会先判断:这个任务属于哪一类?该调用哪个技能?技能里规定的第一步是什么?

以 TDD 为例,一个合格的 TDD 技能应该强制 agent 走这样的顺序:先理解需求 → 写一个会失败的测试 → 运行测试确认它确实失败 → 写最小实现让测试通过 → 重构 → 再跑一遍全部测试。这个顺序不是形式主义,它保证了 agent 每一步都有明确的"完成信号",而不是凭感觉说"我觉得写完了"。

2.3 技能是可组合的积木

单个技能解决单类问题,但真实任务往往是复合的。比如"给用户模块加一个导出 CSV 的接口"这件事,同时涉及:接口设计、测试编写、错误处理、文档更新。如果每个环节都有对应技能,agent 就能把它们串起来,形成一个完整的工作流。这种组合能力,是单纯堆提示词做不到的。

我在实际项目里观察到的一个现象:当 agent 有了明确的技能边界后,它"跑偏"的概率明显下降。因为它知道当前处于哪个阶段,下一步该做什么,而不是自由发挥。

3. 一个 agent-skills 仓库通常长什么样

3.1 目录结构背后的设计意图

虽然输入材料没有给出具体结构,但这类项目的组织方式有很强的共性。一个典型的 skills 仓库大致是这样:

agent-skills/ ├── skills/ │ ├── test-driven-development/ │ │ ├── SKILL.md │ │ ├── examples/ │ │ └── scripts/ │ ├── code-review/ │ │ ├── SKILL.md │ │ └── checklist.md │ └── ... ├── cli/ │ └── ... ├── package.json └── README.md

每个技能一个目录,目录里最核心的是那个描述文件(这里叫SKILL.md,不同项目可能叫别的名字)。这个文件通常包含几块内容:技能名称和一句话描述、触发条件(什么时候该用这个技能)、执行步骤、校验标准、示例。

为什么要把示例和脚本单独放?因为技能描述文件要保持"可读性",让 agent 快速抓住要点;而具体的代码示例、辅助脚本属于"参考资料",按需加载即可。这种分层设计能有效控制上下文长度——agent 不需要一次性把所有细节都读进来。

3.2 SKILL.md 里到底写什么

我拆过几个类似的技能文件,结构上大同小异。一个写得好的技能描述,通常包含以下要素:

  • 元信息:技能名、版本、适用场景的一句话说明。
  • 触发条件:明确列出"当用户要求 X 时"或"当检测到 Y 时"启用本技能。这一块非常关键,写得太宽会导致技能被滥用,写得太窄又永远触发不了。
  • 前置检查:执行前需要确认的环境、依赖、文件状态。
  • 步骤清单:编号的执行步骤,每步都有明确的输入和输出。
  • 完成标准:怎么判断这个技能执行成功了。比如 TDD 技能的完成标准是"所有测试通过且新增测试覆盖了新功能"。
  • 反例:明确写出"不要这样做"的情况,这往往比正面指导更有效。

提示:技能描述文件最忌讳写成散文。agent 读的是结构化信息,不是文学作品。用列表、用明确的动词开头,比大段叙述有效得多。

3.3 技能之间的依赖关系

有些技能不是孤立的。比如"提交代码"这个技能,可能依赖"运行测试"和"运行 lint"两个前置技能。设计时要把这种依赖显式写出来,否则 agent 可能在测试没跑的情况下就提交了。

我见过一种处理方式:在技能文件里加一个depends_on字段,列出必须先完成的技能。agent 加载技能时,会先检查依赖是否满足。这种显式声明比让 agent 自己"悟"要可靠得多。

4. skills CLI:把技能装进你的工作流

4.1 CLI 解决的核心痛点

手动管理技能目录很麻烦:你得知道技能该放哪、怎么让 agent 发现它、更新时怎么同步。skills CLI 就是把这些操作命令化。常见的子命令大概包括:

命令作用典型场景
skills list列出已安装技能查看当前有哪些能力可用
skills add <name>安装某个技能从仓库拉取技能到本地
skills remove <name>卸载技能清理不再需要的技能
skills update更新技能到最新版同步上游改进
skills init初始化技能目录新项目接入时用

这些命令的具体名称和参数,不同实现会有差异,但思路是一致的:让技能的安装、更新、发现变成一条命令的事。

4.2 技能装到哪里,agent 怎么找到它

这是最容易踩坑的地方。技能文件必须放在 agent 能扫描到的路径下。以 Claude Code 这类工具为例,它通常会在项目根目录或用户主目录下寻找特定名称的配置目录。如果技能放错位置,agent 就是"看不见"。

我的建议是:优先放在项目级目录,而不是全局目录。原因很简单,不同项目的技术栈和规范不一样。A 项目用 pytest,B 项目用 jest,你把两套测试技能都塞进全局目录,agent 反而会混乱。项目级技能跟着代码走,团队里每个人 clone 下来就有一致的体验。

具体路径上,常见做法是在项目根目录建一个约定的隐藏目录(比如.agent/skills/或类似名称),然后在 agent 的配置文件里指向它。这一步一定要对着你所用工具的官方文档确认,因为不同版本可能改过默认路径。

4.3 用 CLI 做技能版本管理

技能也是代码,也会迭代。今天写的 TDD 技能可能漏了"测试失败时的处理",明天就得补上。如果团队多人维护,没有版本管理会乱套。

CLI 工具通常会配合一个清单文件(类似package.json或skills.lock),记录每个技能的来源和版本。这样skills update时能精确拉到指定版本,而不是每次都拿最新的(最新版可能引入了不兼容的改动)。这一点和依赖管理是一个道理,别嫌麻烦。

5. 以 TDD 技能为例,拆解一个技能该怎么写

5.1 为什么 TDD 是 agent 技能的"试金石"

在所有候选技能里,测试驱动开发最能检验一个 agent 技能体系是否合格。原因有三:第一,TDD 有严格的步骤顺序,任何一步跳过都会破坏整个流程;第二,它需要 agent 真正运行命令、读取输出、根据结果决策,而不是纯文本生成;第三,它有明确的成功判据——测试从红到绿。

如果 agent 能在 TDD 技能约束下稳定工作,说明这套技能机制是有效的。反过来,如果连 TDD 都跑不顺,那其他更复杂的技能基本也别指望。

5.2 TDD 技能的步骤设计

一个可用的 TDD 技能,步骤应该写得足够具体,具体到 agent 不需要"发挥":

  1. 确认需求边界:把用户的需求转写成一条可验证的行为描述。比如"用户输入非法邮箱时,注册接口返回 400"。
  2. 定位测试文件:根据项目约定,找到或创建对应的测试文件。这一步要明确告诉 agent 测试文件放在哪、命名规则是什么。
  3. 写失败测试:只写测试,不写实现。测试要能表达预期行为。
  4. 运行测试并确认失败:这一步不能省。很多 agent 会"假设"测试失败了就直接写实现,结果测试其实因为语法错误而失败,根本没测到逻辑。
  5. 写最小实现:只写让测试通过的最少代码,不要提前优化。
  6. 运行测试确认通过:看到绿灯才算这一步完成。
  7. 重构:在测试保护下清理代码。
  8. 回归:跑一遍全部测试,确认没破坏别的功能。

5.3 让 agent 真正"运行"测试,而不是"想象"结果

这是实操中最关键的一点。agent 必须被明确要求:每一步都要实际执行命令,并把真实输出作为判断依据。我在项目里见过 agent 声称"测试已通过",结果一查根本没运行,它只是根据代码逻辑"推断"应该通过。

解决办法是在技能文件里写死命令,比如"运行npm test -- <测试文件路径>,读取退出码,退出码为 0 才视为通过"。把判断标准绑定到可观测的信号上,而不是 agent 的自我陈述。

注意:如果你的 agent 环境不允许直接执行终端命令,TDD 技能基本无法完整落地。执行能力是这类技能的前提,配置环境时务必先确认这一点。

5.4 一个 TDD 技能描述文件的骨架

# Skill: test-driven-development ## 触发条件 当用户要求实现新功能、修复 bug,且项目已配置测试框架时启用。 ## 前置检查 - 确认测试命令(读取 package.json / pyproject.toml) - 确认测试文件目录约定 ## 步骤 1. 将需求转写为一条可验证的行为描述 2. 创建或定位测试文件 3. 编写失败测试 4. 执行测试,确认失败原因是"功能未实现"而非语法错误 5. 编写最小实现 6. 执行测试,确认通过 7. 重构,保持测试通过 8. 运行全量测试 ## 完成标准 - 新增测试覆盖新行为 - 全量测试通过 - 无跳过的测试 ## 反例 - 不要先写实现再补测试 - 不要在测试未确认失败前写实现 - 不要用 mock 掩盖真实逻辑

这个骨架可以直接改成你项目里的版本。重点是步骤要可执行、判据要可观测。

6. 接入不同模型时,技能体系会遇到什么

6.1 模型能力差异对技能执行的影响

热搜词里出现了不少关于接入第三方模型的讨论。这里有个现实问题:技能体系对模型的"指令遵循能力"和"工具调用能力"要求很高。同一个 TDD 技能,在指令遵循强的模型上能一步步走完,在弱一些的模型上可能第三步就开始偷懒——跳过"确认失败"直接写实现。

我的经验是:技能越结构化,对模型能力的依赖越低。因为结构化技能把"该做什么"写死了,模型只需要按部就班执行,不需要自己规划。所以如果你用的是能力一般的模型,反而更应该把技能写得细,而不是指望模型自己聪明。

6.2 工具调用是硬门槛

TDD 技能要求 agent 能执行命令、读文件、写文件。如果接入的模型或客户端不支持工具调用(function calling / tool use),那这套技能就只能"纸上谈兵"。选模型时,工具调用支持是比"代码写得好不好"更前置的指标。

6.3 上下文长度与技能加载策略

技能多了以后,不可能全部塞进上下文。合理的做法是:agent 先读一个技能索引(只有名称和一句话描述),判断当前任务需要哪个技能,再加载那个技能的完整内容。这种"按需加载"策略能显著降低上下文压力,也让 agent 的注意力更集中。

如果你的工具支持,可以在技能索引里加上关键词,让匹配更精准。比如 TDD 技能的关键词是"测试、TDD、红绿重构、单元测试",当用户提到这些词时优先加载。

7. 落地一套 agent-skills 的完整流程

7.1 从最小可用集合开始

不要一上来就写二十个技能。我的建议是先做三个:测试驱动开发、代码审查、提交规范。这三个覆盖了日常开发最高频的场景,也最容易验证效果。跑顺了再扩展。

7.2 每个技能都要有"验收测试"

技能本身也需要测试。怎么测?拿一个真实的小任务,让 agent 在技能约束下完成,观察它是否按步骤走、是否在关键节点做了正确判断。如果它跳步了,说明技能描述有歧义,回去改。

我一般会准备几个"标准任务"作为回归用例:一个需要写测试的功能、一个需要修 bug 的场景、一个需要重构的模块。每次改完技能,用这几个任务跑一遍,看行为是否稳定。

7.3 团队协作中的技能维护

技能是团队资产,不是个人玩具。建议把技能仓库纳入代码评审流程:谁改了技能,要说明改的原因,最好附上改动前后的行为对比。这样能避免技能被随意改坏。

另外,技能描述里涉及项目约定的部分(比如测试目录、命名规范),最好从项目配置文件里读取,而不是硬编码。这样换项目时技能还能复用。

7.4 常见问题排查表

现象可能原因排查方向
agent 不加载技能路径不对 / 索引未更新检查技能目录位置和索引文件
技能加载了但不执行触发条件写得太窄放宽触发条件,补充关键词
执行到一半跳步步骤描述有歧义把步骤拆得更细,加明确判据
声称完成但实际没做缺少可观测的完成标准绑定到命令退出码或文件状态
多个技能冲突触发条件重叠明确优先级或合并技能

8. 我在实操中踩过的几个坑

第一个坑是技能写得像文档。我一开始把 TDD 技能写成了一篇讲 TDD 原理的文章,结果 agent 读完还是不知道具体该敲什么命令。后来改成"步骤 + 命令 + 判据"的结构,效果立刻不一样。技能是给机器执行的,不是给人阅读的,这个定位要摆正。

第二个坑是忽略了测试框架的差异。同一个 TDD 技能,在 jest 项目和 pytest 项目里,运行命令、断言写法、文件命名都不一样。我最初的技能硬编码了 jest 的命令,换到 Python 项目就废了。后来改成从项目配置里探测测试命令,通用性好了很多。

第三个坑是过度依赖 agent 的自我报告。有次 agent 说"所有测试通过",我信了,结果提交后 CI 挂了。从那以后,我在技能里强制要求 agent 输出真实的命令和输出片段,而不是一句"通过了"。可观测性这东西,在 AI 辅助开发里比在人写代码时更重要。

第四个坑是技能更新没有版本控制。团队里两个人同时改同一个技能,合并时冲突一堆。后来我们约定技能改动走 PR,并且给技能文件加了版本号,才稳定下来。

9. 技能体系还能往哪些方向扩展

跑通基础技能后,可以往几个方向延伸。一是领域技能,比如针对特定框架(React、Django)的最佳实践技能;二是流程技能,比如发布流程、回滚流程;三是质量技能,比如性能检查、安全检查。

还有一个有意思的方向是技能的组合编排。当技能足够多时,可以定义一个"元技能",描述一个完整任务需要哪些技能、按什么顺序执行。这相当于给 agent 装了一个"项目级工作流引擎"。

不过要提醒一句:技能不是越多越好。每多一个技能,agent 的判断负担就多一分。保持精简、保持每个技能职责单一,比堆数量重要得多。我自己维护的技能集合一直控制在十个以内,够用就行。

最后分享一个我常用的检验方法:把技能描述拿给一个不熟悉项目的同事看,如果他看完能照着做出来,说明这个技能写得够清楚;如果他自己都看不懂,agent 大概率也执行不好。技能的可读性,某种程度上就是它的可执行性。

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

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

立即咨询