---
title: "从零写一个你的 Skill"
wiki: skills
category: "构建指南"
slug: M04-从零写一个你的Skill
url: https://learnagent.wiki/skills/cards/M04-从零写一个你的Skill
tags: ["从零写 Skill", "写作", "结构设计", "实战"]
last_updated: 2026-04-11
reading_time: 25
---

> > 模块4：从零写一个你的 Skill | 用时：约 40 分钟 | 目标：完整走过一遍从规划到测试的流程，最后再做一个带脚本的进阶版

# Skill 从小白到高手系列课

> 模块4：从零写一个你的 Skill | 用时：约 40 分钟 | 目标：完整走过一遍从规划到测试的流程，最后再做一个带脚本的进阶版

---

上一个模块你学会了怎么调 Skill——改 description、调正文、加触发词。但都是基于已有的 Skill 来改。

这个模块我要带你从零开始，手把手写一个**完整的 Skill**。

读完这篇，你将能独立走完一个 Skill 的：规划、编写、测试、迭代，全流程。不光讲概念，我带你**亲手做出来**。

---

## 先给你看看，我们要做成什么样

想象一下，以后你在终端只需要说一句话，AI 就会自动分析你的代码变更，然后输出一个规范的 commit message：

```
你：帮我写个 commit message

AI：[自动加载 commit-message-writer Skill，读取暂存区变更]

feat: 添加用户登录页面

新增了以下内容：
- LoginForm 组件，支持邮箱/密码登录
- JWT token 存储逻辑
- 登录成功后的路由跳转
```

看到了吗？你不需要解释"什么是 commit message"、"要用什么格式"。AI 已经从 Skill 里学会了你的规范。

这就是我们今天要一起做出来的东西。

准备好了吗？让我们从零开始。

---

## 第一步：先想清楚，你要写什么 Skill

动笔之前，先别急。

我问你一个问题：**你现在用 AI 的时候，最烦的是什么？**

是不是每次都要重新描述一遍要求？是不是同样的格式要重复说十遍？

那这就是你的 Skill 要解决的问题。

我给大家举几个真实场景，你看看哪个跟你最像：

### 如果你是自媒体人

每天写文章，标题直接决定打开率。但每次让 AI 写标题，都要重新说："开头要有悬念感"、"数据型标题也来几个"、"别写得太官方"……

**你的 Skill 可以是：** `wechat-title-generator`

它能帮你生成 5 种风格的标题（悬念型、数据型、反常识型、故事型、清单型），还能分析每个标题的预期点击率。

纯指令型就够了，不需要脚本。15 分钟就能做好。

### 如果你是产品经理

每周写 PRD，每次都要先贴一遍公司模板。不同产品类型重点还不一样——B 端要写权限设计，C 端要写用户故事。

**你的 Skill 可以是：** `prd-generator`

它先判断产品类型，然后输出对应的 PRD 骨架。B 端自动带权限矩阵，C 端自动带增长漏斗。你往里填内容就行。

### 如果你是开发者

每天提交代码，commit message 经常偷懒写成 `fix: 修了一下`，结果被 code review 打回来。

**你的 Skill 可以是：** `commit-message-writer`

它自动读 `git diff --staged`，判断变更类型，输出规范的 `<type>: <中文描述>`。

这就是我们今天要一起做的 Skill。

### 如果你是学生

写论文时，文献综述整理到崩溃。一堆论文标题和摘要，要手动分类、找研究脉络。

**你的 Skill 可以是：** `literature-review-helper`

把论文列表丢给它，自动按主题分类、标注核心贡献。

---

**好了，不管你是什么角色，原理都一样。**

下面我以开发者的 `commit-message-writer` 为例，带你完整走一遍 6 步流程。你跟着做一遍，换成你自己的内容，就是你的 Skill 了。

---

## 第二步：动笔前，先回答这 3 个问题

