Skip to content
Chun-Chieh's Blog
Go back

如何写好skills

Edit page

前面一篇文章介绍了agent skills的基本概念,本文将介绍如何写好一个skill。阅读本文前建议先看agent skills笔记。

Table of contents

Open Table of contents

如何写好body content

首先内容要基于真实的业务场景,来源可以是自己的经验,或者是内部文档、代码 review、真实故障案例等。写清楚具体实行步骤和方案,不要给一堆建议。

内容不要写常识,重点放在:项目特有规则,非显而易见的坑,指定工具/API,特殊流程和约束。一个非常好用的判断标准是:“如果没有这句话,模型会不会做错?”

skill的范围要合适,不能太大也不能太小,写的太细可能会和其他skill冲突,同时很难筛选出当前真正相关的内容,写的太宽泛可能不好精确触发,输出格式不可控。只保留必要信息比如用途、触发条件、入参、输出格式、异常处理。明确什么场景用、什么场景绝对不要用。

高风险任务谨慎操作,开放性任务可以给原则,让模型自己判断;但数据库迁移、批量修改、危险操作这类工作,就应该明确规定步骤甚至禁止自由发挥。

高效指令设计模式
这些是用于组织 Skill(技能)内容的可复用技巧。并非每一个技能都需要全部用上,按需选取适配任务的模式即可。

Gotchas
这个比较常用,主要用于避免执行任务时候踩坑。作用是提前列出风险、易错点、边界 case,避免模型犯常识/逻辑漏洞。比如:

## Gotchas
- users 表采用软删除机制。查询时必须带上条件 WHERE deleted_at IS NULL,否则查询结果会包含已停用的账号。
- 用户 ID:数据库中字段为 user_id,认证服务里叫 uid,账单计费 API 中为 accountId;三者指代同一个用户标识。
- /health 健康检查接口:只要 Web 服务进程在运行,就返回 200 状态码,即便数据库连接异常也依旧返回 200。如需校验服务整体健康状态,请使用 /ready 接口。

Output Template
用于输出格式必须稳定,作用是强制输出结构,防止模型自由发挥乱格式,保障结构化输出一致性。比如:

## Report structure

Use this template, adapting sections as needed for the specific analysis:

markdown
# [Analysis Title]

## Executive summary
[One-paragraph overview of key findings]

## Key findings
- Finding 1 with supporting data
- Finding 2 with supporting data

## Recommendations
1. Specific actionable recommendation
2. Specific actionable recommendation

Checklist
用于多步骤任务,防止漏步骤。作用是把任务拆成清单,模型逐条执行,避免遗漏环节。比如:

##Form processing workflow
Progress:
- [ ] Step 1: Analyze the form (run `scripts/analyze_form.py`)
- [ ] Step 2: Create field mapping (edit `fields.json`)
- [ ] Step 3: Validate mapping (run `scripts/validate_fields.py`)
- [ ] Step 4: Fill the form (run `scripts/fill_form.py`)
- [ ] Step 5: Verify output (run `scripts/verify_output.py`)

Validation Loop
用于做完 → 检查 → 修正 → 再检查。作用是让模型自己校验输出,发现问题自动修复,循环直到合格。比如:

## Editing workflow

1. Make your edits
2. Run validation: `python scripts/validate.py output/`
3. If validation fails:
   - Review the error message
   - Fix the issues
   - Run validation again
4. Only proceed when validation passes

Plan → Validate → Execute
用于批量修改、破坏性操作。作用是先做计划,校验计划是否合理,确认没问题再执行,防止误操作。比如:

