skill 技巧

3510 字
18 分钟
skill 技巧

如何编写范围明确且与任务相匹配的技能。

1. 从真正的专业知识出发#

技能创建中一个常见的误区是,让 LLM 在不提供特定领域上下文的情况下生成技能——完全依赖 LLM 的通用训练知识。这样得到的结果往往是模糊、泛泛的流程(例如 “handle errors appropriately”, “follow best practices for authentication”),而非具体的 API 模式、边缘情况和项目约定——而这些正是让技能变得有价值的东西。

有效的技能植根于真正的专业知识。关键在于将特定领域的上下文注入创建过程。

1.1 从实际操作任务中提炼#

在与代理的对话中完成一个真实任务,过程中提供上下文、纠正和偏好。然后,将可复用的模式提炼为技能。注意以下几点:

  • 有效的步骤——通向成功的动作序列
  • 你做的纠正——你引导代理调整方向的地方(例如,“用 X 库而不是 Y 库”“检查边缘情况 Z”)
  • 输入/输出格式——数据输入和输出时的样子
  • 你提供的上下文——代理尚不知道的项目特定事实、约定或约束

1.2 从现有项目产物中综合#

当你拥有大量既有知识时,可以将其输入 LLM,并要求其综合出一个技能。从团队实际的事故报告和运维手册中综合出的数据管道技能,会比从一篇泛泛的 “data engineering best practices” 文章中综合出的技能表现更好,因为它捕捉了你的数据模式、故障模式和恢复流程。关键在于使用项目特定的材料,而非泛泛的参考资料。

好的源材料包括:

  • 内部文档、运维手册和风格指南
  • API 规范、模式(schema)和配置文件
  • 代码评审意见和问题跟踪器(捕捉反复出现的问题和评审者的期望)
  • 版本控制历史,尤其是补丁和修复(通过实际变更揭示模式)
  • 真实世界的失败案例及其解决方案

2. 通过实际运行来改进#

技能的第一稿通常需要改进。用真实任务运行技能,然后将结果——不仅仅是失败的结果——全部反馈到创建过程中。问自己:什么触发了误报?遗漏了什么?哪些可以删掉?

即使只做一次“执行-修改”的循环,也能明显提升质量,而复杂领域通常受益于多次循环。

Tip

阅读代理的执行轨迹,而不仅仅是最终输出。如果代理在无效步骤上浪费时间,常见原因包括:指令过于模糊(代理尝试多种方法才找到可行的一种)、指令不适用于当前任务(代理仍然照做)、或者提供了太多选项却没有明确的默认值。

如需更结构化的迭代方法,包括测试用例、断言和评分,请参阅skill 评估

3. 明智地使用上下文#

一旦技能被激活,其完整的 SKILL.md 正文就会加载到代理的上下文窗口中,连同对话历史、系统上下文和其他激活的技能一起。技能中的每一个 token 都在与窗口中的其他内容争夺代理的注意力。

3.1 增加代理缺乏的,省略代理已知的#

专注于代理 没有 你的技能就不会知道的内容:项目特定的约定、领域特定的流程、不明显的边缘情况,以及要使用的特定工具或 API。你不需要解释 PDF 是什么、HTTP 如何工作,或者数据库迁移是做什么的。

