news 2026/10/28 12:57:53

agent-skills 实战:用 TDD 技能包约束 AI coding agent 行为

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
agent-skills 实战:用 TDD 技能包约束 AI coding agent 行为

1. agent-skills 到底在解决什么问题

第一次看到agent-skills这个词,很多人会以为是某个新出的 AI 模型或者框架。其实它更接近一个"能力包"的概念——把 AI coding agent 需要掌握的技能,用结构化的方式组织起来,让 agent 在特定任务上表现得更稳定、更可控。

我最初接触这个概念是在折腾 Claude Code 的时候。当时遇到一个很实际的问题:默认状态下,Claude Code 能写代码、能改文件、能跑命令,但它在某些特定任务上的表现忽好忽坏。比如让它写测试,有时候它会先写实现再补测试,有时候干脆跳过测试直接给实现。这种不确定性在个人玩票时无所谓,但一旦放到真实项目里,就是灾难。

agent-skills要解决的核心问题就是这个:把"希望 agent 怎么做"变成"规定 agent 必须怎么做"。它通过一套约定好的目录结构和文件格式,把特定领域的知识、流程、约束条件打包成 skill,agent 在执行任务时会自动加载相关 skill,按照里面定义的步骤和规则来工作。

关键词里提到的test-driven-development就是一个典型的 skill 场景。TDD 的流程是固定的:先写测试,测试失败,再写实现,测试通过,重构。这个流程如果靠 prompt 里每次提醒,既啰嗦又不可靠。但把它做成一个 skill,agent 在检测到"写新功能"这类任务时就会自动套用 TDD 流程,不需要人反复强调。

从更宏观的视角看,agent-skills代表了一种趋势:AI coding agent 正在从"通用助手"向"专业化工具"演进。通用助手什么都能聊,但什么都不精;专业化工具在特定场景下表现远超通用助手。skills 就是实现这种专业化的手段之一。

适合读这篇内容的人大概分三类:一是已经在用 Claude Code 或其他 AI coding agent,想让它更听话的开发者;二是团队里在推 AI 辅助开发,需要标准化流程的技术负责人;三是对 agent 架构感兴趣,想了解 skill 机制怎么设计的技术爱好者。不管哪一类,理解agent-skills的工作方式都有实际价值。

2. skills 的目录结构与加载机制

2.1 一个 skill 长什么样

agent-skills的核心是约定优于配置。一个 skill 本质上就是一个文件夹,里面放一个SKILL.md文件,再加上可选的辅助文件。目录结构大概是这样:

skills/ test-driven-development/ SKILL.md examples/ example-test.md templates/ test-template.md code-review/ SKILL.md

SKILL.md是整个 skill 的入口,它用 YAML frontmatter 定义元信息,用 Markdown 正文描述具体内容。一个典型的SKILL.md开头是这样的:

--- name: test-driven-development description: 当需要实现新功能或修复 bug 时,按照 TDD 流程编写测试和实现 ---

name是 skill 的唯一标识,description是关键——agent 会根据这个描述判断当前任务是否需要加载这个 skill。所以 description 写得准不准,直接决定了 skill 会不会在正确的时机被触发。

正文部分就是具体的指令。可以写流程步骤、可以写约束条件、可以写示例代码。Markdown 的好处是 agent 读起来自然,人读起来也清楚。

2.2 skill 是怎么被加载的

这里涉及一个很多人会忽略的细节:skill 不是一次性全部加载的。如果所有 skill 的内容都塞进 context,token 消耗会爆炸,而且 agent 的注意力会被分散。

实际的工作方式是渐进式加载。agent 启动时只读取所有 skill 的name和description,形成一个轻量的索引。当用户提出一个任务时,agent 拿任务描述去匹配这些 description,匹配上的 skill 才会被完整加载。

这个机制解释了一个常见困惑:为什么我写了一个很详细的 skill,但 agent 好像没用上?大概率是 description 没写好,匹配阶段就没被选中。description 要写得像"触发条件"而不是"功能说明"。比如写"当需要实现新功能时使用"就比写"这是一个 TDD 技能"要好得多。

2.3 为什么用 Markdown 而不是 JSON 或代码

有人会问,为什么 skill 用 Markdown 而不是结构化的 JSON 或者 Python 代码?我自己的理解是三个原因。

