手把手书写你的第一个 AI Skill:从原则到工程化

1 阅读16分钟

手把手书写你的第一个 AI Skill:从原则到工程化

前端 AI Skill 体系 · 入门篇

Vercel 的 writing-guidelines Skill 被安装了 32,500 次。GitHub 官方的 create-agentsmd 被安装了 11,800 次。这不是玩具——这是 2026 年 AI 编程的基础设施。


目录


先说结论

Skill = 一份 Markdown 文件,告诉 AI "什么时候用你、怎么干活、什么不能做"。

它不是 Prompt。Prompt 是一次性的对话。Skill 是持久化的职业 SOP——写一次,每次对话自动生效。

Cursor 叫它 .cursor/rules/*.mdc,Claude Code 叫它 CLAUDE.md,GitHub 叫它 AGENTS.md,skills.sh 叫它 SKILL.md。名字不同,本质相同。

本文教你从零写一个,然后把它工程化。


一、原则:写之前必须知道的 6 件事

1.1 触发条件决定生死

AI 不会"主动发现"你的 Skill。它靠 description 里的关键词 判断是否加载。

# ✅ 精准触发
description: |
  Load when user says "日报" / "standup" / "今天做了什么".
  Generate structured daily report from git commits.

# ❌ 模糊到等于没写
description: |
  A helpful skill for various tasks.

实测体感:触发词覆盖 3 种以上表达方式时,命中率从 40% 提升到 90%+。用户说"CR"、"review"、"帮我看看代码"是同一个意图——你得全写上。

1.2 流程必须可执行

每一步都要有:输入 → 动作 → 输出

# ✅ 可执行
1. 读取 `git log --since="today" --oneline`
2. 按 feat/fix/refactor/docs 分类
3. 输出到 `reports/daily/YYYY-MM-DD.md`

# ❌ 不可执行
1. 分析今天的代码变更
2. 生成一份好的日报

"好的日报"不是输出规范。格式、位置、长度——都要写死。

1.3 约束分三级

级别含义示例
MUST铁律,违反即失败MUST: 所有组件使用 TypeScript strict
SHOULD强烈推荐,允许例外SHOULD: 优先使用已有知识库模式
MUST NOT绝对禁止MUST NOT: 不生成 any 类型

别把所有规则都标 MUST。10 条 MUST 互相冲突时,AI 会随机选一条遵守。

1.4 一个 Skill 只干一件事

想让它既写代码又写博客又做设计审查?拆成三个。

判断标准:如果 description 里出现"和"字,就该拆。

1.5 示例 > 描述

1 个精准示例的信息量 > 10 行文字描述。示例要覆盖:

  • 1 个正常路径(happy path)
  • 1 个边界情况(edge case)

1.6 写完不是终点

Skill 是活的。前两周每次用完回顾,发现 AI 没遵守的规则就改。稳定后每月 review 一次。

GitHub 官方 AGENTS.md 规范里原话:"This is living documentation - update it as your project evolves."

六大误区(踩坑清单)

误区真相
"description 写长点,AI 就能理解"description 是触发匹配用的,不是说明书。越精准越好
"把所有规则都写成 MUST"过多强制约束会让 AI 陷入冲突。区分 MUST 和 SHOULD
"一个 Skill 文件搞定一切"超过 200 行就该拆模块。上下文窗口是有限资源
"示例越多越好"1-2 个精准示例 > 10 个冗余示例
"写完就不用管了"Skill 需要迭代。用 2 周,根据实际效果修订
"AI 会自动知道什么时候用"不会。触发条件不写清楚,Skill 就是死文件

二、实战:15 分钟写一个日报生成器

2.1 完整代码

---
name: daily-standup
description: |
  Load when user says "日报" / "standup" / "今天做了什么" / "写日报".
  Generate a structured daily standup report from git commits.
metadata:
  author: your-name
  version: "1.0.0"
  layer: tool
  createdAt: "2026-07-23"
---

# daily-standup — 日报生成器

> 从 git log 自动生成结构化日报。不再手写"今天改了个 bug"。

## 触发条件

用户输入包含:日报 / standup / 今天做了什么 / 写日报 / daily

## 工作流

1. 执行 `git log --since="today 00:00" --oneline --author="$(git config user.name)"`
2. 如果无 commits → 输出"今天暂无提交记录"并询问是否手动补充
3. 按前缀分类:
   - feat: → ✨ 新功能
   - fix: → 🐛 修复
   - refactor: → ♻️ 重构
   - docs: → 📝 文档
   - 其他 → 🔧 杂项
4. 合并同类项(超过 10 条时)
5. 询问"明日计划"和"阻塞项"
6. 输出最终日报

## 输出格式

## 日报 YYYY-MM-DD(周X)

### 今日完成
- ✨ [feat] 用户注册接口联调
- 🐛 [fix] 修复登录页白屏(#1234)

### 明日计划
- (用户回答)

### 阻塞项
- (用户回答,无则写"无")

## 约束

- MUST: 只统计当天 commits,不跨天
- MUST: commit message 为英文时翻译为中文摘要
- SHOULD: 关联 issue 编号(如果 commit message 含 #数字)
- MUST NOT: 不编造不存在的 commit

2.2 逐行拆解

部分作用不写会怎样
name唯一标识无法被引用和管理
description 第一行触发匹配AI 不知道何时加载
metadata.version版本追踪改坏了不知道回滚到哪
触发条件章节人类可读的触发说明维护者(未来的你)看不懂
工作流步骤 2空结果兜底无 commits 时 AI 瞎编
输出格式锁定结构每次输出格式不同
MUST NOT防幻觉AI 可能虚构 commit

30 行。一个可用的 Skill。 存为 daily-standup/SKILL.md,完事。


三、复杂 Skill:当 30 行不够用时

3.1 什么时候该拆

  • SKILL.md 超过 200 行
  • 包含 3 个以上独立子流程
  • 需要 可变配置(注册表、规则表)
  • 需要 持久记忆(知识库)

3.2 真实目录结构

fe-hub(前端编排中枢,58KB SKILL.md,v1.5)为例:

fe-hub/
├── SKILL.md              # 入口(架构定位 + 路由表 + 模块索引)
├── README.md             # 人类说明(快速上手)
├── CHANGELOG.md          # 变更记录(what + why)
├── INSTALL.md            # 安装指南
├── manifest.json         # 机器可读元数据
│
├── modules/              # 🔑 模块化子流程(共 11 个,按需加载)
│   ├── workflow-recipes.md        # 常见任务标准流程
│   ├── input-security.md          # 输入安全校验
│   ├── error-recovery-log.md      # 错误恢复 + 日志
│   ├── session-tracking.md        # 多轮会话追踪
│   ├── token-metrics.md           # Token 用量度量
│   ├── usage-stats.md             # 使用统计
│   ├── knowledge-base.md          # 知识库检索
│   ├── community-skills-matrix.md # 社区 Skill 评估
│   ├── design-inspiration.md      # 设计灵感库
│   ├── extension-guide.md         # 扩展开发指南
│   └── plugin-packaging-guide.md  # 插件打包指南
│
├── config/               # 可变配置(与逻辑分离)
│   └── skill-registry.json  # 子 Skill 注册表
│
├── templates/            # 输出模板
├── tech-stacks/          # 各框架专属规则
├── bin/                  # 辅助脚本
├── stats/                # 运行统计
├── logs/                 # 运行日志
├── sessions/             # 会话持久化
├── reviews/              # 代码审查存档
└── docs/                 # 产出文档

3.3 复杂 Skill 的 5 条规则

#规则为什么
1SKILL.md ≤ 300 行,只放索引和路由AI 上下文窗口有限,全塞进去会稀释重点
2modules/ 一个文件一个子流程按需加载,不用的不占 token
3config/ 与逻辑分离改注册表不用动 SKILL.md
4manifest.json 必须有支撑自动化版本检测和依赖管理
5CHANGELOG.md 必须维护三个月后你会忘记为什么改了那行

3.4 入口文件怎么写(复杂版)

---
name: fe-hub
description: |
  Load when user starts any frontend development task.
  Orchestration hub: routes to the right fe-* Skill.
metadata:
  author: mjd
  version: "1.5.0"
  layer: orchestration
---

# fe-hub — 前端编排中枢

> 所有前端任务的统一入口。不干活,只调度。

## 路由表

| 用户意图 | 触发词 | 分发目标 |
|----------|--------|----------|
| 写组件/页面 | "组件/component/页面" | → fe-engineer-pack S3 |
| 写测试 | "测试/test/单测/e2e" | → fe-test-pack |
| 改 bug | "bug/报错/修复/fix" | → fe-engineer-pack S2 |
| 代码审查 | "review/CR/审查" | → fe-engineer-pack S5 |
| 性能优化 | "性能/优化/lighthouse" | → fe-engineer-pack S7 |
| 初始化项目 | "初始化/init/新项目" | → fe-agent-init |
| 健康检查 | "检查/健康/状态" | → fe-skill-inspector |

## 模块索引

| 模块 | 说明 | 文件 |
|------|------|------|
| 工作流配方 | 常见任务标准流程 | modules/workflow-recipes.md |
| 输入安全 | 防注入/越权校验 | modules/input-security.md |
| 错误恢复 | 失败重试 + 降级策略 | modules/error-recovery-log.md |
| 会话追踪 | 多轮上下文管理 | modules/session-tracking.md |

## 全局约束

- MUST: 路由分发前写入 stats/usage-log
- MUST NOT: 不得跳过 fe-base-skill 的 5 步检测
- SHOULD: 优先使用 tech-stacks/ 中已有模式

3.5 模块文件示例(路由调度)

modules/workflow-recipes.md 片段:

# 路由调度模块

## 匹配规则

按优先级从高到低:

1. **精确匹配**:用户输入包含注册表中某个 Skill 的 triggerKeywords
2. **语义匹配**:用户意图描述与 Skill 的 description 语义相似度高
3. **兜底**:无法匹配 → 询问用户

## 路由记录

每次路由 SHALL 写入 stats/usage-log.md:

| 字段 | 说明 |
|------|------|
| timestamp | ISO 8601 |
| skill | 目标 Skill 名称 |
| trigger | 触发关键词 |
| routedDomain | 命中域 |
| routeCorrected | 是否被用户纠正(默认 false) |

## 冲突解决

当多个 Skill 同时匹配时:
- 优先级:layer 越深越优先(base > capability > orchestration)
- 同 layer:triggerKeywords 精确匹配 > 语义匹配

四、通用规范:任何 Skill 都该遵守的标准

4.1 最小目录结构

my-skill/
├── SKILL.md              # 【必须】唯一被 AI 自动加载的文件
├── README.md             # 【推荐】给人看的说明
├── CHANGELOG.md          # 【推荐】变更记录
├── manifest.json         # 【推荐】机器可读元数据
├── modules/              # 【可选】SKILL.md > 200行时拆分
├── knowledge/            # 【可选】持久记忆(经验/模式/案例)
├── config/               # 【可选】可变配置
├── templates/            # 【可选】输出模板
└── bin/                  # 【可选】辅助脚本

4.2 Frontmatter 规范

---
name: skill-name              # 唯一标识,kebab-case
description: |                # 第一行必须是触发条件
  Load when user [具体场景].
  [一句话核心价值].
metadata:
  author: your-name
  version: "1.0.0"           # 语义化版本
  layer: tool                # meta/orchestration/capability/base/tool/agent
  createdAt: "2026-07-23"
  updatedAt: "2026-07-23"
---

4.3 正文结构(推荐顺序)

# skill-name — 一句话定位

> 补充说明

## 触发条件          ← 什么时候加载(关键词列表)
## 工作流            ← 核心流程(编号步骤,每步有输入→动作→输出)
## 输出规范          ← 格式、位置、模板
## 约束              ← MUST / SHOULD / MUST NOT
## 示例              ← 1 正常 + 1 边界
## 已知局限          ← 诚实标注(可选)

4.4 规则清单

#规则级别
1frontmatter 含 name + description + versionMUST
2description 第一行是 "Load when..."MUST
3正文有明确「触发条件」章节MUST
4流程每步有输入→动作→输出MUST
5约束用 MUST / SHOULD / MUST NOT 三级SHOULD
6超 200 行拆到 modules/SHOULD
7知识库有 _index.md 索引SHOULD
8每次修改更新 CHANGELOGSHOULD
9示例覆盖正常 + 边界SHOULD
10不硬编码可变配置MUST NOT

4.5 完整示例:code-reviewer

---
name: code-reviewer
description: |
  Load when user says "review" / "代码审查" / "帮我看看这段代码" / "CR".
  Structured code review with severity levels and actionable suggestions.
metadata:
  author: mjd
  version: "1.0.0"
  layer: tool
  createdAt: "2026-07-23"
---

# code-reviewer — 结构化代码审查

> 不是"看起来不错",而是"第 42 行有空指针风险,建议改为 optional chaining"。

## 触发条件

用户输入包含:review / CR / 代码审查 / 帮我看看 / 这段代码有问题吗

## 工作流

1. **定位代码**:用户提供的代码片段 / 指定文件 / 最近修改的文件
2. **多维度审查**   - 🔴 正确性(逻辑错误、边界遗漏、空指针)
   - 🟡 健壮性(错误处理、异常路径、资源泄漏)
   - 🟢 可维护性(命名、重复、复杂度)
   - 🔵 性能(不必要的循环、内存分配、N+1)
3. **输出审查报告**

## 输出格式

| 严重度 | 位置 | 问题 | 建议 |
|--------|------|------|------|
| 🔴 Critical | L42 | 未处理 null | 使用 optional chaining |
| 🟡 Warning | L78 | catch 块为空 | 至少 console.error |

## 约束

- MUST: 每个问题必须给出**具体修改建议**,不能只说"这里不好"
- MUST: 按严重度排序,Critical 在前
- SHOULD: 如果代码整体质量好,先肯定再提问题
- MUST NOT: 不做风格偏好争论(tab vs space 之类)

## 示例

输入:用户粘贴一段 20 行的 fetch 函数
输出:
| 🔴 | L5 | fetch 无 error handling,网络异常会 unhandled rejection | 包裹 try-catch + 超时控制 |
| 🟡 | L12 | response.json() 未校验 status | 先检查 res.ok |
| 🟢 | L3 | 变量名 `d` 含义不明 | 改为 `responseData` |

五、Q&A

Q1: Skill 和 System Prompt 什么区别?

System Prompt 是员工手册,Skill 是岗位 SOP。

  • System Prompt:全局生效,定义性格和通用规则
  • Skill:特定场景才加载,定义具体工作流程

一个 AI 可以同时有 1 个 System Prompt + 30 个 Skill。

Q2: Skill 和 RAG 知识库什么关系?

  • Skill = 流程(怎么做)
  • 知识库 = 经验(基于什么做)

Skill 的 knowledge/ 目录就是它的"工作记忆"。写代码时参考已有模式,而不是每次从零推理。

Q3: 文件多大合适?

类型上限超过怎么办
单文件 Skill200 行拆 modules/
SKILL.md 入口300 行只留索引,详情指向 modules/
单个 module150 行继续拆子模块
总量无上限按需加载,别一次性全塞

Q4: 怎么测试 Skill 好不好用?

三个指标:

  1. 触发准确率:说触发词能加载?说无关内容不误触发?
  2. 输出一致性:同输入跑 3 次,结构稳定?
  3. 约束遵守率:MUST 规则每次都被遵守?

Q5: 写好了但 AI 不用?

99% 是 description 的问题:

  • 触发词没覆盖用户真实表达(用户说"CR"你只写了"代码审查")
  • description 太长,匹配权重被稀释
  • 和另一个 Skill 的触发条件冲突

Q6: 多个 Skill 冲突怎么办?

优先级:

  • 层级深的优先(base > capability > orchestration)
  • 精确关键词 > 语义模糊匹配
  • 实在判断不了 → 问用户,别猜

Q7: 社区有现成的能用吗?

有。skills.sh 是 Agent Skill 的 npm

# 搜索
npx skills find "react typescript"

# 安装
npx skills add vercel-labs/agent-skills@writing-guidelines

# 热门榜单(截至 2026-07-23)
# convex-create-component: 89K 安装
# writing-guidelines: 32.5K 安装
# create-agentsmd: 11.8K 安装

Vercel、GitHub、Sentry、LaunchDarkly 都发布了官方 Skill。先装别人的用,理解结构后再写自己的。


六、主流平台适配:一份 Skill 跑遍所有 IDE

6.1 平台对照表

平台载体位置触发方式多文件
Cursor.cursor/rules/*.mdc项目 .cursor/rules/glob 匹配文件时激活
Claude CodeCLAUDE.md + .claude/rules/项目根/子目录/~/.claude/启动加载 + 子目录按需加载
GitHub Copilotcopilot-instructions.md + instructions/.github/自动加载 + path-specific
Windsurf.windsurfrules项目根自动加载
Cline.clinerules项目根/全局自动加载
Aone Copilot.aone_copilot/rules/*.md项目根自动加载
通用AGENTS.md项目根/子目录22+ 工具原生兼容

6.2 Cursor 适配(.mdc 格式)

Cursor 用 .mdc 文件,支持 glob 触发——只在编辑匹配文件时激活:

.cursor/rules/
├── general.mdc          # alwaysApply: true,全局生效
├── react.mdc            # globs: "src/**/*.tsx"
├── testing.mdc          # globs: "**/*.test.*"
└── security.mdc         # globs: "src/api/**"