别急着写代码，先在脑子里想清楚这三个问题：

**问题一：这个 Skill 到底做什么？**

commit-message-writer 做的事很简单：**分析代码变更，生成规范的 commit message**。

但你要想清楚——"分析"到底分析什么？是所有文件的变更，还是只分析暂存区的？

我决定只分析暂存区的，因为 `git diff --staged` 最精准。用户 add 了什么，就分析什么。

**问题二：什么时候触发？**

用户什么时候会说"帮我写 commit message"？

我列了一下：
- "写个 commit"
- "帮我提交代码"
- "git commit"
- "描述一下这次变更"
- "写 commit message"

这些**触发词**，后面都要写进 description。

**问题三：输出什么格式？**

格式是 `<type>: <中文描述>`。

type 必须是 Conventional Commits 规范里的：feat、fix、docs、style、refactor、test、chore。

中文描述不超过 50 字。简洁精准，不啰嗦。

---

**这三个问题的答案，就是整个 Skill 的骨架。**

- name 从"做什么"来
- description 从"什么时候用"来
- 正文从"输出什么"来

想清楚了？那我们开始写。

---

## 第三步：起名字——这里有 6 条硬规则

name 字段看起来简单，但有规则。不遵守，Skill 就无法被识别。

我来逐条讲，每条都给你正反例：

**规则一：只用小写字母、数字、连字符**

- ✅ 正例：`commit-message-writer`、`prd-generator`、`pdf-helper-v2`
- ❌ 反例：`CommitMessageWriter`（不能大写）、`PRD_Generator`（不能用下划线大写混合）

为啥？因为 Skill 的名字要和文件夹名完全一致。文件系统区分大小写，你写大写容易搞混。

**规则二：单词之间用连字符，不用下划线**

- ✅ 正例：`code-reviewer`、`data-analysis`
- ❌ 反例：`code_reviewer`（不能用下划线）、`code.reviewer`（不能用点号）

这和域名命名规则一样。连字符是最安全的分隔符。

**规则三：不能以连字符开头或结尾**

- ✅ 正例：`architecture-diagram`
- ❌ 反例：`-diagram`（开头不能是连字符）、`diagram-`（结尾不能是连字符）

**规则四：不能有连续的连字符**

- ✅ 正例：`ecommerce-report`
- ❌ 反例：`ecommerce--report`（两个连字符会被当成错误）

**规则五：长度限制 1 到 64 个字符**

- ✅ 正例：`pdf-helper`（9 个字符）
- ❌ 反例：超过 64 字符的超长名字。名字太长你自己都记不住。

**规则六：name 必须和文件夹名一致**

如果你文件夹叫 `commit-message-writer/`，那 name 字段就必须写 `commit-message-writer`。**差一个字符都不行。**

这是硬性规则，不是建议。

我给 Skill 起名叫 `commit-message-writer`。符合所有规则，一眼就知道是干什么的。

---

## 第四步：写 description——这是最重要的字段

description 决定了 AI 什么时候加载你的 Skill。

我给你一个公式：

```
description = 做什么 + 什么时候用 + 输出什么 + 触发词
```

展开说：
- **做什么**：一句话描述 Skill 的功能
- **什么时候用**：列出所有可能的触发场景
- **输出什么**：描述输出的格式或内容
- **触发词**：把用户可能说的关键词都塞进去

照着这个公式，我写了 commit-message-writer 的 description：

```yaml
description: >
  分析代码变更并生成规范的Git commit message。
  当用户需要提交代码、写commit message、git commit、
  描述代码变更时使用。
  遵循Conventional Commits规范，格式：<type>: <中文描述>。
```

逐行分析一下：

**第一行** "分析代码变更并生成规范的Git commit message" → **做什么**

直接告诉 AI 这个 Skill 的功能。

**第二行** "当用户需要提交代码、写commit message、git commit、描述代码变更时使用" → **什么时候用 + 触发词**

