智能体 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 占位和示例文件

执行流程:匹配 → 激活 → 执行 → 响应

  1. 匹配(Match):用户输入后,AI 判断是否匹配某个 Skill 的描述
  2. 激活(Activate):匹配成功,AI 加载该 Skill 的完整 SKILL.md 内容作为上下文
  3. 执行(Execute):AI 按照 Workflow 一步步操作(调用 curl、API、运行脚本等)
  4. 响应(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 能力的扩展层
posted @ 2026-07-28 09:12  hou永胜  阅读(32)  评论(0)    收藏  举报