.mdc 文件结构

---
description: "Next.js + React + TypeScript 开发规范"
globs: "src/**/*.tsx"
alwaysApply: false
---

You are an expert in TypeScript, Next.js 14 App Router, React, Tailwind CSS.

Key Principles
- Use functional, declarative programming. Avoid classes.
- Use descriptive variable names with auxiliary verbs (isLoading, hasError).
- Favor named exports for components.

Error Handling
- Handle errors at the beginning of functions.
- Use early returns for error conditions.
- Use guard clauses for preconditions.

React/Next.js
- Use function, not const, for components.
- Minimize 'use client', 'useEffect', 'setState'. Favor RSC.
- Use Zod for form validation.
- Wrap client components in Suspense with fallback.

关键差异globs 字段实现了"按文件类型触发"——编辑 .tsx 时加载 React 规则,编辑 .test.ts 时加载测试规则。这是 Cursor 独有的精细控制。

6.3 Claude Code 适配(层级 + 按需)

Claude Code 用 CLAUDE.md,有两个加载机制:

启动时加载(全局生效):

~/.claude/CLAUDE.md              # 用户级:个人偏好
project/CLAUDE.md                # 项目级:团队共享规范
project/CLAUDE.local.md          # 本地级:个人项目偏好(gitignore)

按需加载(读到该目录文件时才生效):