第一,Markdown 对 LLM 最友好。LLM 的训练数据里 Markdown 占比极高,它对 Markdown 的结构理解得最透彻。用 JSON 写指令,agent 反而容易在嵌套结构里迷失。

第二,人机双读。skill 不只是给 agent 看的,也是给人看的。团队里新来的同学想知道 TDD 流程怎么走,直接打开SKILL.md就能看懂,不需要额外的文档。

第三,修改成本低。改一个流程步骤,直接编辑 Markdown 就行,不需要动代码、不需要重新编译、不需要跑测试。这种低摩擦的迭代方式,让 skill 能快速演进。

提示:如果你的 skill 里需要包含代码示例,建议用代码块标注语言类型。agent 对带语言标注的代码块理解更准确,不容易把示例代码和实际要执行的代码搞混。

3. 从零写一个 TDD skill 的完整过程

3.1 先想清楚要约束什么

写 skill 之前,先别急着打开编辑器。我踩过的坑是:一上来就写,结果写出来的东西又长又乱,agent 根本抓不住重点。

正确的做法是先问自己:这个 skill 要解决的核心问题是什么?以 TDD 为例,核心问题是"agent 倾向于跳过测试直接写实现"。那 skill 的目标就是强制它先写测试。

接下来列出具体的约束点:

  • 必须先写测试,测试要能运行且失败
  • 测试失败后才能写实现
  • 实现要让测试通过,不能改测试来迁就实现
  • 通过后要检查是否有重构空间

这四个点就是 skill 的骨架。其他的细节都是围绕这四点展开的。

3.2 写 description 的讲究

description 是 skill 的"广告词",它的任务是让 agent 在正确的时机选中这个 skill。写的时候要注意几个点。

用触发场景而不是功能描述。对比一下:

  • 差的写法:这是一个测试驱动开发技能
  • 好的写法:当需要实现新功能、修复 bug 或重构代码时,使用此技能确保先写测试

好的写法里包含了"实现新功能""修复 bug""重构代码"这些具体场景词,agent 匹配任务时更容易命中。

控制长度。description 太长会稀释关键词的权重,太短又覆盖不全场景。我的经验是控制在 50 到 100 字之间,把最核心的触发场景说清楚就行。

避免歧义。不要用"可能""也许"这类模糊词。skill 的触发应该是确定的,模糊的描述会让 agent 在该用和不该用之间摇摆。

3.3 正文的写法:流程 + 约束 + 示例

正文部分我习惯分三块写:流程、约束、示例。

流程部分用有序列表,把步骤写清楚:

## 流程 1. 阅读需求,理解要实现的功能 2. 编写测试用例,覆盖正常路径和边界情况 3. 运行测试,确认测试失败(红) 4. 编写最小实现,让测试通过(绿) 5. 检查代码,消除重复和坏味道(重构) 6. 重复 2-5 直到功能完成

约束部分用无序列表,把红线标出来:

## 约束 - 禁止在测试通过前编写实现代码 - 禁止修改测试来让实现通过 - 每次只实现一个测试用例对应的功能 - 测试必须能独立运行,不依赖执行顺序

示例部分给一段具体的代码,让 agent 有参照:

# 先写测试 def test_add_two_numbers(): assert add(1, 2) == 3 # 运行,确认失败 # 再写实现 def add(a, b): return a + b

这三块写下来,一个 skill 的正文大概在 300 到 500 字。太短了约束不够,太长了 agent 抓不住重点。

3.4 实测中的意外情况

写完第一个版本后,我拿几个真实任务测了一下,发现了几个问题。

问题一:agent 有时候会"假装"跑了测试。它会在回复里写"测试失败,符合预期",但实际上根本没执行测试命令。解决办法是在 skill 里明确要求"必须实际执行测试命令,并展示命令输出"。

问题二:agent 会在测试失败后直接改测试。比如测试期望add(1,2)==3,实现返回了 4,它不去改实现,反而把测试改成add(1,2)==4。这个行为很隐蔽,需要在约束里明确禁止。

问题三:skill 加载了但没生效。排查后发现是 description 写得太泛,agent 匹配到了但觉得"这个任务不需要严格走 TDD",就跳过了。后来把 description 改得更具体,问题就解决了。