我把用户可能说的四种说法都写上了。不管用户怎么说，AI 都能识别到该加载这个 Skill。

**第三行** "遵循Conventional Commits规范，格式：<type>: <中文描述>" → **输出什么**

告诉 AI 输出格式是 type 加冒号加中文描述。

整个 description 只有 3 行，但**每个字都有用**。不废话，不抒情，全是信息量。

---

## 第五步：写正文指令——告诉 AI 具体怎么做

正文是 Skill 的核心。AI 加载 Skill 之后，就是按正文里的指令来干活。

我来一步步写。

**首先是 frontmatter**，把 name 和 description 放进去：

```yaml
---
name: commit-message-writer
description: >
  分析代码变更并生成规范的Git commit message。
  当用户需要提交代码、写commit message、git commit、
  描述代码变更时使用。
  遵循Conventional Commits规范，格式：<type>: <中文描述>。
---
```

**然后写操作步骤**，告诉 AI 具体怎么做：

```markdown
## 操作步骤

1. 运行 `git diff --staged` 查看暂存区的变更内容
2. 分析变更，判断变更类型：
   - feat: 新功能
   - fix: 修复bug
   - docs: 文档变更
   - style: 格式调整（不影响逻辑）
   - refactor: 重构（不是新功能也不是修bug）
   - test: 测试相关
   - chore: 构建/工具链变更
3. **只描述主要变更**，忽略次要细节
4. 用中文写简短描述，不超过50字
5. 输出格式：`<type>: <描述>`
```

注意第 3 条"只描述主要变更"。这是我**迭代了三次之后**加上的。

一开始没写这条，AI 就会把每个文件的每个小改动都罗列出来，50 字限制形同虚设。

**然后写示例输出**，让 AI 知道好的输出长什么样：

```markdown
## 示例输出
feat: 添加用户登录页面
fix: 修复购物车数量计算错误
refactor: 重构订单查询逻辑提升性能
docs: 更新API接口文档
```

**最后写反模式**。告诉 AI 不要做什么，和告诉它做什么一样重要：

```markdown
## 反模式
- 不要写模糊描述（"update code"、"fix bug"）
- 不要超过50字
- 不要试图罗列所有变更，抓主要矛盾
- 不要用英文描述（除非用户要求）
```

为什么反模式很重要？因为 AI 有自己的倾向。你不告诉它不要做什么，它就会按照自己的理解来。

比如 AI 默认喜欢写英文，你不写"不要用英文描述"，它就会输出 `feat: add user login page`。你说得对，但我要中文。

把上面的部分拼在一起，就是一个完整的 SKILL.md。

---

## 第六步：组装和放置——放到正确的位置

现在文件写好了，要放到正确的位置。

**先建文件夹**。文件夹的名字必须和 name 字段一致。

我的是 `commit-message-writer`，所以文件夹也叫 `commit-message-writer`。

```
你的项目/
└── .claude/
    └── skills/
        └── commit-message-writer/
            └── SKILL.md
```

路径是 `.claude/skills/<你的Skill名字>/SKILL.md`。

记住这个结构：
- SKILL.md 这个文件名**不能改**，大小写不能变
- 文件夹名可以自己取，但要和 name 字段一致

放好之后，文件结构应该是这样的：

```
.claude/skills/commit-message-writer/SKILL.md
```

就这么一个文件。纯指令型 Skill 不需要别的。没有脚本，没有数据文件，没有 references 目录。

简单清爽。

---

## 第七步：测试和迭代——这是打磨的关键

文件放好了，接下来就是测试。

测试方法很简单：**重启 Claude Code，暂存一些代码变更，然后说"帮我写个 commit message"**。

### v1 —— 我的第一版

这是我刚写完的版本，非常简陋：

```yaml
---
name: commit-message-writer
description: "生成Git commit message。当用户需要写commit message时使用。"
---

## 操作步骤
1. 查看 git diff 了解变更内容
2. 生成 commit message
```