project/src/CLAUDE.md            # 子目录级:模块专属规则
project/src/components/CLAUDE.md # 更深层:组件规范

⚠️ 注意:官方文档明确说"if two rules contradict, Claude may pick one arbitrarily"。不存在"深层一定覆盖浅层"的保证——避免写矛盾规则比依赖优先级更重要。

还支持 .claude/rules/ 目录做 path-specific 规则,以及 @path/to/file 语法导入外部文件。

AGENTS.md 兼容:Claude Code 不原生读 AGENTS.md,但可以在 CLAUDE.md 里写 @AGENTS.md 导入。

6.4 GitHub Copilot 适配(仓库级 + path-specific)

GitHub Copilot 支持两层指令:

.github/
├── copilot-instructions.md          # 仓库级(全局生效)
└── instructions/
    ├── react.instructions.md        # path-specific(匹配特定路径)
    └── testing.instructions.md
  • copilot-instructions.md:所有 Copilot 交互都加载
  • instructions/NAME.instructions.md:只在匹配路径的文件上下文中生效

6.5 AGENTS.md 通用方案

60,000+ 开源项目在用,原生兼容 22 个 AI 编程工具:

Codex (OpenAI) · Jules (Google) · Cursor · Windsurf · Devin · Gemini CLI · Aider · goose · opencode · Zed · Warp · VS Code · Junie (JetBrains) · Amp · RooCode · Kilo Code · Phoenix · Semgrep · GitHub Copilot · Ona · Augment Code · Factory ...

# AGENTS.md

## Project Overview
React 18 + TypeScript + Vite 单页应用...

## Setup Commands
pnpm install
pnpm dev

## Testing Instructions
pnpm test              # 全量
pnpm vitest run -t "login"  # 单个用例

## Code Style
- 函数式组件,不用 class
- 命名:camelCase 变量,PascalCase 组件
- 导入顺序:react → 三方库 → 本地模块 → 样式

## Build and Deployment
pnpm build → dist/
CI: GitHub Actions,PR 必须通过 lint + test

Monorepo 规则:根目录 + 子项目各一份,最近的优先

6.6 单文件平台适配(Windsurf / Cline)

核心策略:压缩到 100 行内,只保留流程 + 约束

# .windsurfrules

## 角色
前端开发助手。TypeScript strict,函数式组件。

## 工作流
写代码:检测技术栈 → 匹配规范 → 生成 → 自检 → 输出
改 bug:复现 → 定位 → 修复 → 验证

## 约束
- MUST: TypeScript strict,不用 any
- MUST: 组件用 function 声明,不用 const 箭头
- MUST: 错误处理用 early return + guard clause
- MUST NOT: 不跳过类型检查
- SHOULD: 优先用项目已有组件

砍掉模块化引用、知识库、示例——单文件平台塞不下,保留最核心的 20%。