这些意外情况说明一件事:skill 不是写完就完事,需要在实际使用中不断调优。第一版能覆盖 70% 的场景就不错了,剩下的 30% 靠迭代补上。

4. skill 与 Claude Code 的配合方式

4.1 Claude Code 怎么发现 skill

Claude Code 默认会扫描项目根目录下的skills/文件夹,也会扫描用户主目录下的配置目录。项目级的 skill 优先级高于用户级的,这样团队可以有自己的 skill 集,个人也可以有自己的偏好 skill。

如果你把 skill 放在非标准位置,需要在配置里显式指定路径。这个配置通常在项目的.claude/目录下,具体文件名和格式随版本变化,建议以官方文档为准。

4.2 什么时候 skill 会被触发

触发时机分两种:自动触发和手动触发。

自动触发就是前面说的 description 匹配。用户提出任务,agent 判断是否需要加载某个 skill。这种方式的好处是无感,用户不需要知道 skill 的存在。

手动触发是用户在对话里明确要求使用某个 skill。比如直接说"用 TDD 流程实现这个功能"。这种方式适合用户想强制走某个流程的场景。

两种方式可以结合。日常开发靠自动触发,关键任务靠手动触发兜底。

4.3 skill 和 CLAUDE.md 的区别

很多人会混淆 skill 和CLAUDE.md。两者都是给 agent 的指令,但定位不同。

CLAUDE.md是项目级的全局指令,每次对话都会加载。它适合放项目的整体约定,比如代码风格、目录结构、常用命令。

skill 是任务级的指令,只在相关任务时加载。它适合放特定场景的流程,比如 TDD、代码审查、发布流程。

打个比方,CLAUDE.md是员工手册,skill 是具体工种的作业指导书。员工手册人人要看,作业指导书只在干那个活的时候才翻。

注意:不要把该放 skill 的内容塞进CLAUDE.md。CLAUDE.md每次对话都加载,塞太多东西会挤占 context,反而让 agent 抓不住重点。

4.4 多 skill 协作的场景

真实项目里往往需要多个 skill 配合。比如实现一个新功能,可能涉及 TDD skill、代码审查 skill、提交信息规范 skill。

这时候要注意 skill 之间的边界。每个 skill 管好自己的事,不要越界。TDD skill 只管测试和实现的顺序,不管代码风格;代码审查 skill 只管审查标准,不管测试怎么写。

如果两个 skill 的职责有重叠,agent 可能会困惑该听谁的。解决办法是在 description 里把触发场景区分清楚,或者在 skill 正文里明确说明"本 skill 不负责 XX,请参考 XX skill"。

5. 让 skill 真正落地的几个关键细节

5.1 description 的迭代比正文更重要

我自己的经验是,skill 写完后,80% 的调优时间花在 description 上。正文写得再好,description 匹配不上就是白搭。

调优 description 的方法很简单:拿一批真实任务,看 agent 有没有在正确的时机加载 skill。没加载的,分析任务描述和 description 的差距,把缺失的场景词补进去。加载了但不该加载的,把过于宽泛的词删掉。

这个过程需要反复几轮,但每轮都能明显提升命中率。

5.2 用示例锚定 agent 的行为

LLM 对示例的敏感度远高于对规则描述的敏感度。与其写十条"不要这样做",不如给一个"应该这样做"的示例。

在 skill 里放示例时,要注意示例的代表性。选最典型的场景,不要选边角案例。示例代码要能直接运行,不要有伪代码。

如果 skill 涉及多种情况,可以给多个示例,但要标注清楚每个示例对应的场景。比如"场景 A:新增功能"下面放一个示例,"场景 B:修复 bug"下面放另一个。

5.3 版本管理和团队协作

skill 是团队资产,应该纳入版本管理。放在项目仓库里,跟着代码一起提交、一起 review。

团队协作时要注意几点。一是 skill 的修改要经过 review,不能随便改,因为改了会影响所有人的 agent 行为。二是 skill 要有变更记录,说明每次改了什么、为什么改。三是新 skill 上线前要在小范围试用,确认没问题再推广。

我见过一个团队把 skill 当草稿纸用,谁想改就改,结果 agent 的行为越来越不可预测。后来他们引入了 review 流程,情况才好转。

5.4 常见问题排查表

