Agent Skills 是给 AI Agent 组织可复用能力的一套方式,核心是把技能拆成独立技能包,让 Agent 在需要时根据描述按需加载,而不是把所有规则一次性塞进系统提示词。它解决的是 Agent 开发里很常见的一类问题:能力越多越混乱、提示词越堆越长、换个场景就得重写流程。适合正在做智能体应用、已经写过提示词工程、想让工具调用更模块化的开发者。
标题里写了“2026最新版”,我的建议是不要把它当成某个固定版本去追。Agent Skills 的落地形态在不同 Agent 环境中会有差异,但底层的设计思路一致:技能包、描述匹配、按需加载。下面按我的学习顺序拆开讲:先理解它解决什么问题,再手写一个能跑的技能,然后处理参数、日志和失败,最后给几个适合练手的项目方向。
1. 先搞清楚 Agent Skills 解决的是什么问题
1.1 它和工具、MCP、提示词的区别
很多人第一次接触 Agent Skills 时,会以为它只是“又一种工具格式”。这个理解会误导后面的设计。
工具是原子能力,通常对应一个函数或 API,比如“读取文件”“发送 HTTP 请求”。MCP 是标准化工具服务协议,把一堆工具打包成服务,让 Agent 通过协议调用。提示词是静态指令,负责告诉模型怎么思考、按什么格式输出。Agent Skills 则把“指导文档 + 脚本 + 资源文件”打包在一起,解决的问题不是“能做什么”,而是“这件事具体该怎么做”。
区别最直接的表现是:工具回答能力,技能回答流程。一个技能内部可以调用多个工具,可以带上参考模板、示例脚本、依赖说明,甚至 MCP 服务地址。技能被加载后,模型看到的是完整操作指引,而不是一句工具描述。
1.2 一个技能包的最小组成
目前常见的技能包结构是一个目录加一个入口文件。最小组成是这样:
text复制skills/
doc-organizer/
SKILL.md
scripts/
organize.py
requirements.txt
SKILL.md 是入口,带 frontmatter。最基础只需要 name 和 description 两个字段。name 是技能标识,description 是给 Agent 看的触发说明。脚本放在 scripts 目录,资源文件、示例文件、依赖声明都可以作为技能包的补充内容。
1.3 为什么按需加载比全量常驻更稳
如果把十几个技能的完整规则都写进系统提示词,上下文会被大量无关指令占满。模型在判断每一步该调用什么时,会受到无关信息干扰,输出不稳定,调一次提示词要花大量时间。按需加载的思路是:平时技能包只以文件形式存在于磁盘,Agent 根据用户任务和技能 description 的匹配程度,决定是否把某个技能加载进来。
这样做有三个直接收益:上下文更干净、技能可复用、维护边界清晰。改一个技能就是改一个目录,不会因为提示词太长而互相影响。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 写第一个能真实运行的技能
2.1 环境准备:先把这个目录建好
以本地命令行版 Agent 为例,你需要准备:
- 一个支持技能目录机制的 Agent 环境,目前常见的有 Claude Code、Codex CLI 这类命令行 Agent,也可以用支持 SKILL.md 的 SDK 自建。
- Python 3.9 以上,用来运行示例脚本。
- 一个不放在系统临时目录里的技能搜索根目录。
第一次做,建议建一个干净的实验目录:
bash复制mkdir -p ~/agent-skills-lab/skills/doc-organizer/scripts
mkdir -p ~/agent-skills-lab/skills/doc-organizer/examples
再把技能根目录配置到 Agent 的搜索路径中。不同环境的配置命令不一样,统一原则是:技能目录必须对外层可读,不能放在临时目录里,否则 Agent 重启后就会找不到。不同版本的 Agent 环境在技能加载机制上可能有差异,落地前先确认你的环境支持哪种加载方式。
2.2 SKILL.md 该怎么写
以“目录整理”技能为例。目标:Agent 拿到一个杂乱目录后,按扩展名把文件分类到 images、documents、archives、others 四个子目录。
SKILL.md 内容:
markdown复制---
name: file-organizer
description: 当用户需要按类型整理目录、归集散落文件、清理杂乱的下载文件夹时使用。输入一个目录绝对路径,输出分类子目录和移动日志。
---
# 文件整理技能
## 适用场景
- 目录里文件命名混乱、类型混杂
- 需要按扩展名快速归档
## 使用方法
1. 调用 scripts/organize.py
2. 传入绝对路径参数
3. 脚本会在目录下创建四个子目录并移动文件
## 规则
- 不处理隐藏文件
- 同名文件加时间戳后缀
- 只移动,不删除源文件
description 不要只写“用于文件整理”。要包含触发条件、输入类型和结果形式,后面第 3 节会专门展开。
2.3 落地脚本:目录分类整理
python复制import os
import sys
import shutil
from datetime import datetime
def main():
if len(sys.argv) < 2:
print("error: missing target_dir", file=sys.stderr)
sys.exit(1)
target_dir = os.path.abspath(sys.argv[1])
categories = {
"images": [".jpg", ".jpeg", ".png", ".gif", ".webp"],
"documents": [".md", ".txt", ".pdf", ".docx"],
"archives": [".zip", ".tar", ".gz"],
"others": [],
}
if not os.path.isdir(target_dir):
print(f"error: {target_dir} 不是有效目录", file=sys.stderr)
sys.exit(1)
for file_name in os.listdir(target_dir):
file_path = os.path.join(target_dir, file_name)
if not os.path.isfile(file_path) or file_name.startswith("."):
continue
ext = os.path.splitext(file_name)[1].lower()
matched = "others"
for category, exts in categories.items():
if ext in exts:
matched = category
break
dest_dir = os.path.join(target_dir, matched)
os.makedirs(dest_dir, exist_ok=True)
dest_path = os.path.join(dest_dir, file_name)
if os.path.exists(dest_path):
stamp = datetime.now().strftime("%Y%m%d%H%M%S")
base, suffix = os.path.splitext(file_name)
dest_path = os.path.join(dest_dir, f"{base}_{stamp}{suffix}")
shutil.move(file_path, dest_path)
print(f"moved: {file_name} -> {matched}")
if __name__ == "__main__":
main()
写的时候有两个细节要提前处理。第一是绝对路径,脚本内部用 os.path.abspath 转一次,避免 Agent 的工作目录影响结果。第二是重名文件,直接覆盖会丢数据,加时间戳后缀更安全。
2.4 验证成功的三个判断标准
放几个测试文件到任意目录,然后对 Agent 说:“请整理 ~/test-inbox 目录,按类型归一下类。”判断是否成功按这个顺序看:
- Agent 是否加载了 file-organizer 技能。如果它绕开技能临时写命令,说明 description 匹配失败。
- 脚本是否正常退出,日志里是否出现 moved 记录。
- 目标目录是否生成四类子目录,文件内容是否完好。
这一步不要急着加并发、加批量。先确认单条路径通,再考虑复杂场景。
先用一条真实任务验证完整链路,再考虑批量。批量时最容易出问题的不是模型,而是路径、重名和失败跳过。
3. 让技能从“能跑”变成“好用”
3.1 描述是入口,写不好等于白写
description 是技能是否被触发的开关。我踩过的典型问题是把描述写得太短,比如“用于文件整理”。这种描述缺少触发条件,Agent 遇到目录杂乱的任务时可能判断不出来,结果绕过技能走别的路径。
更稳的写法要包含三个信息:
- 触发条件:什么场景下该用这个技能。
- 输入类型:传进来的是目录路径、文件列表还是文本。
- 结果形式:输出什么,比如分类子目录、汇总表、日志文件。
示例:“当用户需要按类型整理目录、归集散落文件、清理杂乱的下载文件夹时使用。输入一个目录绝对路径,输出分类子目录和移动日志。”这段描述比“文件整理”准确得多。
另外,不要在 description 里堆关键词。堆扩展名、文件名、动词容易让匹配变脆,意思准确比词多更重要。
3.2 脚本要脱离单一路径复用
第一个技能跑通后,马上会遇到一个问题:脚本写死了要整理某个目录。把目录写进脚本里,技能就只能服务一个场景。更合理的做法是让脚本只接收绝对路径参数,同时支持 --dry-run,先打印将要执行的操作,确认无误再真正移动。
我一般会再抽一层:把“分类规则”从脚本里拆出来,放进一个单独的配置文件或字典。这样不同项目可以复用同一个整理脚本,只是规则不同。这个改造很小,但能避免后面每加一个项目就复制一份代码。
3.3 多技能编排的拆分原则
复杂任务往往需要多个技能接力,比如“整理下载目录 → 生成文件清单 → 写周报”。Agent 可以在不同阶段加载不同技能,但单个技能的功能要克制。如果你发现一个 SKILL.md 里写了超过三个使用场景,大概率是划分太粗。
判断标准只有一句:一个技能只回答一个问题。“把文本转成 Markdown”是一个技能,“转成 Markdown 后再生成摘要”是另一个技能。拆开之后,每一个技能都能单独调试,组合时的失败点也更容易定位。
4. 参数、输出与失败处理提前定好
4.1 输入输出标准化
自己用的小技能,参数随意一点没关系。一旦技能要给别人用,或要接批量和接口,输入输出必须提前定规则。
我建议的最低标准:
- 输入统一用绝对路径,不依赖 Agent 当前工作目录。
- 参数走命令行参数或 JSON 文件,不要依赖交互式输入。
- 输出包含机器可读日志,至少一行一条记录。
- 提供
--dry-run,支持“先预览,再执行”。
--dry-run这个参数值得所有会改文件的技能加上。先看预览,再执行,能避免大部分误操作。
4.2 日志和退出码约定
技能脚本的日志不是给模型看的,是给用户看的,更是排查时给自己看的。每条关键操作至少包含:时间、操作类型、源路径、目标路径、结果状态。下面是推荐约定:
| 状态 | 退出码 | 日志样例 |
|---|---|---|
| 成功 | 0 | 2026-02-01 10:00:01 moved /a/a.png -> /a/images/a.png |
| 参数错误 | 1 | error: missing target_dir |
| 权限失败 | 2 | error: permission denied: /a |
| 未知异常 | 3 | error: unexpected: <message> |
退出码约定好了,Agent 才能根据非零退出码决定是否重试或换方案。如果所有错误都返回 0,Agent 会误以为任务成功,后续排查就变成大海捞针。
4.3 常见报错与排查顺序
我从多次实测里总结的排查顺序是固定的:先看现象,再看输入,再看环境,再看参数,最后才怀疑技能机制本身。
- 现象:技能根本没加载,还是加载后报错,还是跑完结果不对。
- 输入:路径格式、文件编码、文件名里有没有空格或特殊字符。
- 环境:依赖安装、脚本可执行权限、目录可读权限。
- 参数:Agent 传给脚本的参数数量对不对,示例里写的内容和实际是否一致。
- 机制:description 是否匹配当前任务,技能目录是否真的在搜索路径里。
最常见的报错集中在 Permission denied 和 FileNotFoundError。前者去查目录权限,后者去查路径拼接。不要一报错就怀疑模型能力,大多数时候问题出在脚本和路径上,不在 Agent 本身。
5. 三个适合练手的项目方向
5.1 文档批量转码与摘要
这个方向适合练习技能分层。技能 A 负责把 docx、pdf、txt 转成 Markdown;技能 B 负责读取 Markdown 生成摘要。两个技能拆开,可以单独调试,也可以组合使用。文件数量从 5 个开始,日志确认无误后再跑 100 个。
批量场景要专门看失败重试。哪个文件转换失败、失败原因是什么、是否跳过继续、最终有没有汇总清单。如果这些信息缺失,Agent 表面上跑完了,实际上可能静默丢掉一批文件。
5.2 数据清洗与报表生成
适合练习参数设计和输出规范。技能输入一个 CSV 路径,输出清理后的 CSV 和一份字段说明。常见的数据文件编码比较杂,脚本里要主动处理 utf-8、gbk 两类读取,不能指望 Agent 自动猜测。
验收标准:给一份带空值、错位列、前后空格的数据,技能执行后字段数量和行数都要可核对。数据清洗类技能最怕“跑完了但数字对不上”,所以日志里要输出原始行数、清洗后行数、删除行数。
5.3 团队技能库的组织方式
当技能超过十个,建议按目录分类:document、data、code、ops。每个技能包写清楚适用边界和依赖。团队协作最常见的问题不是“没人会写技能”,而是技能没被触发、被错误触发、以及多人维护后行为不一致。
我给每个技能包维护一个 CHANGELOG.md,哪怕只写一行“改了哪个参数”。跨版本排查时会轻松非常多,尤其当 Agent 行为在某次改动后突然变化时,可以快速定位是哪次调整引入的。
6. 边界与建议:我实测后会优先盯住哪些点
6.1 不要一开始就把参数拉满
低配置机器上不要让技能脚本开高并发。Agent 本身已经占用上下文,脚本再并发读写文件,不稳定概率会明显上升。资源占用要看三个点:单次执行耗时、峰值内存、失败率。先跑单文件,再跑小批量,稳定后再逐步提高并发。
“支持某个格式”只代表脚本里有对应分支,不代表所有编码、所有版本都稳定。遇到异常文件,先拿小样例定位,确认是哪一类问题,再决定是修脚本还是调整输入。
6.2 我建议的学习顺序和验收方式
按这个顺序可以少走不少弯路:
- 用 10 个测试文件跑通一个最小技能。
- 验证 description 触发效果,连续换三种说法请求同一个任务,看技能是否都能被加载。
- 给脚本补
--dry-run、退出码和日志。 - 再拆第二个技能,练习技能接力。
- 最后才考虑批量、并发和团队共享。
如果你需要处理的是完全确定性的流水线,比如“每天凌晨归档一次”,不要依赖 Agent 技能触发,直接写 cron 或 CI 更稳。Agent Skills 更适合需要判断和灵活组合的任务,而不是固定调度。
我的判断是:很多问题最后都不是 Agent Skills 机制不行,而是前置环境和输入材料没有处理干净。技能描述写得再准,脚本路径不对也跑不起来;日志约定得再好,输入编码没处理也全是乱码。先把最小闭环跑通,再谈批量、接口和团队化。
