最佳实践
编写高质量的 Skill 不仅是技术问题,更是设计问题。本章总结了一系列最佳实践,帮助你创建专业、可维护、高效的 Skills。
从真实专业经验出发
编写有效 Skill 的一个常见误区是让 LLM 在没有提供领域特定上下文的情况下生成 Skill——仅依赖 LLM 的一般训练知识。结果是模糊、通用的流程(如"适当处理错误"、"遵循认证最佳实践"),而不是具体的 API 模式、边界情况和项目约定。
有效的 Skill 必须基于真实的专业经验。
从实际任务中提取
在与 Agent 协作完成真实任务的过程中,提供上下文、纠正和偏好,然后提取可复用的模式。关注以下方面:
- 成功的步骤:导致成功的操作序列是什么?
- 你做的纠正:你引导 Agent 方法的地方(如"用库 X 代替 Y"、"检查边界情况 Z")
- 输入/输出格式:数据进出时的样子是什么?
- 你提供的上下文:Agent 不知道的项目特定事实、约定或约束
从现有项目文档中综合
当你有现有的知识体系时,可以将其综合成一个 Skill。从团队实际事故报告和运维手册综合的数据管道 Skill,将优于从通用"数据工程最佳实践"文章综合的 Skill,因为它捕获了你的模式、故障模式和恢复程序。
好的源材料包括:
- 内部文档、运维手册和风格指南
- API 规范、模式和配置文件
- 代码审查评论和问题跟踪器(捕获重复关注点和审查者期望)
- 版本控制历史,特别是补丁和修复(通过实际变更揭示模式)
- 真实的故障案例及其解决方案
用真实执行来优化
Skill 的初稿通常需要优化。针对真实任务运行 Skill,然后将结果——所有的结果,不仅仅是失败的——反馈到创建过程中。问:
- 什么触发了误报?
- 什么被遗漏了?
- 什么可以删减?
即使只有一次执行-然后-修订的流程也能显著提高质量,复杂领域通常需要几次迭代。
核心原则
简洁是关键
上下文窗口是公共资源。你的 Skill 与 Agent 需要知道的其他所有内容共享上下文窗口,包括:
- 对话历史
- 系统上下文
- 其他活跃的 Skills
并非 Skill 中的每个 token 都有即时成本。启动时,只预加载所有 Skill 的元数据(name 和 description)。Agent 只在 Skill 变得相关时才读取 SKILL.md,并只在需要时读取额外文件。然而,保持 SKILL.md 简洁仍然很重要:一旦 Agent 加载了它,每个 token 都会与对话历史和其他上下文竞争。
默认假设:Agent 已经很聪明
只添加 Agent 还没有的上下文。质疑每条信息:
# 好的例子:简洁(约 50 tokens)
## 提取 PDF 文本
使用 pdfplumber 进行文本提取:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
不好的例子:太啰嗦(约 150 tokens)
提取 PDF 文本
PDF(便携式文档格式)文件是一种常见的文件格式,包含文本、图像和其他内容。要从 PDF 中提取文本,你需要使用库。有很多库可用于 PDF 处理,但推荐使用 pdfplumber,因为它易于使用且能很好地处理大多数情况。首先,你需要使用 pip 安装它。然后你可以使用下面的代码...
简洁版本假设 Agent 知道 PDF 是什么以及库是如何工作的。
### 设置适当的自由度
根据任务的脆弱性和多变性,匹配指令的具体程度。
**高自由度**(基于文本的指令):当多种方法有效且任务可容忍变化时使用。
```markdown
## 代码审查流程
1. 分析代码结构和组织
2. 检查潜在的 bug 或边界情况
3. 建议可读性和可维护性改进
4. 验证是否遵循项目约定
中等自由度(伪代码或带参数的脚本):当有经过验证的方法但需要调整参数时使用。
## 生成报告
使用此模板并按需自定义:
```python
def generate_report(data, format="markdown", include_charts=True):
# 处理数据
# 以指定格式生成输出
# 可选地包含可视化
**低自由度**(特定脚本,很少或没有参数):当操作脆弱、一致性重要或必须遵循特定顺序时使用。
```markdown
## 数据库迁移
严格运行此脚本:
```bash
python scripts/migrate.py --verify --backup
不要修改命令或添加额外参数。
**类比**:把 Agent 想象成探索路径的机器人:
- 高自由度:给它一个目的地,让它自己找路
- 中等自由度:给出路线建议,但允许根据路况调整
- 低自由度:给出详细地图和必须遵循的具体路线
## 设计原则
### 单一职责原则
每个 Skill 应该专注于一个明确的任务。不要试图创建"全能型" Skill。
❌ 违反单一职责 name: "code-helper" description: "帮助编写、审查、测试和优化代码"
✅ 遵循单一职责 name: "code-reviewer" description: "审查代码质量,发现潜在问题"
name: "test-generator" description: "为代码生成单元测试"
name: "code-formatter" description: "按照规范格式化代码"
单一职责的好处:
- 更容易触发:description 更精准
- 更易维护:修改不会影响其他功能
- 更易复用:可以灵活组合多个 Skills
### 明确边界原则
Skill 应该明确说明它的适用范围和边界。
```markdown
## 适用范围
- Python 3.8+ 代码
- 单文件或代码片段
- 项目代码(非库代码)
## 不适用场景
- 其他编程语言
- 整个项目审查
- 库 API 设计审查
## 边界情况处理
- 空文件:提示用户
- 超大文件(>500 行):建议分批审查
- 非代码文件:跳过并提示
渐进式信息原则
指令应该从简单到复杂,从概览到细节。
## 审查流程
### 第一阶段:快速扫描(30 秒)
快速识别明显问题:
- 语法错误
- 导入问题
- 命名规范
### 第二阶段:详细审查(5 分钟)
逐项检查:
- 类型注解
- 文档字符串
- 错误处理
### 第三阶段:深度分析(可选)
针对关键代码:
- 性能分析
- 安全审计
- 可维护性评估
Description 编写技巧
功能 + 触发条件公式
description 应该遵循"功能描述 + 触发条件"的格式:
[功能描述]。当用户 [触发条件] 时触发。
示例:
description: "审查 Python 代码质量,检查 PEP 8 规范和潜在问题。当用户请求代码审查、代码检查、code review 或提交 Python 代码时触发。"
关键词覆盖
列出用户可能使用的各种说法:
description: "为代码生成单元测试。当用户请求生成测试、写测试、添加单元测试、创建测试用例或 test coverage 时触发。"
排除条件
如果需要避免误触发,可以添加排除条件:
description: "审查 Python 代码质量。当用户请求代码审查时触发。注意:不适用于代码编写、代码调试或代码解释场景。"
指令编写技巧
使用检查清单
检查清单让 AI 系统地执行任务:
## 检查清单
在审查代码时,请逐项检查以下内容:
### 命名规范
- [ ] 变量名使用 snake_case
- [ ] 类名使用 PascalCase
- [ ] 常量使用全大写 SNAKE_CASE
- [ ] 私有属性以单下划线开头
- [ ] 名称具有描述性,避免单字母(循环变量除外)
### 类型注解
- [ ] 函数参数有类型注解
- [ ] 返回值有类型注解
- [ ] 复杂类型使用 typing 模块
- [ ] Optional 类型正确使用
### 文档
- [ ] 模块有 docstring
- [ ] 公共函数有 docstring
- [ ] docstring 格式一致
提供示例
示例比抽象描述更有效:
## 输出示例
### 📊 审查摘要
- 文件:user_service.py
- 问题总数:5
### 🔴 严重问题
| 行号 | 问题描述 | 修改建议 |
|------|----------|----------|
| 15 | 未处理可能的 None 值 | 添加 None 检查 |
| 42 | 资源未关闭 | 使用 with 语句 |
### 🟡 警告
| 行号 | 问题描述 | 修改建议 |
|------|----------|----------|
| 8 | 缺少类型注解 | 添加参数和返回值类型 |
| 23 | 行长度超过 88 字符 | 拆分长行 |
### 📝 总体评价
代码整体结构清晰,但存在一些需要改进的地方。建议优先修复严重问题。(评分:7/10)
定义优先级
明确问题的优先级,帮助用户聚焦:
## 问题优先级
### 🔴 严重(必须修复)
- 可能导致运行时错误
- 安全漏洞
- 数据丢失风险
### 🟡 警告(建议修复)
- 代码风格问题
- 性能问题
- 可维护性问题
### 🔵 建议(可选优化)
- 代码简化建议
- 文档改进建议
- 测试覆盖建议
组织多个 Skills
技能组合
多个 Skills 可以组合成工作流:
项目开发工作流:
1. code-formatter → 格式化代码
2. code-reviewer → 审查代码质量
3. test-generator → 生成测试
4. doc-generator → 生成文档
避免功能重叠
确保不同 Skills 之间没有功能重叠:
❌ 功能重叠
skill-a: "审查 Python 代码风格"
skill-b: "检查 Python 代码规范"
✅ 功能互补
skill-a: "审查 Python 代码风格(PEP 8)"
skill-b: "检查 Python 类型注解正确性"
建立技能库
为团队建立统一的技能库:
team-skills/
├── python/
│ ├── code-reviewer/
│ ├── test-generator/
│ └── doc-generator/
├── frontend/
│ ├── react-reviewer/
│ └── css-linter/
└── devops/
├── docker-reviewer/
└── ci-cd-generator/
版本管理
版本号规范
使用语义化版本号:
---
name: "code-reviewer"
version: "1.2.0"
---
版本号格式:主版本号.次版本号.修订号
- 主版本号:不兼容的重大变更
- 次版本号:向后兼容的功能新增
- 修订号:向后兼容的问题修复
变更日志
在 Skill 文件中记录变更:
## 变更日志
### v1.2.0 (2026-01-15)
- 新增:支持异步代码审查
- 改进:优化输出格式
### v1.1.0 (2026-01-01)
- 新增:支持类型注解检查
- 修复:空文件处理问题
### v1.0.0 (2025-12-20)
- 初始版本
性能优化
控制指令长度
过长的指令会增加 Token 消耗和响应时间:
❌ 过长的指令(5000+ 字符)
包含大量重复内容、冗长解释
✅ 适中的指令(1000-3000 字符)
精炼、结构化、无冗余
按需加载
利用 description 实现按需加载:
description: "审查 Python 代码。仅在用户明确请求代码审查时触发。"
分层指令
对于复杂任务,可以使用分层指令:
## 基础审查(默认执行)
- 语法检查
- 风格检查
## 深度审查(用户请求时执行)
- 性能分析
- 安全审计
测试与验证
测试用例
为 Skill 准备测试用例:
## 测试用例
### 用例 1:正常代码
输入:符合规范的 Python 代码
预期:通过审查,无严重问题
### 用例 2:问题代码
输入:包含明显问题的代码
预期:正确识别并报告问题
### 用例 3:边界情况
输入:空文件
预期:友好提示,不报错
### 用例 4:误触发测试
输入:"帮我写一个 Python 函数"
预期:不触发此 Skill
持续改进
根据使用反馈持续改进:
- 收集用户反馈
- 分析触发准确性
- 优化输出质量
- 更新文档和示例
常见陷阱
陷阱一:过度抽象
❌ 过度抽象
description: "处理文本"
✅ 具体明确
description: "审查 Python 代码质量,检查 PEP 8 规范"
陷阱二:指令冲突
❌ 指令冲突
"检查所有代码风格问题,但忽略命名规范"
✅ 指令一致
"检查所有代码风格问题,包括命名规范"
陷阱三:忽略边界情况
❌ 忽略边界
(没有处理空输入、超大输入等情况)
✅ 处理边界
"对于空文件,提示用户提供代码"
"对于超大文件,建议分批审查"
用真实执行来优化
Skill 的初稿通常需要优化。针对真实任务运行 Skill,然后将结果——所有的结果,不仅仅是失败的——反馈到创建过程中。问:什么触发了误报?什么被遗漏了?什么可以删减?即使只有一次执行-然后-修订的流程也能显著提高质量,复杂领域通常需要几次。
执行跟踪分析
在迭代 Skill 时,比较 Agent 在各测试用例上的执行跟踪。如果你注意到 Agent 每次运行都独立重新发明相同的逻辑——构建图表、解析特定格式、验证输出——那就是写一个经过测试的脚本并捆绑到 scripts/ 的信号。
上下文消耗策略
一旦 Skill 激活,其完整的 SKILL.md 正文就会加载到 Agent 的上下文窗口中,与对话历史、系统上下文和其他活跃 Skills 并存。Skill 中的每个 token 都与窗口中的其他所有内容竞争 Agent 的注意力。
渐进式披露:三层加载
Skills 采用三层加载机制高效管理上下文:
| 层级 | 内容类型 | 加载时机 | Token 预算 |
|---|---|---|---|
| 1. 元数据 | frontmatter (name + description) | 会话启动时,加载所有 Skills | ~100 tokens |
| 2. 指令 | SKILL.md 正文 | Skill 被激活时 | < 5000 tokens(建议) |
| 3. 资源 | scripts、references、assets | 指令明确引用时 | 按需加载 |
添加 Agent 缺乏的,省略它已知道的
专注于 Agent 在没有你的 Skill 情况下不会知道的内容:项目特定约定、领域特定流程、非显而易见的边界情况,以及要使用的特定工具或 API。你不需要解释什么是 PDF、HTTP 如何工作或数据库迁移做什么。
设计一致的单元
决定 Skill 应该覆盖什么就像决定函数应该做什么:你希望它封装一个一致的工作单元,并能与其他 Skills 很好地组合。
- 范围太窄的 Skill 会强制为单个任务加载多个 Skill,有开销和指令冲突的风险
- 范围太广的 Skill 变得难以精确激活
查询数据库并格式化结果的 Skill 可能是一个一致的单元,而也覆盖数据库管理的 Skill 可能试图做太多事情。
追求适度细节
过于全面的 Skill 可能弊大于利——Agent 难以提取相关内容,可能追求由不适用的指令触发的非生产性路径。简洁、逐步的指导和有效的示例通常优于详尽的文档。
当你发现自己覆盖每个边界情况时,考虑大多数是否最好由 Agent 自己的判断来处理。
用渐进式披露构建大型 Skills
规范建议保持 SKILL.md 在 500 行和 5000 tokens 以下——只包含 Agent 每次运行需要的核心指令。当 Skill 合法地需要更多内容时,将详细参考材料移到 references/ 或类似目录中的单独文件。
关键是告诉 Agent 何时 加载每个文件。"如果 API 返回非 200 状态码,读取 references/api-errors.md"比通用的"详见 references/ 更有用。"这让 Agent 按需加载上下文而不是预先加载,这正是渐进式披露的设计工作方式。
偏好流程而非声明
Skill 应该教 Agent 如何处理 一类问题,而不是 为特定实例生成什么。比较:
# 声明式(特定实例)
生成包含以下部分的用户报告:
- 用户名
- 注册日期
- 最后登录
- 总订单数
# 流程式(通用方法)
分析用户数据并生成报告:
1. 确定数据源中的可用字段
2. 选择与报告目的相关的字段
3. 格式化为清晰、可读的结构
4. 添加总结或关键洞察(如适用)
即使个别细节是特定的,流程式方法也应该泛化。
小结
遵循这些最佳实践,可以创建高质量的 Skills:
- 简洁是关键:上下文窗口是公共资源,添加 Agent 缺乏的,省略它已知道的
- 单一职责:每个 Skill 只做一件事,封装一致的工作单元
- 明确边界:定义适用范围和边界情况
- 精准触发:description 包含功能和触发条件,使用祈使语气编写
- 结构化指令:使用检查清单和示例
- 适当自由度:根据任务脆弱性调整指令具体程度
- 渐进式披露:大型 Skills 使用分层结构,SKILL.md < 500 行
- 偏好流程:教 Agent 如何处理问题,而不是为特定实例生成什么
- 易错点清单:列出环境特定的陷阱
- 持续优化:根据真实执行反馈改进
- 多模型测试:在所有计划使用的模型上测试 Skill
下一章我们将通过 实战案例 加深理解。