<!-- 过于冗长——代理已经知道 PDF 是什么 -->
## 提取 PDF 文本
PDF(便携式文档格式)文件是一种常见的文件格式,包含
文本、图像和其他内容。要从 PDF 中提取文本,你需要
使用一个库。推荐使用 pdfplumber,因为它能很好地处理大多数情况。
<!-- 更好——直接切入代理靠自己不会知道的内容 -->
## 提取 PDF 文本
使用 pdfplumber 进行文本提取。对于扫描文档,回退使用
pdf2image 搭配 pytesseract。
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
```

针对每部分内容问自己:“如果没有这条指令,代理会不会犯错?”如果答案是否定的,就删掉。如果不确定,就测试一下。如果代理不需要技能就能很好地完成整个任务,那么这个技能可能没有增加价值。关于如何系统性地测试,请参阅skill 评估

3.2 设计内聚的单元#

决定一个技能应该涵盖什么,类似于决定一个函数应该做什么:你希望它封装一个内聚的工作单元,并能与其他技能良好组合。范围过窄的技能会迫使单个任务加载多个技能,带来开销和指令冲突的风险。范围过宽的技能则难以精确激活。一个用于查询数据库并格式化结果的技能可能是一个内聚的单元,而一个同时涵盖数据库管理的技能则可能试图做得太多。

3.3 力求适度的详细程度#

过于全面的技能弊大于利——代理难以提取相关部分,并可能因不适用于当前任务的指令而走上无效路径。简洁、分步的指导加上可运行的示例,往往比详尽的文档更有效。当你发现自己正在覆盖每一个边缘情况时,请考虑其中大多数是否更适合由代理自己的判断来处理。

3.4 通过渐进式披露组织大型技能#

agentskills.io 规范建议将 SKILL.md 控制在 500 行和 5,000 个 token 以内——即代理每次运行所需的核心指令。当技能确实需要更多内容时,应将详细的参考材料移至 references/ 或类似目录中的单独文件。

关键在于告诉代理 何时 加载每个文件。“如果 API 返回非 200 状态码,请阅读 references/api-errors.md”比泛泛的 “参见 references/ 中的详情” 更有用。这能让代理按需加载上下文,而不是预先加载,这正是 渐进式披露 的设计初衷。

4. 校准控制粒度#

并非技能的每个部分都需要同样的指令强度。根据任务的脆弱性来匹配指令的具体程度。

4.1 根据脆弱性匹配具体程度#

给代理自由,当多种方法都有效且任务允许变化时。对于灵活的指令,解释 原因 可能比严格的指令更有效——理解指令背后目的的代理能做出更好的、依赖上下文的决策。代码审查技能可以描述要关注什么,而不必规定具体步骤:

## 代码审查流程
1. 检查所有数据库查询是否存在 SQL 注入(使用参数化查询)
2. 验证每个端点上的身份验证检查
3. 在并发代码路径中查找竞态条件
4. 确认错误消息不会泄露内部细节

提供明确的指令,当操作脆弱、一致性重要,或必须遵循特定顺序时:

## 数据库迁移
请精确运行以下命令序列:
```bash
python scripts/migrate.py --verify --backup
```
不要修改命令或添加其他标志。

大多数技能都是混合的。请独立校准每个部分。

4.2 提供默认值,而不是菜单#

当多种工具或方法都可行时,选择一个默认值,并简要提及替代方案,而不是将它们作为同等选项呈现。

<!-- 选项太多 -->
你可以使用 pypdf、pdfplumber、PyMuPDF 或 pdf2image...
<!-- 明确的默认值,附有备用方案 -->
使用 pdfplumber 进行文本提取:
```python
import pdfplumber
```
对于需要 OCR 的扫描 PDF,请使用 pdf2image 搭配 pytesseract 作为替代。

4.3 倾向于流程而非声明#

技能应该教会代理 如何处理 一类问题,而不是针对特定实例 生成什么。比较以下两者:

<!-- 特定答案——仅对此确切任务有用 -->
`orders` 表与 `customers` 表按 `customer_id` 连接,筛选
`region = 'EMEA'`,并对 `amount` 列求和。
<!-- 可复用的方法——适用于任何分析查询 -->
1.`references/schema.yaml` 读取 schema,查找相关表
2. 使用 `_id` 外键约定连接表
3. 根据用户请求中的筛选条件应用 WHERE 子句
4. 根据需要聚合数值列,并格式化为 markdown 表格

这并不意味着技能不能包含具体细节——输出格式模板、约束条件如 “绝不输出 PII” 以及特定工具指令都很有价值。关键在于,即使个别细节是具体的,方法 本身应该具有通用性。

5. 有效指令的模式#

这些是组织技能内容的可复用技巧。并非每个技能都需要全部——请使用适合你任务的那些。

5.1 易错点(Gotchas)部分#

许多技能中价值最高的内容是一份易错点列表——那些违背合理假设的环境特定事实。这些不是泛泛的建议(“妥善处理错误”),而是具体的纠正,让代理在未被明确告知时避免犯错:

## 易错点
- `users` 表使用软删除。查询必须包含
`WHERE deleted_at IS NULL`,否则结果会包含已停用的账户。
- 用户 ID 在数据库中是 `user_id`,在认证服务中是 `uid`
在计费 API 中是 `accountId`。这三个值指向同一个实体。
- `/health` 端点只要 Web 服务器在运行就返回 200,
即使数据库连接已断开。请使用 `/ready` 来检查完整的服务健康状态。

请将易错点放在 SKILL.md 中,以便代理在遇到情况前读到它们。如果使用单独的参考文件,则需要告诉代理何时加载,但对于不明显的问题,代理可能无法识别触发条件。

Tip

当代理犯错而你不得不纠正时,请将纠正内容添加到易错点部分。这是迭代改进技能最直接的方法之一。

5.2 输出格式模板#

当你需要代理以特定格式生成输出时,请提供一个模板。这比用文字描述格式更可靠,因为代理对具体结构有很好的模式匹配能力。简短的模板可以直接放在 SKILL.md 中;对于较长的模板,或仅在特定情况下需要的模板,请将它们存储在 assets/ 中,并在 SKILL.md 中引用,以便仅在需要时加载。

## 报告结构
使用此模板,并根据具体分析调整各部分:
```markdown
# [分析标题]
## 执行摘要
[关键发现的一段落概述]
## 主要发现
- 发现 1,附带支持数据
- 发现 2,附带支持数据
## 建议
1. 具体可操作的建议
2. 具体可操作的建议
```

5.3 多步骤工作流的检查清单#

明确的检查清单有助于代理跟踪进度并避免跳过步骤,尤其是在步骤之间存在依赖或验证门槛时。

## 表单处理工作流
进度:
- [ ] 步骤 1:分析表单(运行 `scripts/analyze_form.py`
- [ ] 步骤 2:创建字段映射(编辑 `fields.json`
- [ ] 步骤 3:验证映射(运行 `scripts/validate_fields.py`
- [ ] 步骤 4:填写表单(运行 `scripts/fill_form.py`
- [ ] 步骤 5:验证输出(运行 `scripts/verify_output.py`

5.4 验证循环#

指示代理在继续之前验证自己的工作。模式是:执行工作、运行验证器(脚本、参考检查清单或自检)、修复问题、重复直到验证通过。

## 编辑工作流
1. 进行编辑
2. 运行验证:`python scripts/validate.py output/`
3. 如果验证失败:
- 查看错误消息
- 修复问题
- 再次运行验证
4. 仅在验证通过后才继续

参考文档也可以充当“验证器”——指示代理在最终确定之前,根据参考文档检查其工作。

5.5 计划-验证-执行#

对于批量操作或破坏性操作,让代理以结构化格式创建中间计划,根据事实来源进行验证,然后才执行。

## PDF 表单填写
1. 提取表单字段:`python scripts/analyze_form.py input.pdf``form_fields.json`
(列出每个字段名称、类型以及是否为必填)
2. 创建 `field_values.json`,将每个字段名称映射到其预期值
3. 验证:`python scripts/validate_fields.py form_fields.json field_values.json`
(检查每个字段名称在表单中是否存在、类型是否兼容、必填字段是否缺失)
4. 如果验证失败,修改 `field_values.json` 并重新验证
5. 填写表单:`python scripts/fill_form.py input.pdf field_values.json output.pdf`

关键要素是步骤 3:一个验证脚本,用于检查计划(field_values.json)是否符合事实来源(form_fields.json)。像“未找到字段 ‘signature_date’——可用字段:customer_name, order_total, signature_date_signed”这样的错误信息,为代理提供了足够的信息来自我修正。

5.6 捆绑可复用脚本#

迭代技能 时,比较代理在不同测试用例中的执行轨迹。如果你注意到代理每次运行都在独立地重复发明相同的逻辑——构建图表、解析特定格式、验证输出——那就说明应该编写一次经过测试的脚本,并将其捆绑在 scripts/ 中。

关于设计和捆绑脚本的更多信息,请参阅 skill 脚本

6. 后续步骤#

当你有了一个可以运行的 skill 后,你可以参考这些优化你的 skill:

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

skill 技巧
https://agentskills.io/
作者
HAC
发布于
2026-07-08
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
HAC
观之非易,行且克难
Greetings
欢迎来到我的博客!这里主要分享我的学习笔记与兴趣爱好。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
5
标签
13
总字数
79,889
运行时长
0
最后活动
0 天前

文章目录