6.7 跨平台迁移清单

  • 目标平台支持多文件?(决定是否需要压缩)
  • 触发方式?(自动加载 / glob 匹配 / path-specific / 手动引用)
  • 上下文窗口多大?(决定能塞多少内容)
  • 保留 frontmatter(即使平台不解析,留作人类参考)
  • 用 3-5 个真实场景测试触发准确率
  • 记录平台差异到 CHANGELOG

6.8 一句话

Skill 的本质是平台无关的。 变的是载体(.mdc / CLAUDE.md / AGENTS.md / .windsurfrules),不变的是四件事:触发条件 + 流程 + 约束 + 示例。写好一份 SKILL.md,适配只是格式转换。


结语

2026 年,AI 编程的竞争力不在于"会用哪个 IDE",而在于你给 AI 装了多少职业记忆

  • 30 行的日报生成器,让你每天省 10 分钟
  • 300 行的编排中枢,让 31 个 Skill 协同工作
  • 一份 AGENTS.md,让 22 个 AI 工具接手你的项目时不用从零解释

Vercel 做了,GitHub 做了,Sentry 做了。32,500 人安装了 writing-guidelines。

现在轮到你了。打开编辑器,从那个你每天都要重复解释 3 遍的场景开始。

你的 AI 不该每天失忆。


下一篇:《手把手书写你的第一个 AI Agent》—— 当 Skill 有了记忆、有了角色、有了主动性,它就不再是工具,而是同事。