就这么几行。我满怀信心地测试了。

结果呢？我输入"帮我写 commit"，AI 确实触发了 Skill，但输出了：

```
update code
```

这种描述等于没说。

**问题出在哪？**

第一，我没告诉 AI 用什么格式（Conventional Commits）。
第二，我没告诉 AI 用中文。
第三，我没给示例输出。AI 不知道好的长什么样，就按自己理解来了。

### v2 —— 第二版

我回去改了。加了类型分类和反模式：

```yaml
---
name: commit-message-writer
description: "生成Git commit message。当用户需要提交代码、写commit message、git commit时使用。"
---

## 操作步骤
1. 运行 `git diff --staged` 查看变更
2. 判断变更类型：feat / fix / docs / style / refactor / test / chore
3. 用中文写描述，不超过50字

## 反模式
- 不要写模糊描述（"update code"、"fix bug"）
```

好多了。大部分情况能用了。

但有一次我改了 5 个文件，涉及登录功能、注册功能、密码重置、权限验证、用户列表。

AI 输出了：

```
feat: 添加用户管理模块的登录功能、注册功能、密码重置功能、权限验证、用户列表
```

50 个字？早超了。AI 把所有变更都列出来了，完全没有"抓主要矛盾"的意识。

### v3 —— 第三版

我又加了两条规则：

```markdown
## 操作步骤
1. 运行 `git diff --staged` 查看变更
2. 判断变更类型：feat / fix / docs / style / refactor / test / chore
3. **只描述主要变更**，忽略次要细节
4. 用中文写描述，不超过50字
5. 输出格式：`<type>: <描述>`

## 反模式
- 不要写模糊描述（"update code"、"fix bug"）
- 不要超过50字
- 不要试图罗列所有变更，抓主要矛盾
- 不要用英文描述（除非用户要求）
```

第 3 条"只描述主要变更"是关键新增。

同样的 5 个文件变更，这次输出变成了：

```
feat: 添加用户管理模块
```

简洁精准。8 个字，一击必中。

### 我的迭代教训

我花了**三轮**才打磨好。每轮测试 5 分钟，总共 15 分钟。

但之后每天至少省 5 分钟写 commit message 的时间。**三天就赚回来了。**

原则很简单：**先跑起来，再逐步打磨。**

不要一上来就追求完美。v1 能用就行，问题会在使用中自然暴露。

你不可能坐在那儿想出所有边界情况，只有真实使用才能发现漏洞。

### 用真实的 git diff 给你演示

我来模拟一下真实的使用场景。假设你的项目里有这些变更：

**变更内容（git diff --staged 的输出）：**

```diff
diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue
new file mode 100644
index 0000000..a1b2c3d
--- /dev/null
+++ b/src/components/LoginForm.vue
@@ -0,0 +1,45 @@
+<template>
+  <form @submit.prevent="handleLogin">
+    <input v-model="email" type="email" placeholder="邮箱" />
+    <input v-model="password" type="password" placeholder="密码" />
+    <button type="submit">登录</button>
+  </form>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+
+const email = ref('')
+const password = ref('')
+const router = useRouter()
+
+async function handleLogin() {
+  const res = await fetch('/api/login', {
+    method: 'POST',
+    body: JSON.stringify({ email: email.value, password: password.value })
+  })
+  if (res.ok) {
+    localStorage.setItem('token', (await res.json()).token)
+    router.push('/dashboard')
+  }
+}
+</script>

diff --git a/src/utils/auth.js b/src/utils/auth.js
new file mode 100644
index 0000000..d4e5f6a
--- /dev/null
+++ b/src/utils/auth.js
@@ -0,0 +1,12 @@
+export function getToken() {
+  return localStorage.getItem('token')
+}
+
+export function isAuthenticated() {
+  return !!getToken()
+}
+
+export function logout() {
+  localStorage.removeItem('token')
+  window.location.href = '/login'
+}
```

