1. 从“skills”这个标题说起:它到底指什么
第一次看到“skills”这个标题,很多人会以为是某个泛泛而谈的能力清单,或者一份简历上的技能罗列。但结合热搜词里的 Agent Skills、Google Cloud、npx、AI agents、claude agent skills、codex skills 这些词来看,这里的 skills 显然不是指人类的能力,而是指AI Agent 可以调用的技能模块——一种让 AI 从“只会聊天”变成“能干活”的扩展机制。
我最早接触这个概念是在折腾 Claude 的 Agent 能力时。当时我让模型帮我处理一个前端项目,它能写代码,但没法自己跑构建、没法截图验证页面、没法查数据库。后来我给它挂上几个 skills,情况完全变了:它能自己调用 Playwright 打开浏览器、能执行 shell 命令、能读写文件、能查 API 文档。那一刻我的感受就是热搜里那句“今天学会了skills,打开新世界”。
所以这篇内容我想聊的是:Agent Skills 到底是什么、它的运行原理是什么、怎么安装和开发、有哪些好用的 skills、踩过哪些坑。适合正在玩 Claude、Codex、各类 AI Agent 框架的开发者,也适合想给自己团队搭一套自动化 Agent 工作流的人。哪怕你只是刚听说这个词,看完也能明白它为什么突然这么火。
需要先说明一点:skills 这个概念在不同平台上的实现细节不完全一样,但核心思想是共通的——把一段可复用的能力封装成标准模块,让 Agent 在需要的时候按需加载和调用。理解了这一点,后面所有的安装、开发、调试都是围绕这个核心展开的。
2. Agent Skills 的核心设计思路拆解
2.1 为什么需要 skills:从“万能模型”到“专业工具包”
大模型有个天然矛盾:它的知识面极广,但在具体任务上往往不够专精。你让它写一个符合公司代码规范的 React 组件,它可能写得出来,但风格飘忽;你让它操作一个内部系统,它根本不知道接口长什么样。
传统的解法是微调或者写超长 prompt,但这两种方式都有明显问题。微调成本高、迭代慢;超长 prompt 会挤占上下文、容易互相干扰。skills 提供的是第三条路:把特定能力做成独立模块,Agent 按需加载。
打个比方,模型本身像一个刚毕业的高材生,什么都懂一点。skills 就像给他配的一套工具箱——需要拧螺丝的时候拿出螺丝刀,需要量尺寸的时候拿出卷尺。工具箱里的工具是预先调试好的,用起来稳定,而且不会因为工具太多而让他分心。
这个设计思路带来的直接好处有三个。第一是上下文经济:不需要把所有能力都塞进 system prompt,只在触发时才加载对应 skill 的描述和指令。第二是可维护性:某个 skill 出问题了,单独修它就行,不影响其他能力。第三是可组合性:多个 skills 可以串联使用,比如“查数据库”+“生成图表”+“发邮件”组合成一条完整工作流。
2.2 skills 的目录结构与加载机制
一个标准的 skill 通常是一个文件夹,里面至少包含一个描述文件(常见的是SKILL.md或skill.json),用来告诉 Agent 这个 skill 叫什么、什么时候用、怎么用。复杂一点的 skill 还会带上脚本、模板、参考文档、示例代码。
我用过的一个典型结构是这样的:
my-skill/ ├── SKILL.md # 核心描述文件,包含元数据和指令 ├── scripts/ # 可执行脚本 │ └── run.py ├── templates/ # 输出模板 │ └── report.md └── references/ # 参考资料 └── api-doc.mdSKILL.md里的内容一般分两部分。前面是元信息,用类似 YAML frontmatter 的格式写清楚 name、description、触发条件;后面是给模型看的指令正文,说明这个 skill 能做什么、输入输出是什么、有哪些注意事项。
加载机制上,不同平台做法不同。有的平台是启动时扫描 skills 目录,把所有 skill 的元信息注入到 Agent 的可用工具列表里,模型根据用户请求判断要不要调用;有的平台是懒加载,只有匹配到关键词才把完整指令读进来。我实测下来,懒加载对上下文更友好,尤其是 skills 数量多的时候,全量注入会明显拖慢响应速度。
提示:如果你自己开发 skill,description 字段一定要写得精准。模型主要靠这段描述来判断“这个请求该不该用这个 skill”。描述太宽泛会导致误触发,太窄又会导致该用的时候用不上。
2.3 和 MCP、Function Calling 的区别在哪
很多人会把 skills 和 MCP(Model Context Protocol)、Function Calling 混为一谈。它们确实相关,但层次不一样。
Function Calling 是最底层的机制,解决的是“模型如何结构化地输出一个函数调用请求”。MCP 是一套协议标准,解决的是“不同工具和数据源如何用统一接口接入模型”。而 skills 更偏向能力封装和知识组织的层面,它可能内部用到 Function Calling,也可能通过 MCP 连接外部服务,但它本身强调的是“一个完整的、可复用的任务能力”。
举个具体例子。你要让 Agent 会“生成周报”。Function Calling 层面,你需要定义get_commits、get_issues、format_report这些函数。MCP 层面,你可能接了一个 Git 服务的 MCP server。而 skill 层面,你封装的是一个叫“weekly-report”的技能,里面写清楚了:先拉取本周提交,再汇总 issue,按项目分组,用固定模板输出。Agent 看到“帮我写周报”就知道调用它,不需要关心底层用了哪些函数。
这个区分很重要,因为它决定了你该在哪个层面解决问题。如果只是接一个数据源,用 MCP 就够了;如果要固化一套工作流程和输出规范,那就该做成 skill。
3. 安装与配置:从零把 skills 跑起来
3.1 环境准备与前置依赖
在装 skills 之前,有几样东西得先确认好。我用的是 Node.js 环境,因为大部分 Agent 工具链都是 npm 生态的,npx 命令用起来最顺手。
先检查基础环境:
node -v npm -v npx -vNode 版本建议 18 以上,太低会遇到各种依赖不兼容。如果版本不对,用 nvm 切换最省事:
nvm install 20 nvm use 20然后是 Agent 运行环境本身。不同平台的安装方式不一样,有的提供 CLI,有的提供桌面客户端,有的需要自己拉源码跑。我建议先用官方推荐的安装方式,别一上来就折腾源码编译,容易在环境问题上耗掉半天。
网络方面要有心理准备。很多 skills 仓库和依赖包在境外,下载速度可能很慢。我的做法是提前配好 npm 镜像源,能省不少时间:
npm config set registry https://registry.npmmirror.com注意:镜像源只解决包下载问题,有些 skill 运行时需要访问外部 API,那部分网络得单独处理。如果 skill 依赖的服务连不上,表现往往是“调用超时”或“返回空结果”,排查时先确认网络连通性。
3.2 通过 npx 安装 skills 的标准流程
npx 是目前最主流的 skills 安装方式,好处是不用全局安装,用完即走,版本也好控制。典型流程分三步:搜索、安装、验证。
搜索 skill:
npx skills search playwright这条命令会列出所有和 playwright 相关的 skill,包括名称、描述、作者、下载量。我一般会优先选下载量高、最近有更新的,稳定性更有保障。
安装 skill:
npx skills install playwright-browser安装完成后,skill 会被放到 Agent 的 skills 目录下。不同平台目录位置不同,常见的有~/.agent/skills/、项目根目录的.skills/、或者平台配置里指定的路径。装完最好确认一下文件确实到位了:
npx skills list这条命令会列出当前已安装的所有 skills。如果列表里能看到刚装的那个,说明安装成功。
验证 skill 是否可用,最直接的办法是让 Agent 实际调用一次。比如装了 playwright skill,就让它“打开 example.com 并截图”。如果它能正确执行并返回截图路径,说明 skill 加载正常。
3.3 安装失败的常见原因与排查
npx playwright install失败是热搜里出现频率很高的问题,我踩过好几次。总结下来原因主要有这几类:
| 失败现象 | 常见原因 | 解决方向 |
|---|---|---|
| 下载超时 | 网络到下载源不稳定 | 配置镜像或代理下载地址 |
| 权限拒绝 | 目标目录无写权限 | 用管理员权限或改安装路径 |
| 版本冲突 | Node 或依赖版本不匹配 | 升级 Node,清理 node_modules |
| 磁盘空间不足 | 浏览器二进制包体积大 | 清理空间或指定其他盘 |
| 依赖缺失 | 系统缺少运行库 | 按提示安装对应系统依赖 |
我遇到最多的是下载超时。Playwright 要下载浏览器内核,包体几百兆,网络一抖就断。解决办法是设置下载镜像:
export PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install另一个高频问题是权限。在 Linux 或 macOS 上,如果 skills 目录属于 root,普通用户装不进去。这时候要么改目录权限,要么用--prefix指定一个用户可写的路径。
提示:安装失败时先看完整报错,别只看最后一行。很多错误信息里已经写清楚了是网络问题还是权限问题,照着提示走比盲目重试高效得多。
4. 开发自己的 skill:从需求到落地
4.1 什么样的需求适合做成 skill
不是所有东西都值得封装成 skill。我的判断标准有三条:高频、稳定、有明确输入输出。
高频指的是这个任务你会反复做。比如每天都要生成测试报告、每周都要整理数据、每次发版都要跑一遍检查清单。偶尔用一次的东西,写个 prompt 就够了,没必要做成 skill。
稳定指的是流程相对固定,不会天天变。如果每次的步骤都不一样,那更适合让模型自由发挥,硬做成 skill 反而僵化。
有明确输入输出指的是你能说清楚“给它什么、它返回什么”。比如输入一个 Git 仓库地址和日期范围,输出一份 Markdown 格式的提交摘要。这种边界清晰的,做成 skill 最合适。
反过来,像“帮我思考一下产品方向”这种开放式任务,就不适合做成 skill。它没有固定流程,也没有标准输出,封装起来意义不大。
4.2 编写 SKILL.md 的关键字段
SKILL.md是整个 skill 的灵魂,写得好不好直接决定它能不能被正确触发和使用。我一般按这个结构来写:
--- name: weekly-report description: 根据 Git 提交记录生成周报,适用于需要汇总本周工作内容的场景 version: 1.0.0 author: your-name triggers: - 写周报 - 生成周报 - weekly report --- # 周报生成技能 ## 功能说明 读取指定仓库的 Git 提交记录,按项目分组,生成 Markdown 格式的周报。 ## 输入参数 - repo_path: 仓库本地路径 - start_date: 起始日期,格式 YYYY-MM-DD - end_date: 结束日期,格式 YYYY-MM-DD ## 执行步骤 1. 使用 git log 拉取指定日期范围的提交 2. 按作者和项目分组 3. 提取每条提交的摘要信息 4. 按模板格式化输出 ## 输出格式 参考 templates/report.md 中的模板。 ## 注意事项 - 如果日期范围内没有提交,返回提示信息而非空报告 - 提交信息中的敏感内容需要过滤这里有几个细节值得展开说。description要同时包含“做什么”和“什么时候用”,模型主要靠它判断触发时机。triggers是辅助触发词,用户说的话里包含这些词时更容易命中。执行步骤要写得足够具体,但也不要细到每一步都规定死,给模型留一点灵活空间。
我踩过的一个坑是:一开始把 description 写得太技术化,用了很多内部术语,结果模型根本不知道什么时候该调用它。后来改成大白话描述使用场景,触发准确率明显提升。
4.3 给 skill 加上脚本和模板
纯指令型的 skill 只能做模型能力范围内的事。要让它真正“动手”,得配上脚本。脚本一般放在scripts/目录下,用 Python、Node 或 shell 都行,看你的技术栈。
比如周报 skill 里,我放了一个collect_commits.py:
import subprocess import sys from datetime import datetime def get_commits(repo_path, start_date, end_date): cmd = [ "git", "-C", repo_path, "log", f"--since={start_date}", f"--until={end_date}", "--pretty=format:%h|%an|%s|%ad", "--date=short" ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Error: {result.stderr}", file=sys.stderr) return [] commits = [] for line in result.stdout.strip().split("\n"): if line: parts = line.split("|") commits.append({ "hash": parts[0], "author": parts[1], "message": parts[2], "date": parts[3] }) return commits if __name__ == "__main__": repo = sys.argv[1] start = sys.argv[2] end = sys.argv[3] for c in get_commits(repo, start, end): print(f"{c['date']} {c['author']}: {c['message']}")然后在SKILL.md里说明怎么调用这个脚本。模型会先执行脚本拿到原始数据,再根据模板整理成最终报告。
模板文件放在templates/下,用占位符标记需要填充的部分:
# 周报({{start_date}} 至 {{end_date}}) ## 本周完成 {{completed_items}} ## 进行中 {{in_progress_items}} ## 下周计划 {{next_week_plan}}这样模型只需要负责“把数据填进模板”,格式稳定性大大提高。我实测下来,有模板的 skill 输出质量比纯自由发挥稳定得多,尤其是需要固定格式的场景。
5. 好用的 skills 推荐与场景实测
5.1 前端开发场景:Playwright 自动化验证
前端开发是我用 skills 最多的场景。以前让 AI 改完代码,我得自己打开浏览器看效果。现在挂了 Playwright skill,它能自己跑起来验证。
典型工作流是这样的:我让 Agent 改一个按钮样式,它改完代码后自动调用 Playwright skill,启动浏览器、打开页面、截图、对比预期。如果样式不对,它会自己再改一轮。整个过程我只需要最后看一眼结果。
这个 skill 的价值在于闭环。没有它的时候,AI 改代码是“盲改”,改完不知道对不对。有了它,AI 能自己验证,迭代效率提升非常明显。
配置上要注意的是浏览器内核的下载。前面提到的npx playwright install失败问题,在这个场景里最容易遇到。我的建议是提前把浏览器装好,别等到 skill 运行时才现装。
5.2 论文写作场景:结构化研究与引用管理
热搜里有个词是“codex写论文的skills”,我专门试过。论文写作的痛点在于:需要大量查资料、需要规范引用、需要保持结构一致。这些恰好是 skill 擅长的。
我搭的一套论文 skill 包含三个子能力:文献检索、引用格式化、章节结构检查。文献检索负责从指定来源拉取相关论文摘要;引用格式化负责把引用统一成指定格式(APA、MLA 等);章节结构检查负责对比模板,看有没有缺章节或结构混乱。
实测下来,这套 skill 最大的价值不是“帮你写”,而是“帮你管”。论文写作中真正耗时的往往是格式和引用这些琐事,skill 把这些自动化之后,人能专注在内容本身上。
注意:文献检索类 skill 要特别注意来源的可靠性。我一般会限定只从几个权威来源拉取,避免引入质量参差不齐的内容。
5.3 自动化测试与安全检测场景
热搜里还有“自动挖洞skills”和“agent skills测试”这类词,指向的是自动化和安全检测场景。这类 skill 的特点是流程长、步骤多、对准确性要求高。
我搭过一个接口自动化测试 skill,流程是:读取接口定义文件、生成测试用例、执行测试、汇总结果、生成报告。整个流程封装成一个 skill 后,每次接口有变动,跑一遍就行,不用手动重写测试。
安全检测类的 skill 我用得比较谨慎。这类 skill 通常需要扫描目标、分析响应、判断漏洞,对误报率要求很高。我的做法是让 skill 只负责“收集信息”和“初步分类”,最终判断还是人工来做。把 skill 定位成助手而不是决策者,风险可控得多。
这类 skill 开发时有个经验:把每一步的中间结果都落盘保存。因为流程长,一旦中间某步出错,有中间结果就能快速定位问题,不用从头重跑。
6. 实操中踩过的坑与排查技巧
6.1 skill 不触发或误触发怎么办
这是最常见的问题。表现是:明明该用某个 skill,Agent 却没用;或者不该用的时候,它乱用。
排查思路分三步。第一步,检查 description 是否清晰。把 description 单独拿出来读一遍,问自己:一个不了解背景的人,能不能从这段话判断出什么时候该用?如果答案是否定的,就得改。
第二步,检查触发词覆盖。用户的实际表达可能和你想的不一样。比如你写的是“生成周报”,用户说的是“帮我总结下这周干了啥”。这时候要么加触发词,要么把 description 写得更贴近自然语言。
第三步,检查 skill 数量。skills 装太多会互相干扰,模型在多个相似 skill 之间容易选错。我的经验是同类 skill 只保留一个,功能重叠的合并掉。
6.2 上下文被占满导致响应变慢
skills 装多了之后,响应明显变慢,这是上下文被占满的典型表现。每个 skill 的元信息都要占 token,几十个 skill 加起来就是不小的开销。
解决办法有两个。一是用懒加载,只把 skill 名称和简短描述注入,完整指令等触发时再读。二是定期清理,把不用的 skill 删掉。我一般每个月过一遍 skills 列表,三个月没用过的就删。
还有一个技巧是分层组织。把常用 skill 放在一级目录,不常用的放到子目录里,加载时只扫一级目录。这样既保留了能力,又不占用日常上下文。
6.3 脚本执行权限与路径问题
skill 里的脚本执行失败,十有八九是权限或路径问题。权限方面,脚本文件要有可执行权限:
chmod +x scripts/run.py路径方面,脚本里尽量用相对路径或环境变量,别写死绝对路径。因为 skill 可能被安装到不同机器上,写死路径换台机器就挂了。
我习惯在脚本开头加一段路径处理:
import os SKILL_DIR = os.path.dirname(os.path.abspath(__file__)) TEMPLATE_DIR = os.path.join(SKILL_DIR, "..", "templates")这样不管 skill 装在哪,脚本都能找到自己的资源文件。
6.4 常见问题速查表
| 问题 | 可能原因 | 快速排查 |
|---|---|---|
| skill 装了但列表里没有 | 安装路径不对 | 检查 skills 目录配置 |
| 调用时报“找不到命令” | 脚本无执行权限 | chmod +x 加权限 |
| 输出格式乱 | 模板未正确加载 | 检查模板路径 |
| 响应特别慢 | skills 过多占上下文 | 清理不用的 skill |
| 触发不稳定 | description 模糊 | 重写描述,加触发词 |
| 脚本报依赖缺失 | 环境未装依赖 | 按报错装对应包 |
这张表是我自己排查时总结的,基本覆盖了八成以上的常见问题。遇到新问题先对照这张表过一遍,能省不少时间。
7. skills 生态的扩展玩法
7.1 组合多个 skill 完成复杂任务
单个 skill 能力有限,但组合起来能做的事就多了。我搭过一条内容生产流水线:素材收集 skill 负责从指定来源拉取信息,内容整理 skill 负责结构化,配图生成 skill 负责出图,排版 skill 负责最终格式化。四个 skill 串起来,从原始素材到成品文章基本全自动。
组合的关键是接口对齐。前一个 skill 的输出格式,要正好是后一个 skill 的输入格式。我一般会先定义好中间数据格式,再分别开发各个 skill,这样拼起来不会出问题。
7.2 把 skill 分享给团队使用
个人用的 skill 和团队用的 skill,要求不一样。个人用可以随意一点,团队用就得考虑版本管理、权限控制、文档说明。
我的做法是建一个内部 skills 仓库,每个 skill 独立目录,用 Git 管理版本。新成员入职时,拉下仓库、跑一遍安装脚本,环境就配好了。skill 更新走正常的代码评审流程,避免有人改坏了影响所有人。
文档方面,每个 skill 除了SKILL.md,我还会额外写一个README.md,面向人类读者,说明这个 skill 解决什么问题、怎么用、有什么限制。SKILL.md是给模型看的,README.md是给人看的,两者分工明确。
7.3 持续迭代:根据使用反馈优化 skill
skill 不是写完就完事了,得根据实际使用情况持续优化。我一般会记录每次 skill 调用的情况:触发了没有、结果对不对、哪里需要手动干预。攒一段时间后回头看,问题模式就出来了。
常见的优化方向有三个。一是补充边界情况处理,比如输入为空、格式不对、依赖服务不可用时的表现。二是优化输出格式,让结果更符合实际使用习惯。三是精简指令,把模型容易误解的部分改得更直白。
我个人的体会是,skill 的质量和迭代次数强相关。第一版能用就行,后面根据反馈慢慢打磨,用着用着就顺手了。急着一次做到完美,反而容易在细节上纠结太久,耽误实际使用。
最后分享一个小技巧:给 skill 加一个“调试模式”,开启后会把中间步骤和决策过程都打印出来。排查问题时特别有用,能清楚看到模型在哪一步做了错误判断。平时关掉,不影响正常使用。