Agent Harness深度专题:Skills编写方法论、目录模板与实战踩坑
很多同学配置完一整套Rules之后发现:AI 知道代码长什么样,但不知道完整工序,经常一步试图完成多件事,出现漏步骤、跳过校验、输出半成品代码。
Skills就是用来解决这个问题:它是一套原子化可复用的执行工序包,告诉Agent“完成某一类具体任务的完整操作步骤、模板、验收标准”。
本文基于Cursor真实工程模板,结合后端开发落地经验,讲清楚Skills的作用域、目录结构、编写模板、和Rules的边界,同时梳理大量生产环境踩坑点,同样对比Cursor、Qoder的差异。
一、Skills到底是什么,和Rules边界如何划分
很多人落地Harness,最容易混淆Rules与Skills,写着写着把执行步骤塞进Rules,或者把编码规范写进Skills,整个体系职责混乱。
简单直白区分:
- Rules:约束契约,回答「做成什么样子,什么不能做」,只讲结果标准,不描述操作步骤。常驻上下文,只要满足触发条件就生效。
- Skills:工序能力包,回答「这件事具体怎么做,分哪几步,模板是什么,做完如何自检」,按需动态加载,任务结束就释放,不长期占用token。
举后端开发实际例子:
Rules写:Controller禁止直接调用Mapper,必须经过Service层;统一返回JsonData。
Skills写:生成 Controller、Request、VO 接口代码的完整步骤,读取哪些模板,生成完成之后做哪些自检。
Skills分为两个作用域:用户级Skills、项目级Skills。
用户级Skills
- Cursor存放路径:IDE设置内Stills面板,账号同步;~/.cursor/skills/;Qoder:~/.qoder/skills/
- 保存在本机,不要提交Git
- 适用场景:个人通用能力,例如日志分析、简单脚本处理,所有项目都可以调用。
- 禁止:存放当前业务项目专属工序,避免切换项目被错误调用。
项目级Skills(团队最常用)
- Cursor存放路径:.cursor/skills/;Qoder存放路径:.qoder/skills/
- ✅必须提交Git,团队所有成员共享同一套工序
- 适用场景:当前项目业务工序,例如建表生成DO、生成Controller接口、bug修复流程、接口测试流程。
关键特性:Skills是按需加载。Agent判断当前任务匹配Skill描述,才会把Skill完整内容读入上下文;任务结束自动释放,不会像Rules那样全程常驻,减少token消耗。
二、Cursor与Qoder的Skills目录格式差异
Cursor Skill目录规范
每一个Skill是独立文件夹,文件夹名就是skill名称,和SKILL.md中的name字段保持一致。
核心主文件是SKILL.md,支持YAML frontmatter元数据。可选配套目录存放模板、脚本、参考文档。
.cursor/skills/create-table/
├── SKILL.md # 【必填】Skill主文件,元数据、使用时机、执行步骤、自检规则
├── assets/ # 【可选】存放模板文件 templates.md,SQL模板、代码骨架
├── scripts/ # 【可选】可执行脚本,校验脚本、预处理脚本
└── references/ # 【可选】补充参考文档,不会默认加载,按需引用
Qoder Skill目录规范
整体逻辑和Cursor对齐,目录为.qoder/skills/,同样每个Skill独立文件夹,主文件SKILL.md,frontmatter元数据字段基本兼容,目录结构完全通用。
区别点:部分元数据字段存在小差异,不支持部分Cursor专属hook配置。
最佳实践:写Skill尽量使用通用字段,不要写平台私有能力,方便后续在Cursor、Qoder之间迁移项目。
调用入口:斜杠命令
项目配置完成后,对话窗口可以直接斜杠唤起,例如/create-table,直接触发该Skill,不需要大模型自主判断。Agent编排的时候,内部也可以自动引用对应Skill。
三、Skill编写方法论:坚持原子化,拒绝大而全
核心原则:一个Skill,只干一件事
这是编写Skill第一铁律。
❌反面案例:一个叫full-dev的Skill,里面把建表、生成DO、Service、Controller、写测试全部塞进去。
问题:任务粒度巨大,中间任意一步出错,全部流程卡死;部分场景我只想要生成Mapper,不需要写Controller,无法单独复用。
✅正确拆分(参考示例模板)
- create-proposal:只做需求分析、方案设计、技术选型
- create‑table:只做建表SQL
- create‑model:只生成DO + Mapper
- create‑service:只生成Service层代码
- create‑api:只生成Controller、Request、VO
- create‑apidoc:只输出接口文档
- test‑api:只做接口测试
- create‑bugfix:缺陷修复工序
- query-db:只生成查询数据库的SQL语句
- mock-db-data:只生成插入数据库的模拟数据SQL语句
每个Skill只负责单一垂直环节;复杂完整业务,交给上层Agent编排,由Agent按顺序依次调用多个原子Skill,不要在Skill内部做跨阶段大流程。
SKILL.md标准结构
name必须和文件夹同名;description非常关键,Agent靠description判断要不要加载这个Skill,要写清楚:能干什么、什么场景触发。
一份可直接复制的SKILL.md实战模板
文件路径:.cursor/skills/create‑table/SKILL.md
—
name: create-table
description: 按照项目规范生成MySQL建表、改表DDL语句。用于新增业务数据表,变更表字段。
Use when: 需要新建业务表、增加字段、修改索引;不要用于写业务代码。
—
# create‑table 建表Skill
## 使用时机
– 需要新增业务数据表
– 需要给现有表新增字段、调整索引
### 禁止使用场景
– 不用于生成Java业务代码;写DO、Mapper请调用create‑model。
## 执行步骤
1. 读取项目AGENT.mdc总图,确认数据库公共字段规范(ID、DEL、CREATE_TIME、UPDATE_TIME)。
2. 接收业务表信息:中文表名、英文表名、字段清单、索引需求。
3. 套用assets/templates.md里面的DDL模板生成SQL。
4. 检查表是否包含公共审计字段;逻辑删除字段DEL是否存在。
5. 生成完成,输出完整DDL,不自动执行SQL,等待用户确认。
## 自检清单(全部必须检查)
1. 表名全部大写,符合项目数据库命名约定。
2. 必须带上公共列 ID、DEL、CREATE_TIME、UPDATE_TIME。
3. 字段非空、默认值设置符合业务描述。
4. 索引定义完整,无重复索引。
## 退出条件
如果用户没有提供完整字段清单,立刻停止执行,向用户收集信息,不要自行脑补字段。
配套模板放到./assets/templates.md,不要全部堆在SKILL.md正文,避免主文件过于臃肿。
四、Skill和Agent如何分工
Skill只定义单一任务的工序和自检;Skill内部不要做任务拆解、不要做多Skill编排。
多步骤串联,交给Agent来完成。
比如develop‑agent接收“新增一张业务表”需求,它的工作就是:依次调用create‑table → create‑model → create‑service → create‑api。
- Skill:“做这件事的步骤和检查项”
- Agent:“我现在要做一个大需求,依次调用哪几个Skill,处理中间异常,汇总最终结果”
五、高频踩坑避坑清单(实战踩过的问题)
坑1:Skill写的太臃肿,多个业务动作塞进同一个Skill
现象:一个Skill里面包含建表、生成代码、写测试全套。
后果:无法复用,中间任意一步异常整个流程崩坏。
解决:坚持原子化,一Skill一职责;多工序交给上层Agent编排。
坑2:description写的模糊笼统,Agent不会自动触发
错误描述:用来处理数据库相关。
正确描述:生成MySQL建表、改表DDL语句,用于新增业务数据表,变更表字段。
说明:Agent依靠description匹配任务,如果描述模糊,不会主动加载,只能手动斜杠调用。
坑3:把Rules约束写进Skill步骤
错误:在Skill步骤重复写“Controller禁止直接调用Mapper”这类规范。
解决:编码规范交给Rules,Skill只写执行工序、自检;自检可以引用Rules,不要重复抄写大段规则文本。
坑4:模板全部内联写在SKILL.md正文
现象:几百行SQL模板、Java代码模板全部粘贴在SKILL.md。
后果:SKILL.md膨胀,阅读维护困难;多Skill需要复用模板时无法共享。
解决:模板统一放到assets/templates.md,Skill内部引用路径。
坑5:缺少自检清单,Skill执行完直接标记完成
现象:Skill跑完步骤就结束,不做任何结果校验,输出半成品。
解决:每个Skill末尾必须增加Self‑Check自检清单,明确必须校验的条目,不通过不能标记完成。
坑6:缺少退出条件,信息不全还强行脑补执行
现象:用户没有提供完整字段,Skill自己脑补字段继续往下生成。
解决:写明Exit Condition,关键输入缺失立刻终止,向用户收集信息,禁止脑补业务。
坑7:把用户级Skill混入项目skills目录提交Git
现象:把个人调试脚本、个人习惯的Skill提交进仓库。
后果:团队其他成员不需要该能力,容易被误触发。
解决:项目专属工序放项目skills目录提交Git;个人通用能力放在本机用户skills目录,不提交版本库。
坑8:Skill内部做复杂任务编排,在Skill里面调用其他Skill
现象:在create‑table的Skill步骤里面写:完成之后调用create‑model。
后果:职责混乱,Skill变成小型Agent,失去原子复用能力。
解决:Skill只负责自身任务;跨Skill串联交给上层Agent。
坑9:忽略兼容性,大量使用某一个IDE私有hook语法
现象:大量写Cursor专属hooks配置,直接复制到Qoder直接报错失效。
解决:核心流程只使用通用SKILL.md语法,平台私有能力做备注,不要作为主流程依赖。
六、完整落地工作流
例如:建表、生成DO/Mapper、生成Service、生成Controller、写接口文档、缺陷修复、接口测试。
七、总结
Rules定义标准,Skills定义工序,Agents负责编排调度,三者各司其职。
再重申一遍边界:Rules管输出长什么样;Skills管这件事怎么做;Agents管什么时候调用哪个Skill。