**v1 的输出：**

```
update code
```

完全没法用。

**v2 的输出：**

```
feat: 添加LoginForm组件和auth工具函数
```

好一点了，但描述还是有点散。两个东西写一行，读起来不够清晰。

**v3 的输出：**

```
feat: 添加用户登录功能
```

精准。LoginForm 和 auth.js 都是围绕"用户登录"这个核心功能的，抓住主线就行。

---

## 进阶：纯指令型 vs 带脚本型——两条路径怎么选

写完 commit-message-writer 之后，你可能已经意识到一件事：

这个 Skill 全靠指令驱动，没有任何代码脚本。AI 读到指令，自己去执行。

这就叫**纯指令型**。

但有些场景，光靠指令不够用。比如你需要精确计算，需要读取外部数据，需要处理文件。

这时候就要加脚本了。

我来对比一下两条路径。

### 纯指令型

纯指令型就是只有一个 SKILL.md 文件。所有逻辑都用自然语言写在这个文件里。AI 读到就照着做。

**适合什么？** 适合处理**文本类**的任务。

- 写文章
- 生成模板
- 代码审查
- 格式转换
- 翻译润色

这些都用纯指令型就够了。

commit-message-writer 就是一个纯指令型 Skill。它的全部逻辑就是：读 diff、判断类型、写描述。不需要算什么，不需要查什么数据库。AI 的语言能力足够处理这些。

**纯指令型的优势是简单。** 写一个文件，放到目录里，就完事了。不需要懂编程，不需要调试脚本，不需要管依赖。

### 带脚本型

带脚本型除了 SKILL.md，还有 `scripts/` 目录（放 Python 脚本）和 `data/` 目录（放数据文件）。

AI 读到 SKILL.md 里的指令，然后调用脚本去执行具体任务。

**适合什么？** 适合需要**精确计算**或需要**大量数据**的场景。

- 数据分析
- 文件处理
- 数据库查询
- 自动化操作

这些 AI 自己做容易出错，交给脚本更靠谱。

我下面给你一个完整的带脚本型 Skill 示例。这个例子是电商运营人员用的，每周出一份销售数据报告。

---

## 完整示例：电商数据分析 Skill

假设你是一个电商运营，每周要从美团或淘宝导出 CSV 数据，然后写一份销售报告。

报告包括：
- 总销售额
- 环比增长
- TOP 10 商品
- 各品类占比
- 异常波动预警

这个需求如果让 AI 直接分析 CSV，它可能会：
- 算错环比增长率
- 分不清同比和环比
- TOP 10 排名排错

所以我们把计算部分交给 Python 脚本。

**文件结构：**

```
ecommerce-report/
├── SKILL.md                    ← 告诉 AI 工作流程
├── scripts/
│   └── analyze_csv.py          ← 实际干计算活的代码
└── references/
    └── report-template.md      ← 报告模板
```

**SKILL.md 的内容：**

```yaml
---
name: ecommerce-report
description: >
  分析电商销售CSV数据，生成结构化周报。
  当用户提供销售数据、需要出报告、周报、
  电商数据分析、销售分析时使用。
  支持美团和淘宝数据格式。
---

## 操作步骤

1. 确认用户提供的数据文件路径
2. 运行分析脚本：
   ```bash
   python3 scripts/analyze_csv.py <csv文件路径>
   ```
3. 脚本会输出以下数据（JSON格式）：
   - 本周总销售额和订单数
   - 环比上周增长率（自动计算）
   - TOP 10 商品排名（按销售额）
   - 各品类销售占比
   - 异常波动预警（增长率超过正负50%的商品）
4. 按 `references/report-template.md` 模板格式化输出
5. 在报告末尾加上"运营建议"部分，基于数据给出2-3条具体建议

## 数据格式要求

输入CSV必须包含以下列：
- date（日期）
- product_name（商品名称）
- category（品类）
- sales_amount（销售额）
- order_count（订单数）

## 反模式
- 不要手动计算环比增长率，交给脚本
- 不要猜测数据趋势，以脚本输出为准
- 不要省略异常波动预警部分
```

