智能体 Skill 编写核心技巧
智能体 Skill 编写核心技巧
写好一个智能体 Skill,核心在于解决真实世界的重复性问题,并让 AI 能高效、准确地执行你的工作流。以下是从参考内容中提炼的实用技巧:
核心原则:解决重复性工作
只跑一次的任务没必要封装成 Skill;你手动执行超过三次的流程,才值得写。Skill 的本质是对知识、工作流程、工具集的封装,形式为一个包含 SKILL.md 的文件夹,让 AI Agent 在需要时自动加载。
渐进式信息披露:省 Token 的关键设计
这是 Skill 设计的核心思想。Skill 使用三级加载系统来管理上下文长度:
| 层级 | 内容 | 何时加载 | 大小建议 |
|---|---|---|---|
| Level 1 | 元数据(name + description) | 会话启动时加载 | ~100 词 |
| Level 2 | SKILL.md 正文 | 触发时加载 | < 5,000 词(理想 1,500-2,000) |
| Level 3 | 引用文件(references/、templates/ 、scripts/等) | 按需加载 | 不限 |
设计原则:从轻到重,逐步展开。Agent 先看到摘要,确认匹配后加载正文,遇到细节再拉取引用文件。这样在不牺牲专业深度的前提下,最大限度节省 Token 消耗。
目录结构:最小可用与完整结构
最小可工作 Skill(约 30 行):
skill-name/
└── SKILL.md ← 唯一的必需文件
完整 Skill 结构:
skill-name/
├── SKILL.md ← 必需:核心指令文件
├── references/ ← 可选:Agent 读取但不复制的参考文档
├── templates/ ← 可选:Agent 复制到项目中的模板文件
├── scripts/ ← 可选:Agent 执行的可执行脚本
└── assets/ ← 可选:用于最终输出的静态资源
关键:只有在实际需要时再创建 scripts/、references/ 和 assets/,不要保留空目录和示例占位文件。
SKILL.md 编写技巧
1. 必写字段
- name:唯一标识,不能有空格或特殊字符
- description:必须写清楚“Use when”和“NOT for”,否则 AI 会乱用!
2. 写作风格:命令式 + 解释意图
- 多用祈使句,也就是命令形语句
- 尽量向模型解释为什么你的要求重要,而不是一刀切写“禁止”。AI 会很聪明地理解你的意图,而简单写“禁止”指令,只会让 AI 变得机械教条化
- 利用 theory of mind(心智原理),让 AI 不仅仅理解问题,更能理解问题背后的需求、问题背后的人是怎么想怎么感受的
3. 描述越具体越好
- description 同时写清任务能力和触发场景
- 正文越具体越好,边界越清楚越好
- 删除不需要的 TODO 占位和示例文件
执行流程:匹配 → 激活 → 执行 → 响应
- 匹配(Match):用户输入后,AI 判断是否匹配某个 Skill 的描述
- 激活(Activate):匹配成功,AI 加载该 Skill 的完整
SKILL.md内容作为上下文 - 执行(Execute):AI 按照 Workflow 一步步操作(调用 curl、API、运行脚本等)
- 响应(Respond):把结果返回给你
关键点:AI 不是“运行代码”,而是“阅读指令并模拟执行”。它会调用系统命令(如 curl)、读取文件、甚至运行你提供的脚本。
安全提醒 ⚠️
- 不要写
curl xxx | bash这种危险命令! - 第三方 Skill 要审计,防止恶意脚本
- 敏感操作(如发邮件)建议手动确认
好 Skill 的评判标准
| 标准 | 说明 |
|---|---|
| 解决真实世界的问题 | 反面案例:输出一堆不解决问题的文档,或看起来华丽但无用的解决方案 |
| 使用业内最佳实践 | 领域高手常用的工作流和工作认知,而非简单按约定流程执行 |
| 执行效率高,自动化稳定 | 能主动解决潜在遇到的问题,不需要人工干预 |
给新手的建议
写出一个好 Skill 的门槛很高,既要在现实世界真正解决问题,又要达到业内高手水平,还要自动化不需要人工干预。如果从零做,几乎不可能,推荐使用官方的 skill-creator 技能来辅助创建复杂技能。
总结:写 Skill 更要关注需求和执行反馈,而中间过程往往被高估。先想清楚”在什么场景下解决什么问题,你的目标是什么,通常会怎么做”,再动手编写。
1. skill-creator:创建高质量 Skill
用途:从零创建新 Skill 或更新已有 Skill。适合任何需要封装专业知识、工作流或工具集成的场景。
使用时机:
- 有一个重复性工作流需要固化
- 需要为团队封装领域知识(如公司政策、数据库模式、API 对接流程)
- 想将已有的 Shell/Python 脚本捆绑成可复用的 Skill
核心流程(6 步):
| 步骤 | 做什么 | 关键产出 |
|---|---|---|
| 1. 理解示例 | 收集用户的具体使用场景 | 技能能力清单 |
| 2. 规划内容 | 分析可复用的脚本、参考、资产 | 资源规划表 |
| 3. 初始化 | 运行 init_skill.py 生成骨架 |
Skill 目录结构 |
| 4. 编辑 | 编写 SKILL.md + 捆绑资源 | 完整的 Skill |
| 5. 打包 | 运行 package_skill.py 验证+打包 |
.zip 分发文件 |
| 6. 迭代 | 真实使用后反馈优化 | Skill 版本迭代 |
实用技巧:
- 优先写 SKILL.md,再考虑捆绑资源。很多场景下 SKILL.md 本身(30-50 行)就够用了,不需要 scripts/ 或 references/。
- description 的 Use when / NOT for 原则:写清楚”什么时候触发”和”什么时候别触发”。例如:”用户要求操作数据库时使用。NOT for 纯前端页面改动。”
- 善用渐进式披露:把长篇参考文档放入
references/,SKILL.md 中只写核心工作流和关键指令。Agent 需要时才会加载参考文件,省 Token。 - scripts/ 适合确定性任务:需要重复执行的精确操作(如 PDF 旋转、数据格式转换)适合写脚本,而不是让 AI 每次都重新生成代码。
- assets/ 放输出模板:如果 Skill 的目的是生成某种文件(如 PPT、Word 文档),将模板放入 assets/,Agent 复制后修改。
实战案例:创建 java-api-test 技能
以本项目 java-api-test 技能为例,展示完整的 skill-creator 6 步流程:
步骤 1 — 理解示例:
用户需求:”测试学生选课系统的 8 个模块 API(course/student/teacher/department/
enrollment/schedule/classroom/sys-dict),覆盖 CRUD + 业务场景”
→ 分析调用模式:每次测试都需要 curl 调用、验证 JSON 响应、对比字段值
→ 发现痛点:手动写 curl 测试重复且容易遗漏边界场景
步骤 2 — 规划可重用内容:
→ scripts/api-test-runner.py:Python 测试框架,读取声明式 YAML/JSON 用例,执行 HTTP 请求并断言
→ references/api-testing-patterns.md:API 测试设计模式(分页验证、filter 组合、异常场景)
→ references/ 下逐个模块的测试用例文件(course_api_test.py, student_api_test.py ...)
步骤 3 — 初始化:
→ 运行 init_skill.py,生成骨架:
java-api-test/
├── SKILL.md ← 模板(含 TODO 占位)
├── scripts/ ← 示例文件
└── references/ ← 示例文件
步骤 4 — 编辑 SKILL.md:
→ 删除不需要的 assets/ 目录
→ 编写核心工作流:准备数据 → 收集接口 → 执行测试 → 输出报告
→ 重点描述测试数据规范(姓名用真实常见名、身份证合法校验、地址真实城市...)
→ 引用 scripts/api-test-runner.py 的具体使用方法
→ 引用 references/ 下的用例文件
步骤 5 — 打包:
→ package_skill.py java-api-test → 生成 java-api-test.zip
→ 验证通过:name/description 完整、SKILL.md 格式正确、引用的文件存在
步骤 6 — 迭代:
第 1 轮:测试 course 模块 → 发现分页 total=0
→ 更新 SKILL.md 补充”分页插件必须配置”的检查项
第 2 轮:测试 course filter → 发现 500 异常
→ 更新 SKILL.md 补充”禁止 LambdaQueryWrapper,改用 QueryWrapper”
第 3 轮:全面测试 8 模块 78 用例 → 全部通过
→ SKILL.md 不再需要修改,技能稳定
关键洞察:迭代环节最容易忽略。java-api-test 在测试 course 模块时发现 2 个隐藏问题(分页配置缺失 + LambdaQueryWrapper NPE),这些问题在创建 Skill 时不可能预先知道,只有在真实使用中才会暴露。每个 Skill 都应该经历至少一轮”真实任务测试 → 回头修改 SKILL.md”的迭代。
2. skill-share:团队协作与发布
用途:创建新 Skill 并自动通过 Slack 分享给团队,适合团队协作环境。
使用时机:
- 创建了一个团队通用的 Skill 需要告知同事
- 自动化 Skill 的创建 → 验证 → 打包 → 通知的流水线
- 在团队中推广 Skill 文化
核心功能:
| 功能 | 说明 |
|---|---|
| 技能创建 | 生成标准化的 Skill 目录结构和 YAML 元数据 |
| 技能验证 | 自动检查 SKILL.md 格式、命名规范、元数据完整性 |
| 技能打包 | 生成可分发的 .zip 文件,包含所有资产和文档 |
| Slack 通知 | 通过 Rube Bot 自动将技能名称、描述、链接发布到指定频道 |
实用技巧:
- 打包前自动验证:
package_skill.py会检查必需的 YAML 字段、命名约定(kebab-case)、目录结构完整性。验证失败不会生成包,避免分发残缺的 Skill。 - Slack 通知模板:正确配置 description 后,团队成员能直接从 Slack 消息中理解这个 Skill 是做什么的。
- 适合构建 Skill 发布流水线:如果团队频繁创建新 Skill,skill-share 可以嵌入到自动化流程中。
实战案例:分发 java-coding 技能到团队
以本项目 java-coding 技能为例,展示 skill-share 的完整流程:
场景:团队完成了学生选课系统的基础技能开发,需要将 java-coding 技能分发给
后端团队全体成员,确保大家生成代码时遵循统一规范。
执行流程:
1. 技能创建(已存在 java-coding/ 目录):
java-coding/
├── SKILL.md ← 47 行核心规范
└── (无 scripts/,无 references/,无 assets/ — 纯指令型技能)
2. 技能验证:
package_skill.py java-coding/
→ 检查 YAML 前置元数据:name ✅ description ✅
→ 检查命名规范:kebab-case ✅
→ 检查目录结构:SKILL.md 存在 ✅
→ 验证通过,生成 java-coding.zip
3. Slack 通知(通过 Rube Bot):
┌────────────────────────────────────────────┐
│ 🤖 新技能发布:java-coding │
│ │
│ 📝 Java 编码技能 — 编写符合阿里巴巴/Google │
│ 规范的 Java 代码,涵盖设计模式、异常处理、 │
│ 并发编程等。编写或修改 Java 代码时主动使用。 │
│ │
│ 📎 java-coding.zip(12 KB) │
│ #java-team │
└────────────────────────────────────────────┘
4. 团队成员安装:
unzip java-coding.zip -d ~/.claude/skills/
→ 重启 Claude → 输入"生成课程表业务代码"
→ 自动匹配 java-coding 技能 → 输出统一规范的 8 类文件
效果:
- 所有后端成员生成的代码结构一致:Entity → VO → Req → Mapper → Converter
→ Service → ServiceImpl → Controller
- 新人入职只需安装 skill,不再需要口头传授代码规范
- java-coding 后续更新(如增加新规范)→ 重新打包 → Slack 通知 → 团队更新
注意:本项目的 java-coding 是纯指令型技能(只有 SKILL.md,没有脚本/参考文件)。这类技能特别适合 skill-share,因为体积小(< 20 KB)、更新频繁、团队所有成员都需要保持一致。反之,如果技能带有大型脚本或资源文件(如 java-api-test 的 api-test-runner.py),分发前需确认接收方环境兼容。
3. mcp-builder:构建 MCP 服务器
用途:开发 MCP(Model Context Protocol)服务器,让 LLM 通过工具调用与外部服务交互。支持 Python(FastMCP)和 Node/TypeScript(MCP SDK)。
使用时机:
- 需要将外部 API(如短信、支付、疾控数据上报)封装为 LLM 可调用的工具
- 已有 REST API 想暴露给 AI Agent 使用
- 需要构建自定义工具链(如数据库查询、文件处理、第三方服务集成)
核心流程(4 阶段):
| 阶段 | 内容 | 关键动作 |
|---|---|---|
| 1. 研究与规划 | 理解 MCP 协议、API 文档、设计工具 | WebFetch 获取官方文档,设计工具清单和 I/O 模式 |
| 2. 实现 | 搭建项目结构 → 基础设施 → 逐个实现工具 | 定义 Pydantic/Zod 模型,编写 async 工具函数 |
| 3. 审查与完善 | 代码质量检查、测试、安全检查清单 | DRY/可组合性/一致性/错误处理/类型安全 |
| 4. 创建评估 | 设计 10 个复杂真实评估问题 | 工具检查 → 内容探索 → 问题生成 → 答案验证 |
实用技巧:
- 为工作流构建,而非 API 端点:不要简单包装 REST API。例如,不提供
create_user+send_notification两个独立工具,而是提供一个register_user_with_welcome工具一次完成两个操作。 - 错误信息要可操作:LLM 看到错误后应该知道下一步怎么做。例如:”查询结果为空,尝试使用 filter='active_only' 减少筛选条件” 而非 “查询失败”。
- 默认返回简洁,可选详细:LLM 上下文很宝贵,默认返回精简信息(名称而不是 ID),提供
verbose=true参数可选展开详情。 - 使用 async/await:所有 I/O 操作必须异步,避免阻塞事件循环。
- 评估先行:用 10 个真实场景问题验证你的 MCP 服务器是否真的能帮助 LLM 完成任务。
实战案例:构建 Postgres MCP 服务器
提供 pg_connect / pg_list_tables / pg_get_table_info / pg_insert / pg_update / pg_create_table / pg_export_design_docs / pg_get_relationships 共 8 个工具,以此为例,展示 mcp-builder 的设计原则如何在实际中落地:
阶段 1 — 研究与规划:
需求:让 LLM 能直接操作 PostgreSQL 数据库,执行查表、建表、插入数据等操作。
工具设计(遵循”为工作流构建”原则):
❌ 错误做法:暴露原始 SQL 执行工具(pg_execute_sql)
→ 风险:LLM 可能生成 DROP DATABASE、DELETE FROM 等危险 SQL
→ 风险:SQL 注入,字符串拼接不可控
✅ 正确做法(实际采用):
pg_list_tables → 只读,列出所有表
pg_get_table_info → 只读,查询单表结构
pg_get_relationships → 只读,查看外键关系
pg_insert → 参数化插入,限制 schema/table
pg_update → 参数化更新,限制 WHERE 条件
pg_create_table → 白名单列类型,校验标识符
pg_export_design_docs → 一键生成文档(组合多个查询)
每个工具都:
- 参数化绑定($1, $2)防止 SQL 注入
- 标识符白名单校验(表名、列名、类型名)
- 返回可操作的错误信息
阶段 2 — 实现(Python + FastMCP 示例):
# 以 pg_insert 为例——体现了”为工作流构建”原则
@mcp.tool(
description=”””Insert one or more rows into a PostgreSQL table.
Builds a safe, parameterized INSERT statement.
All identifiers are validated and quoted; values are bound as parameters.
Example: pg_insert(table_name='employees', rows=[{'name': 'Alice'}, {'name': 'Bob'}])”””,
readOnlyHint=False,
destructiveHint=False,
idempotentHint=True,
)
async def pg_insert(
table_name: str = Field(description=”Target table name”),
schema: str = Field(default=”public”, description=”Schema name”),
rows: list[dict] = Field(description=”Rows to insert”),
returning: list[str] | None = Field(default=None, description=”Columns to return”),
) -> str:
# 1. 校验标识符(防 SQL 注入)
validate_identifier(table_name)
validate_identifier(schema)
# 2. 参数化绑定
placeholders = [f”${i+1}” for i in range(len(columns))]
query = f”INSERT INTO {quoted_schema}.{quoted_table} (...) VALUES (...)”
# 3. 可操作错误
try:
await execute(query, params)
except UniqueViolation:
return “❌ 唯一键冲突:该记录已存在。如需更新请使用 pg_update”
except ForeignKeyViolation as e:
return f”❌ 外键约束失败:{e.detail}。请先确保关联表存在对应记录”
# 4. 返回简洁但完整的信息
return f”✅ 成功插入 {len(rows)} 行...”
阶段 3 — 审查与完善:
质量检查:
✅ DRY 原则:所有工具共享 validate_identifier()、build_where()、format_response() 函数
✅ 一致性:所有工具返回 Markdown 格式,错误信息都以 ❌ 开头 + 下一步建议
✅ 错误处理:每个外部调用(数据库查询)都有 try/except
✅ 类型安全:Pydantic 模型定义了每个参数的约束(minLength, maxLength, regex)
✅ 文档:每个工具都有完整的 docstring + 使用示例
阶段 4 — 创建评估:
10 个评估问题(节选):
1. “列出 phd_frame schema 下所有表” → pg_list_tables
2. “查看 course 表结构” → pg_get_table_info(table_name=”course”, schema=”phd_frame”)
3. “course 表和哪些表有关联?” → pg_get_relationships(schema=”phd_frame”, table_name=”course”)
4. “插入 3 门新课程,返回课程 ID 和名称” → pg_insert(table_name=”course”, rows=[...], returning=[“id”, “course_name”])
5. “生成完整的数据库设计文档” → pg_export_design_docs(schema=”phd_frame”)
三者关系:Skill 生态的完整生命周期
skill-creator ───→ 创建/编辑 Skill ───→ skill-share ───→ 打包分发到团队
↑ │
│ ↓
│ 团队使用反馈
│ │
└──────────── 迭代优化 ←──── mcp-builder ←────── 需要扩展外部能力
(为 Skill 构建 MCP 工具)
- skill-creator 是元技能,用于创建任何 Skill(包括其他两个工具本身也可以用它创建)
- skill-share 解决”创建之后怎么给团队用”的问题
- mcp-builder 解决”Skill 需要调用外部服务”的问题,是 Skill 能力的扩展层

浙公网安备 33010602011771号