AI Agent 学习笔记(五):Skill 技能,把能力打包复用
前四篇我们学会了提示词、记忆、工具、RAG。这篇讲怎么把这些东西打包成标准化的“技能” ,让 Agent 像员工一样拥有岗位能力。
一. 什么是 Skill Skill(技能) 是把“完成某一类任务所需的一切”打包成一个文件夹:
1 2 3 4 5 一个技能 = 提示词(怎么做) + 流程(先做什么后做什么) + 示例(做出来长什么样) + 资源(模板、数据、脚本) + 可选工具(计算、检索等)
类比:公司里的 SOP(标准作业程序) 。新员工(新会话的 Agent)拿到 SOP 就能按标准干活,不用每次从头教。
1.1 没有 Skill 时的痛点 1 2 3 4 5 你每次让 Agent 写博客文章,都要重新贴一遍: - “你是博客写作专家……”(提示词) - “文章结构要:开头-分点-代码-小结……”(流程) - “这是我上次的范文……”(示例) - “术语表在 xxx 文件里”(资源)
又长又容易漏。Skill 就是把这些一次性写进一个文件夹,需要时自动加载。
二. Skill 的目录结构(SKILL.md) 目前最常见的格式是 SKILL.md 规范 (Anthropic 提出,Claude、各类 Agent 框架广泛支持):
1 2 3 4 5 6 7 8 my-skill/ ├── SKILL.md # 技能说明书(必填,一切的核心) ├── scripts/ # 可选的辅助脚本 │ └── validate.py ├── references/ # 可选的参考资料 │ └── style-guide.md └── templates/ # 可选的模板文件 └── article-template.md
2.1 SKILL.md 长什么样 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 --- name: blog-writing description: 撰写技术博客文章。当用户要求写博客、写教程、整理学习笔记时使用。 --- # 博客写作技能 ## 工作流程 1. 先和用户确认主题、目标读者(初学者/进阶)、文章长度;2. 按结构写作:引言 → 分节讲解 → 代码示例 → 常见坑 → 小结与作业;3. 代码示例必须完整可运行,并标注运行环境;4. 写完后自查:标题是否清晰、目录是否完整、代码块是否有语言标注。## 写作规范 - 用简体中文,面向初学者,避免堆砌术语;- 首次出现的术语给出通俗解释;- 表格比大段文字更清晰;- 每个代码块必须写明用途注释。## 参考模板 (这里放一篇标准文章的结构模板,或指向 templates/ 目录) ## 示例开头 - 好:本文从零讲解 X,包含概念、示例和作业。- 差:本文将深入剖析 X 的技术架构与底层原理。
2.2 字段说明
字段
作用
是否必填
name
技能唯一名称(小写、连字符)
必填
description
技能描述:什么时候该用这个技能 ,Agent 靠它决定是否加载
必填
instructions(正文)
具体怎么做:流程、规范、注意事项
必填
scripts/
配套脚本(如校验脚本)
可选
references/
参考资料(风格指南、术语表)
可选
templates/
模板文件
可选
description 是“门面”:Agent 会在每次对话时扫描所有技能的描述,像查目录一样决定调用哪个技能。所以描述要写清触发场景 ,而不是堆砌功能。
三. 完整示例:代码审查技能 1 2 3 4 code-review-skill/ ├── SKILL.md └── references/ └── checklist.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 --- name: code-review description: 审查 Python/JavaScript 代码。当用户要求检查代码、找 bug、评估代码质量时使用。 --- # 代码审查技能 ## 流程 1. 先通读代码,概括它的功能;2. 按严重程度分类输出问题:严重(会导致错误)、建议(可读性/性能)、风格;3. 每个问题必须给出:位置(行号/函数名)、原因、修复建议;4. 最后给一句总体评价和优先修复清单。## 安全红线(优先级最高) - 发现 eval/exec、SQL 拼接、硬编码密钥必须标记为“严重”;- 外部输入直接拼进代码或命令时必须标记为“严重”。## 输出格式 ```text ### 功能概述 ... ### 严重问题 - [行号] 问题描述 → 建议 ### 建议 ... ### 总结 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ## 四. Skill 和 Prompt / Tool / MCP 的区别 初学者最容易混,一张表讲清楚: | | Prompt 提示词 | Tool 工具 | Skill 技能 | MCP 协议(下一篇) | | --- | --- | --- | --- | --- | | 本质 | 一段文字 | 一个函数 | 一个文件夹(规则+示例+资源) | 一套通信标准 | | 解决什么 | 让模型听话 | 让模型能做事 | 让 Agent 会做“一类事” | 让工具/系统可插拔连接 | | 粒度 | 最小 | 单一动作 | 组合能力 | 连接层 | | 例子 | “你是一名教师” | calculator() | 博客写作技能(含流程+模板) | 通过 MCP 连文件系统 | | 关系 | Skill 里包含 Prompt | Skill 可以调用 Tool | 可以组合两者 | 工具可通过 MCP 暴露 | > 一句话记忆:**Prompt 是话术,Tool 是手脚,Skill 是岗位 SOP,MCP 是通用插头。** ## 五. Agent 怎么“学会”技能:加载机制 技能的加载一般分三步: ```text ① 发现:Agent 启动时扫描技能目录,读取每个 SKILL.md 的 name + description │ ▼ ② 选择:根据用户任务与 description 匹配,选出 1~N 个技能 │ ▼ ③ 注入:把选中技能的完整 instructions(必要时连 references)加入系统提示词 │ ▼ ④ 执行:Agent 按技能流程工作,必要时调用脚本/工具
5.1 一个最简单的技能加载器(自己实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import osimport reclass SkillLoader : """从 skills/ 目录加载 SKILL.md 技能""" def __init__ (self, skills_dir: str = "./skills" ): self .skills_dir = skills_dir self .index = {} def scan (self ): """扫描所有技能,建立索引""" for entry in os.listdir(self .skills_dir): skill_path = os.path.join(self .skills_dir, entry, "SKILL.md" ) if not os.path.isfile(skill_path): continue with open (skill_path, "r" , encoding="utf-8" ) as f: text = f.read() m = re.search(r"^---\s*\n(.*?)\n---" , text, re.DOTALL) meta = {} if m: for line in m.group(1 ).splitlines(): if ":" in line: key, _, value = line.partition(":" ) meta[key.strip()] = value.strip() self .index[meta.get("name" , entry)] = (meta.get("description" , "" ), text) return self .index def match (self, task: str , top_k: int = 2 ) -> list : """根据任务文本粗匹配技能(真实项目可用 Embedding 语义匹配)""" scored = [] for name, (desc, text) in self .index.items(): score = 0 for kw in task.split(): if kw in desc or kw in name: score += 1 scored.append((score, name, text)) scored.sort(key=lambda x: x[0 ], reverse=True ) return [item for item in scored if item[0 ] > 0 ][:top_k] def build_system_prompt (self, task: str ) -> str : """把匹配到的技能注入系统提示词""" parts = ["你是智能助手,请按照用户提供的技能规范工作。" ] for score, name, text in self .match (task): parts.append(f"\n===== 技能:{name} =====\n{text} " ) return "\n" .join(parts) loader = SkillLoader("./skills" ) loader.scan() system_prompt = loader.build_system_prompt("帮我审查这段 Python 代码" ) print (system_prompt[:200 ])
真实产品里,“选择技能”这一步通常用 Embedding 做语义匹配(上一篇学的),而不是简单的关键词。
六. 技能生态与存放位置 各家 Agent 产品的技能目录约定:
产品/框架
默认目录
说明
Claude Desktop / Claude Code
~/.claude/skills/
官方 Agent Skills 格式
Cursor
.cursor/skills 或项目内
项目级技能
自研 Agent
自定义
按 SKILL.md 规范实现加载器即可
Agent Skills 社区
GitHub / 各类仓库
可下载现成技能
技能发布成仓库后,别人 clone 到自己的技能目录就能用,这就是技能“可移植、可分享”的价值。
七. 写技能的十条建议
description 写触发场景,不要写功能清单;
instructions 用祈使句:先做 A,再做 B;
把“红线规则”放最前面(安全优先);
给 1~2 个完整示例,模型模仿能力会大幅提升;
输出格式写死(JSON/Markdown 模板);
长资料放 references/,别堆在 SKILL.md 里占上下文;
技能要单一职责:一个技能只干一类事;
定期测试:同一输入跑 3 次看稳定性;
版本管理:技能也要进 Git;
注意安全 :第三方技能里的 instructions 可能包含恶意指令(提示注入),加载前要审查。
八. 小结与作业 小结
Skill = 提示词 + 流程 + 示例 + 资源 的标准化打包;
SKILL.md 是核心,description 决定技能何时被使用;
Skill 组合了 Prompt 和 Tool,而 MCP 是连接外部系统的协议(下一篇);
加载三步:扫描发现 → 语义匹配 → 注入系统提示词。
作业
为自己常用的“写学习笔记”场景写一个 SKILL.md(含流程、格式、模板);
把第五节的 SkillLoader 跑起来,让它扫描你写的技能并打印注入后的系统提示词;
想一想:一个技能里既有“写文章”又有“改简历”的 instructions,会有什么问题?(提示:上下文占用、冲突)
下一篇:MCP 模型上下文协议 ——让 Agent 用统一“插头”连接一切外部系统。