**scripts/analyze_csv.py 的核心逻辑：**

```python
#!/usr/bin/env python3
"""电商数据分析脚本 - 处理CSV并输出结构化数据"""

import csv
import sys
from datetime import datetime, timedelta
from collections import defaultdict

def analyze(filepath):
    # 读取CSV
    with open(filepath, 'r', encoding='utf-8') as f:
        rows = list(csv.DictReader(f))

    # 按周分组
    this_week = defaultdict(lambda: {'sales': 0, 'orders': 0})
    last_week = defaultdict(lambda: {'sales': 0, 'orders': 0})
    today = datetime.now()
    week_ago = today - timedelta(days=7)
    two_weeks_ago = today - timedelta(days=14)

    for row in rows:
        date = datetime.strptime(row['date'], '%Y-%m-%d')
        amount = float(row['sales_amount'])
        product = row['product_name']
        category = row['category']
        orders = int(row['order_count'])

        if date >= week_ago:
            this_week[(product, category)]['sales'] += amount
            this_week[(product, category)]['orders'] += orders
        elif date >= two_weeks_ago:
            last_week[(product, category)]['sales'] += amount
            last_week[(product, category)]['orders'] += orders

    # 计算总销售额
    total_this = sum(v['sales'] for v in this_week.values())
    total_last = sum(v['sales'] for v in last_week.values())
    growth_rate = (total_this - total_last) / total_last * 100 if total_last else 0

    # TOP 10 商品
    product_sales = defaultdict(float)
    for (product, _), data in this_week.items():
        product_sales[product] += data['sales']
    top10 = sorted(product_sales.items(), key=lambda x: x[1], reverse=True)[:10]

    # 品类占比
    category_sales = defaultdict(float)
    for (_, category), data in this_week.items():
        category_sales[category] += data['sales']
    total_cat = sum(category_sales.values())
    category_ratio = {k: round(v/total_cat*100, 1) for k, v in category_sales.items()}

    # 异常波动检测
    anomalies = []
    for (product, category) in this_week:
        tw = this_week[(product, category)]['sales']
        lw = last_week[(product, category)]['sales']
        if lw > 0:
            change = (tw - lw) / lw * 100
            if abs(change) > 50:
                anomalies.append({
                    'product': product,
                    'change': round(change, 1),
                    'direction': '暴涨' if change > 0 else '暴跌'
                })

    # 输出结果
    print(f"本周总销售额: {total_this:.2f} 元")
    print(f"环比增长: {growth_rate:.1f}%")
    print(f"\nTOP 10 商品:")
    for i, (name, sales) in enumerate(top10, 1):
        print(f"  {i}. {name}: {sales:.2f} 元")
    print(f"\n品类占比:")
    for cat, ratio in sorted(category_ratio.items(), key=lambda x: x[1], reverse=True):
        print(f"  {cat}: {ratio}%")
    if anomalies:
        print(f"\n异常波动预警:")
        for a in anomalies:
            print(f"  {a['product']}: {a['direction']} {abs(a['change']}%")

if __name__ == '__main__':
    analyze(sys.argv[1])
```

**references/report-template.md：**

```markdown
# 电商周报 - {日期范围}

## 一、整体概览

- 本周销售额：{total_this} 元
- 本周订单数：{total_orders} 单
- 环比增长：{growth_rate}%

## 二、TOP 10 热销商品

{top10_list}

## 三、品类分布

{category_distribution}

## 四、异常波动

{anomalies}

## 五、运营建议

{ai_suggestions_based_on_data}
```

### 为什么用脚本而不是让 AI 直接算？