## PDF form filling
1. Extract form fields: `python scripts/analyze_form.py input.pdf` → `form_fields.json`
   (lists every field name, type, and whether it's required)
2. Create `field_values.json` mapping each field name to its intended value
3. Validate: `python scripts/validate_fields.py form_fields.json field_values.json`
   (checks that every field name exists in the form, types are compatible, and
   required fields aren't missing)
4. If validation fails, revise `field_values.json` and re-validate
5. Fill the form: `python scripts/fill_form.py input.pdf field_values.json output.pdf`

Scripts 用于模型每次都在重复实现同一段逻辑。作用是把重复逻辑封装成 “脚本”,模型直接调用脚本执行,不用每次重新写逻辑。

Note

好的Skill = 真实经验 + 非显然知识 + 明确默认路径 + 可复用流程 + 验证机制 − 废话

如何写好description

description主要是告诉 Agent:什么时候应该调用这个 Skill。比如”当用户需要分析、清洗、转换或可视化表格数据时使用。”

技巧:

description: 提取 PDF 文本和表格,填写表单,合并 PDF。使用场景:处理 PDF 文件、提取文档内容、填写 PDF 表单、合并多个 PDF、用户提及「PDF」「提取」「表单」「合并」等关键词。
# 不好的描述 - 太笼统
description: 帮助处理各种文件。

# 好的描述 - 具体明确
description: 处理图像文件,包括调整大小、转换格式、应用滤镜。使用场景:处理图片、调整图像尺寸、转换图片格式。
description: 执行代码审查,检查安全漏洞、代码质量和性能问题。使用场景:代码审查、PR 审查、代码检查、安全扫描、质量评估、用户要求「review」「检查代码」「安全性」等。
# 技能 1:PDF 文本提取
name: pdf-extract
description: 从 PDF 文件中提取文本内容和表格数据。使用场景:提取 PDF 文字、读取 PDF 内容、PDF 转文本、用户提及「PDF 提取」「读取 PDF」等。

# 技能 2:PDF 表单处理
name: pdf-form
description: 填写 PDF 表单字段,提取表单数据。使用场景:填写 PDF 表单、填充表单字段、PDF 表单数据处理、用户提及「PDF 表单」「填写表单」等。
description: 
  生成专业的 PowerPoint 演示文稿。当用户需要制作幻灯片、PPT、演讲稿、
  汇报材料时,必须使用此 Skill,即使用户没有明确说"用 pptx 格式"。
  只要涉及演示文稿的创建或修改,都应触发此 Skill。

长度: 简单技能50-100字符,中等复杂度技能100-200字符,复杂技能200-400字符

Tip

注意:描述不是越长越好。过长的描述可能包含过多无关信息,反而干扰代理的判断。

测试:

description写完后要测试,写大概20条贴近真实场景的用户提示词,并提前标注是否应当触发本技能,8‑10 条应当触发,8‑10 条不应当触发。比如说可以写:

需要触发的问题:

不需要触发的问题:

查询和skill关键词或概念相关的内容,但实际需要的是完全不同的能力,比如“我需要修改 Excel 预算表格里的公式”—— 同样提到 “电子表格”“数据”,但需求是编辑 Excel,不是 CSV 分析。

同一个问题建议问三次,应当触发的查询:触发率高于阈值(默认阈值 0.5)才算通过。不应当触发的查询:触发率低于该阈值才算通过。20 条查询,每条跑 3 次,合计就要执行 60 轮调用。因此需要脚本自动化完成这套流程。

优化:

有的本该触发却没有触发,有的不该触发却意外触发了。优化描述就是针对这些失败的测试用例进行迭代修改。

修复漏触发(该触发没触发)

修复误触发(不该触发却触发)

Warning

不要只针对少数几条失败用例过度调优描述。如果为了搞定个别用例把描述写得极度特殊化,会造成过拟合,推荐训练集60%,测试集40%。

根据失败用例修改技能描述。使用整套评估查询,重新跑完整套测试(每条多次运行)。统计新的触发率,观察假阳性、假阴性是否改善。重复循环,直到绝大多数测试用例达标。

整体流程:

写 description——准备 trigger / non-trigger 测试——运行测试——找误触发 / 漏触发——修改 description——重新测试——看validation

Note

好的description = 用户意图 + 适用场景 + 隐含触发场景 + 清晰边界

Tip

一般先写body content,再写description,body content是告诉agent这个skill能干什么,description是告诉agent这个skill什么时候触发。

skill evaluation

写完body content和description后,skill就可以使用了,但是我们需要知道Skill到底有没有真的让结果变好。我们需要对其进行评估,评估不是简单的使用几遍后感觉良好,需要做结构化eval.

设计真实测试案例,每个 test case 包含:用户 prompt、你期待的结果、可选输入文件等。将同一个任务用skill和不用skill进行对比,每次使用干净的session。第一次结果输出后写assertion,用于后续机器判断,好的assertion能明确验证成功标准,不要过于死板,不要太模糊,比如:

之后可以通过机器和人工审核来判断,机器用于检测代码以及输出格式等是否正确,人工评审主观质量。机器判断可以根据断言和输出结果来打分,打分要有证据。还要结合tooken消耗量,时间,通过率等判断。判断后即可优化。assertion也很重要,关系着打分是否合理。

关于assertion优化:

情况意味着什么
有 Skill / 没 Skill 都 PASSSkill 对这件事可能没贡献(可以删除或者修改)
有 Skill / 没 Skill 都 FAIL测试有问题,或者 Skill 根本没解决
有 Skill PASS、没 Skill FAIL这是 Skill 真正创造的价值
同一测试忽好忽坏Skill 指令可能模糊或模型随机性较大

优化 Skill
获取 3 类信号来修改 skill

把当前SKILL.md + 全部信号交给 LLM,生成修改建议,遵循原则:

优化后重复操作,同时和之前对比有无提升。

整体流程:
设计测试案例 → 建立评估标准 → Skill / 无 Skill 对比 → 自动 + 人工评估 → 分析失败原因 → 优化 Skill → 重新验证

scripts/

简单脚本比如一次性命令uv pipx等不需要写在这里面,直接在skill.md里面写即可,锁定版本,保证行为可复现,写明环境依赖即可。如果是复杂脚本,skill.md中写相对于skill.md根目录的相对路径,明确列出可用脚本。不要写交互式脚本,脚本要提供有用的错误信息,比如找不到文件,缺少必须参数等,优先结构化输出,建议每个脚本写一个—help.

scripts/目录下脚本应该尽量自包含,自包含脚本是指脚本中包含了所有必要的依赖,不需要外部环境支持。比如:

# /// script
# dependencies = [
#   "beautifulsoup4",
# ]
# ///

from bs4 import BeautifulSoup

# 示例 HTML 内容
html = '<html><body><h1>Welcome</h1><p class="info">RUNOOB 测试</p></body></html>'

# 使用 BeautifulSoup 解析 HTML
soup = BeautifulSoup(html, "html.parser")

# 提取 class="info" 的段落文本
info_text = soup.select_one("p.info").get_text()
print(info_text)

进一步建议

参数传递与接收

skill.md里面可以通过自然语言描述,告诉agent需要从上下文中提取哪些信息。agent 会根据这份说明,主动从上下文中提取信息,或在信息不足时向用户追问。比如:

---
name: csv-analyzer
description: 分析用户上传的 CSV 文件,输出统计摘要。当用户提到 CSV、表格数据分析时触发。
---

# CSV 分析器

## 输入要求

用户应提供以下信息(从对话上下文中获取):
- **文件路径**:已上传 CSV 文件的路径(位于 /mnt/user-data/uploads/)
- **分析目标**(可选):用户希望了解什么,如"找出空值"、"统计分布"
- **输出格式**(可选):表格、图表或文字摘要

若上述信息未明确,主动向用户确认后再执行。

也可以通过脚本传递,Skill 脚本在执行前,应始终验证关键参数是否合法。这可以防止因参数缺失或格式错误导致的运行时崩溃。参数验证的失败信息应清晰说明期望什么和实际得到什么,方便 agent 向用户反馈具体原因。


Edit page
Share this post:

Previous Post
ai恐怖小游戏
Next Post
agent skills笔记