现象可能原因排查方向
skill 完全没被加载description 不匹配检查 description 是否包含任务关键词
skill 加载了但行为没变正文指令不够明确检查是否有明确的流程和约束
agent 部分遵守 skill约束之间有冲突检查 skill 内部和 skill 之间是否矛盾
skill 加载过于频繁description 太宽泛收窄 description 的触发场景
多个 skill 同时加载导致混乱职责边界不清明确各 skill 的职责范围

这张表是我在实际使用中总结的,大部分问题都能对应上。遇到新问题时,先往这几个方向排查,通常能快速定位。

6. 关于 agent-skills 的一些个人体会

用了一段时间agent-skills之后,我最大的感受是:它把 prompt engineering 从"一次性技巧"变成了"可积累的资产"。

以前调 prompt,调好了存在某个笔记里,下次用的时候再翻出来复制粘贴。这种方式的问题是,经验散落在各处,没法沉淀,没法复用,没法协作。

skill 机制改变了这一点。每个 skill 都是一个独立的、可版本管理的、可复用的单元。写得好就留着,写得不好就改,改好了团队都能用。这种积累效应,时间越长价值越大。

另一个体会是,skill 的粒度很关键。太粗了,一个 skill 管太多事,agent 抓不住重点;太细了,skill 数量爆炸,匹配阶段就容易出错。我的经验是,一个 skill 对应一个明确的流程或一类明确的任务,不要贪多。

最后说一个实际的小技巧。如果你不确定某个 skill 该不该拆,可以先写成一个,用一段时间,等发现里面确实有两块相对独立的内容时再拆。过早拆分反而会增加维护成本。

agent-skills这个方向还在快速演进,现在的做法过几个月可能就过时了。但底层的思路——把 agent 的能力模块化、可配置化、可积累化——应该是长期有效的。抓住这个思路,具体的实现方式怎么变都能跟上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 12:57:24

impeccable:AI编程助手前端设计质量层实战指南

1. 从"impeccable"这个词说起:一个前端设计工具链的野心第一次看到"impeccable"这个词被用作项目名,我的反应是:这名字起得够狂。"无可挑剔"——一个前端设计工具敢叫这个名字,要么是噱头&#xff…

作者头像 李华
网站建设 2026/10/28 12:57:24

ponytail 插件化任务编排:skill 声明式自动化实践指南

1. 从“ponytail”这个热词说起:它到底是什么第一次看到“ponytail”这个词被顶上热搜,我其实是有点懵的。马尾辫?这不是个发型词吗,怎么突然跟“skill”“插件”这些技术圈的黑话搅在一起了。后来花了两天时间把相关的讨论、仓库…

作者头像 李华
网站建设 2026/10/28 12:56:16

基于.NET的实验室管理信息系统设计与实现

1. 项目背景与核心需求实验室管理信息系统(LMIS)是高校和科研机构信息化建设的重要组成部分。传统实验室管理普遍存在以下痛点:设备台账混乱、预约流程繁琐、耗材管理低效、数据统计滞后。这些问题在高校扩招和科研项目增多的背景下愈发突出。…

作者头像 李华
网站建设 2026/10/28 12:56:09

Linux三剑客grep、sed、awk核心用法与实战技巧

1. Linux三剑客:grep、sed、awk核心解析在Linux系统管理和文本处理领域,grep、sed、awk这三个工具被并称为"三剑客"。它们各自拥有独特的功能定位,组合使用能解决90%以上的文本处理需求。作为从业15年的Linux系统工程师&#xff0c…

作者头像 李华
网站建设 2026/10/28 12:55:28

SQL注入实战:sqli-labs-Less-5靶场解析与防御

1. sqli-labs-Less-5靶场环境解析Less-5是sqli-labs靶场中经典的基于错误的单引号字符型注入场景。这个关卡的特殊性在于它不会直接返回查询结果,而是通过报错信息或布尔盲注的方式泄露数据。实际测试时,页面仅返回"You are in..."的固定提示&…

作者头像 李华
网站建设 2026/10/28 12:55:22

AI Agent技能包(skills)设计指南:从原理到团队落地实践

1. 从“skills”这个词说起:它到底在解决什么问题第一次看到“skills”这个标题,很多人会以为是某个泛泛的能力清单,或者招聘网站上的技能标签。但如果你最近在折腾 Claude Code、Codex、Cursor 这类 AI 编程工具,就会发现“skill…

作者头像 李华