这是一个关键问题。

数据分析涉及精确计算。环比增长率是 `(本周 - 上周) / 上周 * 100`，这个公式很简单，但 AI 在处理大量数据行时容易漏算或重复计算。

TOP 10 排名如果让 AI 用自然语言做，它可能排错顺序。

异常波动检测需要逐商品对比两周数据，超过 50% 才标记。这个逻辑用 Python 写 5 行代码搞定，但用自然语言描述就容易有歧义。

**分工原则：**
- 脚本负责**精确计算**和**数据清洗**
- AI 负责"调度"和"解读"

脚本输出数字，AI 基于数字写分析和建议。这样既准确又高效。

---

## 两种类型的选择指南

什么时候用纯指令型，什么时候用带脚本型？

我给你一个简单的判断方法：

**如果你要做的事，人用文字就能完成**（写文章、做模板、审代码、提建议），就用纯指令型。

**如果你要做的事，需要跑代码才能完成**（数据分析、文件转换、批量处理、精确计算），就用带脚本型。

另一个判断角度是**容错率**。

如果输出错了只是措辞不好，纯指令型够用。

如果输出错了会导致计算错误、数据对不上、金额算错，那一定要用脚本。

**不要因为"带脚本听起来更高级"就去用脚本。**

大部分场景纯指令型就够了。脚本是手段，不是目的。能简单解决的问题，不要搞复杂。

---

## 要点总结

1. **先想清楚再动笔。** 三个问题：做什么、什么时候用、输出什么。想清楚了再写，否则写出来也要改。

2. **name 要规范。** 小写、连字符、1-64 字符、和文件夹名一致。六条规则不能违反。

3. **description 有公式。** 做什么 + 什么时候用 + 输出什么 + 触发词。把这四样东西写进去，触发就不会出问题。

4. **正文三要素。** 操作步骤、示例输出、反模式。缺了哪个都会影响输出质量。

5. **先跑起来再打磨。** v1 能用就行，v2 修大问题，v3 精细调整。三轮迭代足够了。

6. **两种路径选简单的。** 能纯指令解决的不要加脚本。需要精确计算和数据处理的才用脚本。

---

## FAQ

**Q：一个 Skill 可以做很多事吗？**

不建议。一个 Skill 专注做一件事。需要多件事就写多个 Skill，AI 会自动组合使用。

一个"万能 Skill"反而会因为 description 太宽导致触发混乱。

**Q：正文写多长合适？**

建议控制在 200 行以内。太长的正文会占用太多上下文空间，AI 也不一定全记住。

如果内容确实多，把详细部分拆到 references/ 目录的文件中。

**Q：怎么知道自己的 Skill 写得好不好？**

看两个指标：
- **触发准确率**：该触发时触发，不该触发时不触发
- **输出质量**：是否符合你的预期

两个指标都满意，就是好 Skill。

**Q：带脚本的 Skill 需要什么前置条件？**

需要 Python 环境。大部分系统自带 Python。

如果没有：
- macOS：`brew install python3`
- Windows：`winget install Python.Python.3.12`
- Ubuntu：`sudo apt install python3`

脚本不需要任何第三方库，只用 Python 标准库就够了。

**Q：references/ 目录里的模板文件，AI 怎么知道去读？**

在 SKILL.md 的操作步骤里明确写出来。

比如"按 references/report-template.md 模板格式化输出"。

AI 执行到这一步就会去读这个文件。你不说它不会主动去读。

---

*以上，这就是从零写一个 Skill 的完整流程。*

*你已经学会了规划、编写、测试、迭代，还了解了纯指令型和带脚本型的区别。*

*现在，动手写你的第一个 Skill 吧。*

*我们，下一个模块见。*

---
*Source: https://learnagent.wiki/skills/cards/M04-从零写一个你的Skill*
*Markdown mirror of https://learnagent.wiki, served as text/markdown for LLM ingestion.*