技能创建者的最佳实践#
如何编写范围明确、且针对任务校准良好的技能。
从真实的专业经验开始#
技能创建中一个常见的陷阱是:在不提供特定领域上下文的情况下,要求 LLM 生成技能 —— 仅仅依赖于 LLM 的通用训练知识。其结果往往是模糊、通用的流程(如“妥善处理错误”、“遵循身份验证的最佳实践”),而不是那些使技能具有真正价值的具体 API 模式、边缘情况和项目约定。
有效的技能往往根植于真实的专业经验。其关键在于将特定领域上下文馈送到创建过程中。
从实际任务中提取#
在与 Agent 的对话中完成一个真实任务,并在此过程中提供上下文、更正和偏好。然后,将这种可复用的模式提取成技能。请关注以下几点:
- 奏效的步骤 —— 指向成功的行动序列。
- 你做出的更正 —— 你引导 Agent 方法的地方(例如,“使用库 X 而不是 Y”、“检查边缘情况 Z”)。
- 输入/输出格式 —— 数据进入和输出时的样子。
- 你提供的上下文 —— Agent 之前不知道的特定于项目的实施、约定或约束。
从现有项目资产中合成#
当你拥有大量的现有知识时,你可以将其提供给 LLM 并要求它合成为一项技能。通过你团队真实的事故报告和运行手册(Runbooks)合成的数据管道技能,其表现将优于从通用的“数据工程最佳实践”文章中合成的技能,因为它捕获了你的 Schema、故障模式和恢复程序。关键在于特定于项目的材料,而非通用参考资料。
良好的源材料包括:
- 内部文档、运行手册和风格指南。
- API 规范、Schema 和配置文件。
- 代码评审建议和问题追踪器(捕获了反复出现的关注点和评审者的预期)。
- 版本控制历史,特别是补丁和修复(通过实际发生的更改揭示模式)。
- 真实的失败案例及其解决方案。
通过实际执行进行微调#
技能的初稿通常需要进一步细化。针对实际任务运行该技能,然后将结果(包括成功的和失败的)反馈回创建过程。思考:是什么触发了误报?遗漏了什么?哪些部分可以删减?
即使仅进行一次“执行-修订”循环,也能显著提高质量;对于复杂的领域,通常需要进行多次迭代。
阅读 Agent 的执行痕迹(Traces),而不仅仅是最终输出。如果 Agent 在生产力较低的步骤上浪费时间,常见原因包括:指令过于模糊(Agent 在找到可行方法前尝试了多种方法)、指令不适用于当前任务(但 Agent 仍然遵循了它们),或者在没有明确默认值的情况下提供了过多的选项。
关于结构化的迭代方法(包括测试案例、断言和评分),请参阅评估技能输出质量。
明智地消耗上下文#
一旦技能被激活,其完整的 SKILL.md 正文将与对话历史、系统上下文和其他活动技能一起加载到 Agent 的上下文窗口中。你技能中的每一个 Token 都在与该窗口中的其他内容竞争 Agent 的注意力。
增加 Agent 缺乏的信息,省略它已知的内容#
重点关注那些 Agent 在没有你的技能的情况下无法确知的内容:项目特定的约定、特定领域的流程、不明显的边缘情况,以及要使用的特定工具或 API。你不需要解释什么是 PDF、HTTP 如何工作或数据库迁移的作用。
<!-- 过于冗长 —— Agent 已经知道 PDF 是什么了 -->
## 提取 PDF 文本
PDF(便携式文档格式)文件是一种常见的包含文本、图像和其他内容的文件格式。
要从 PDF 中提取文本,你需要使用一个库。推荐使用 pdfplumber,因为它能很好地处理大多数情况。
<!-- 更好 —— 直接进入 Agent 无法自行获知的内容 -->
## 提取 PDF 文本
优先使用 pdfplumber 进行文本提取。对于扫描文档,请回退到使用 pdf2image 配合 pytesseract。
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
```对每一项内容都问问自己:“如果没有这条指令,Agent 会做错吗?”如果答案是否定的,请删掉它。如果你不确定,请测试它。如果 Agent 在没有该技能的情况下也能很好地处理整个任务,那么该技能可能没有增加价值。请参阅评估技能输出质量了解如何进行系统化测试。
设计连贯的单元#
决定一项技能应该包含什么,就像决定一个函数应该做什么一样:你希望它封装一个能与其他技能良好组合的连贯工作单元。范围过窄的技能会迫使单次任务加载多个技能,从而带来开销和指令冲突的风险。范围过宽的技能则难以精确激活。一项用于查询数据库并格式化结果的技能可能是一个连贯的单元,而如果该技能还涉及数据库管理,那么它可能承担了过多的职责。
追求中等的详细程度#
过于详尽的技能可能会弊大于利 —— Agent 难以提取相关信息,并可能因不适用于当前任务的指令而触发无效率的路径。简洁的、逐步的指导配合工作示例,表现往往优于详尽的文档。当你发现自己正在覆盖每一个边缘情况时,请考虑大多数情况是否更适合由 Agent 自身的判断来处理。
使用渐进式表现结构化大型技能#
规范建议将 SKILL.md 保持在 500 行和 5,000 个 Token 以内 —— 仅包含 Agent 每次运行核心所需的指令。当技能确实需要更多内容时,请将详细的参考资料移动到 references/ 或类似目录下的单独文件中。
关键在于告诉 Agent 何时加载每个文件。“如果 API 返回非 200 状态码,请阅读 references/api-errors.md”比通用的“详情请见 references/”更有用。这让 Agent 能根据需求加载上下文,而不是预先加载,这正是渐进式表现(Progressive Disclosure)的设计初衷。
校准控制力#
并非技能的每个部分都需要相同程度的指令性。请使你指令的明确程度与任务的脆弱性相匹配。
使明确程度与脆弱性匹配#
当有多种方法有效且任务允许变化时,赋予 Agent 自由度。对于灵活的指令,解释“为什么”可能比僵化的指令更有效 —— 了解指令背后意图的 Agent 能做出更好的依赖上下文的决策。一个代码评审技能可以描述寻找什么,而不必规定具体步骤:
## 代码评审流程
1. 检查所有数据库查询是否存在 SQL 注入(使用参数化查询)
2. 验证每个端点的身份验证检查
3. 寻找并发代码路径中的竞态条件
4. 确认错误消息不会泄露内部细节当操作非常敏感、一致性至关重要或必须遵循特定顺序时,请保持高度的指令性:
## 数据库迁移
请严格执行以下序列:
```bash
python scripts/migrate.py --verify --backup
```
请勿修改命令或添加其他 Flag。大多数技能都包含这两者的混合。请独立地校准每个部分。
提供默认选项,而非菜单式选择#
当有多种工具或方法可行时,请选择一个默认方案并简要提及替代方案,而不是将它们作为对等的选项罗列。
<!-- 选项过多 -->
你可以使用 pypdf、pdfplumber、PyMuPDF 或 pdf2image...
````markdown
<!-- 带有退出机制的明确默认方案 -->
使用 pdfplumber 进行文本提取:
```python
import pdfplumber对于需要 OCR 的扫描 PDF,请改用 pdf2image 配合 pytesseract。
### 优先考虑流程而非声明
技能应该教会 Agent **如何处理**一类问题,而不是在特定情况下**应该产出什么**。对比:
```markdown
<!-- 具体答案 —— 仅对本次特定任务有用 -->
将 `orders` 表通过 `customer_id` 与 `customers` 表关联,过滤 `region = 'EMEA'`,并对 `amount` 列求和。
<!-- 可复用的方法 —— 对任何分析查询都有效 -->
1. 阅读 `references/schema.yaml` 中的 Schema 以找到相关表
2. 使用 `_id` 外键约定关联表
3. 将用户请求中的任何过滤器作为 WHERE 子句应用
4. 根据需要聚合数值列,并格式化为 Markdown 表格这并不意味着技能不能包含特定细节 —— 输出格式模板(见输出格式模板)、约束条件(如“绝不输出 PII 敏感信息”)和工具特定的指令都是很有价值的。重点在于:即使单个细节是具体的,其方法论也应该是通用的。
有效指令的模式#
这些是用于结构化技能内容的复用技术。并非每项技能都需要全部技术 —— 请使用适合你任务的技术。
“Gotchas”(注意事项)部分#
在许多技能中,价值最高的内容是一系列“Gotchas” —— 那些违反常规假设的环境特定事实。这些不是通用的建议(如“妥善处理错误”),而是对 Agent 在没有被告知的情况下会犯的错误的具体纠正:
## 注意事项(Gotchas)
- `users` 表使用软删除。查询必须包含 `WHERE deleted_at IS NULL`,否则结果将包含已停用的账户。
- 用户 ID 在数据库中是 `user_id`,在身份验证服务中是 `uid`,在计费 API 中是 `accountId`。这三个值指向相同的实体。
- 只要 Web 服务器在运行,`/health` 端点就会返回 200,即使数据库连接已断开。请使用 `/ready` 来检查完整的服务健康状况。将 Gotchas 保留在 SKILL.md 中,以便 Agent 在遇到具体情况前就能阅读它们。如果告诉 Agent 何时加载,单独的参考文件也可以,但对于非显而易见的问题,Agent 可能无法识别触发时机。
当 Agent 犯了你必须纠正的错误时,请将该纠正添加到 Gotchas 部分。这是迭代式改进技能最直接的方法之一(见通过实际执行进行微调)。
输出格式模板#
当你需要 Agent 以特定格式产出输出时,请提供模板。这比用散文描述格式更可靠,因为 Agent 非常擅长针对具体结构进行模式匹配。简短的模板可以内联在 SKILL.md 中;对于较长的模板,或仅在某些情况下需要的模板,请将它们存储在 assets/ 中并在 SKILL.md 中引用,以便它们仅在需要时加载。
## 报告结构
使用此模板,并根据具体分析的需要调整各部分:
```markdown
# [分析标题]
## 执行摘要
[对关键发现的单段概述]
## 关键发现
- 带有支持数据的发现 1
- 带有支持数据的发现 2
## 建议
1. 具体的、可操作的建议
2. 具体的、可操作的建议
```多步工作流的清单#
明确的清单有助于 Agent 跟踪进度并避免跳过步骤,特别是当步骤之间存在依赖关系或验证门限时。
## 表单处理工作流
进度:
- [ ] 步骤 1:分析表单(运行 `scripts/analyze_form.py`)
- [ ] 步骤 2:创建字段映射(编辑 `fields.json`)
- [ ] 步骤 3:验证映射(运行 `scripts/validate_fields.py`)
- [ ] 步骤 4:填写表单(运行 `scripts/fill_form.py`)
- [ ] 步骤 5:验证输出(运行 `scripts/verify_output.py`)验证循环#
指示 Agent 在进入下一步之前验证自己的工作。模式是:完成工作,运行验证器(脚本、参考清单或自检),修复任何问题,并重复直到验证通过。
## 编辑工作流
1. 进行编辑
2. 运行验证:`python scripts/validate.py output/`
3. 如果验证失败:
- 检查错误消息
- 修复问题
- 再次运行验证
4. 仅在验证通过时继续参考文档也可以作为“验证器” —— 指示 Agent 在最终确定前针对参考文档检查其工作。
计划-验证-执行#
对于批处理或破坏性操作,让 Agent 以结构化格式创建一个中间计划,针对真实数据来源验证该计划,然后再执行。
## 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:一个根据真实数据(form_fields.json)检查计划(field_values.json)的验证脚本。诸如“未找到字段 ‘signature_date’ —— 可用字段为:customer_name, order_total, signature_date_signed”之类的错误消息能为 Agent 提供足够的自纠正信息。
捆绑可重用的脚本#
在迭代技能时,比较 Agent 在不同测试用例下的执行痕迹。如果你发现 Agent 每次运行都在独立地“重新制造轮子” —— 构建图表、解析特定格式、验证输出 —— 这是一个信号,说明你应该编写一个经过测试的脚本并将其捆绑在 scripts/ 中。
更多关于设计和捆绑脚本的内容,请参阅在技能中使用脚本。
下一步#
一旦你拥有了一个可运行的技能,以下两份指南可以帮助你进一步完善它: