这段时间 AI 圈最热闹的一个词,除了 agent,就是skills。我关注这个方向,很大程度上是因为 Andrej Karpathy 在多个场合反复提过一个观点:未来大模型的使用方式,不会停留在"你问我答",而是会演化成"你给模型一套可复用的技能包,让它自己调用"。吴恩达随后也专门做了 agent skills 的教程,GitHub 上一夜之间冒出来一堆 skills 仓库,Claude Code、Codex、opencode 这些工具也纷纷把 skills 作为一等公民。这篇博文就围绕andrej-karpathy-skills这个话题,聊聊我理解的 skills 到底是什么,和 prompt 有什么本质区别,以及我实际动手写一个代码仓库分析 skill 时的完整过程、踩坑记录和一些可复用的经验。适合正在研究 agent、给 AI 编程工具做增强,或者想把大模型接入自己工作流的人参考,新手也可以从零跟下来。
1. Karpathy 反复提 skills,其实是在说 agent 的"原子能力"
1.1 从"模型参数能力"到"上下文装配能力"的转变
先说个背景。过去一年我们衡量一个模型好不好,主要看它的参数量、训练数据、benchmark 分数。但是 Karpathy 几次公开讲话里,都强调了一个容易被忽略的事实:模型的固有能力只是下限,真正决定体验的是你往上下文里塞了什么。他把这个叫做"上下文工程",而 skills 就是上下文工程里最结构化的一种实现方式。
我举个生活化的类比。你请了一个很厉害的实习生,他本身聪明、学得快,但如果你不给他工作手册、不给模板、不告诉他公司内部的流程和工具怎么用,他发挥出来的水平可能连老员工的一半都不到。skills 就是那份"工作手册 + 工具清单 + 经验库"的三合一。模型权重里存的是"通用人类知识",而 skill 文件里存的是"某个特定场景下的做事方法"。这两者叠加,才是 agent 真正能干活的底层逻辑。
Karpathy 的原话大意是:我们不应该期待模型什么都会,而是应该期待模型"知道去哪里找怎么做的方法"。这句话对我的启发很大。它把问题的重心从"训练更大的模型"转移到了"设计更好的上下文结构",而这恰好是普通开发者也能参与的事情。
1.2 为什么偏偏是现在:上下文窗口和结构化指令的交叉点
有人可能会问:prompt 不是一直都能写吗?为什么 skills 这个概念现在才火?我觉得有三个客观条件刚好在这个时间点交汇。
第一是上下文窗口足够大了。早期模型上下文就几千 token,塞一份完整技能文档进去就占了一半,根本玩不转。现在 Claude、GPT 系列动辄几十万 token 的上下文,才允许我们把完整的操作手册、示例、规则、工具说明全部放进去。
第二是agent 类应用的爆发。纯聊天场景下,用户自己会补充背景信息,模型不需要"技能"。但 agent 要自主完成多步任务,它必须能够在没有人类干预的情况下知道"第一步做什么、用什么工具、遇到异常怎么处理"。这种自主性必须有结构化的技能文件支撑。
第三是工具生态的成熟。Claude Code 的 SKILL.md 约定、Codex 的 skills 目录、opencode 的 skills 机制,本质上都是在定义同一种东西:怎么让一个模型"学会"调用一个复杂工作流。各家虽然命名不同,但底层思路高度一致,这说明方向已经被验证了。
1.3 从"吴恩达都在出教程"看 skills 的行业信号
还有一个信号值得注意:Andrew Ng 专门出了一份 agent skills 的教程 PDF,GitHub 上相关的 skill 仓库已经成千上万。一个概念能同时吸引 Karpathy 和吴恩达这两位大佬下场,基本可以判断这不是一阵风,而是 agent 走向实用化的必经之路。
我自己观察到的行业变化是:招聘市场上已经开始出现"技能工程师"或者"agent 工作流工程师"这种岗位。传统上我们写代码是给 CPU 执行的,现在写的 SKILL.md 是给模型参考的,这是一种全新的"编程"方式。指令写得清楚,模型就稳定;指令写得模糊,模型就会自由发挥,结果不可控。这个领域的工程方法和最佳实践,目前还非常不成熟,所以谁先动手谁就有优势。
2. skills 不等于 prompt:四个关键差异必须搞清楚
2.1 一份 skill 的完整构成:不止是"一段话"
很多第一次接触 skills 的人,以为写一个 skill 就是写一段比较长的 prompt。我一开始也这么想,直到真正拆开一个成熟 skill 的目录结构才明白,差距非常大。一个标准的 skill 通常包含以下部分:
| 组成部分 | 作用 | 典型文件 |
|---|---|---|
| 声明文件 | 定义技能的名称、描述、适用场景、依赖 | SKILL.md |
| 知识资产 | 存放领域背景、规范、模板、经验库 | references/ 目录下的 md 文件 |
| 脚本工具 | 调用外部程序、解析代码、执行命令 | scripts/ 下的 Python 或 shell 脚本 |
| 示例库 | 输入输出对,供模型进行少样本参考 | examples/ 目录 |
| 测试用例 | 验证 skill 是否按预期工作 | tests/ 目录 |
SKILL.md 的开头还有 YAML frontmatter,标记技能的 name 和 description。很多工具就是靠解析这个 description 来决定"什么时候该调用这个技能"的。如果你的 description 写得太泛,模型就会在不需要的时候也去调用,反而干扰主任务。
2.2 差异一:prompt 是"一次性指令",skill 是"可复用资产"
普通 prompt 是写给一次对话看的,用完就扔。skill 则像一个函数封装,它把"怎么做某事"的完整方法论固化下来,可以在不同的对话、不同的项目中反复加载。这种复用性是 prompt 不具备的。
我举个例子。我写过一个"代码仓库分析"的 prompt,效果勉强能用,但每次都要把方法重新粘贴一遍,而且粘贴的长短不同,模型的行为就不同,很不稳定。后来我把它整理成一个 skill,包含仓库结构识别规则、核心模块提取方法、README 生成模板、常见架构模式的判断标准,结果稳定性和输出质量都有明显提升。
2.3 差异二:skill 能携带"知识",prompt 只能携带"指令"
指令解决的是"怎么做",知识解决的是"依据什么做"。比如你想让模型帮你审查代码中的安全漏洞,prompt 里写"请检查安全问题",模型能做的只是基于通用知识给出泛泛建议。但如果 skill 里附上了 OWASP 的检查清单、你们团队的编码规范、历史漏洞的案例库,模型的判断就有了依据,输出质量完全不同。
这也是为什么references 目录往往比 SKILL.md 本身更能决定 skill 的质量。写 skills 的时候,真正花时间的不是写指令,而是整理领域知识。
2.4 差异三:skill 是可测试、可迭代的,prompt 基本靠玄学
普通 prompt 改一个字效果可能都会变,而且很难说清是为什么。skill 因为有明确的输入输出定义和测试用例,你可以像调试代码一样调试它。我在实际开发 skill 时,会维护一组 golden 测试样本,每次修改 skill 之后跑一遍回归,确保旧功能没有退化。这在 prompt 开发里是难以想象的。把 prompt 工程升级成软件工程,正是 skills 最核心的价值。可复现、可追踪、可回归,这三个特性加在一起,才让"教模型做事"变成一项可靠的工程活动。
3. 亲手做一个"代码仓库分析"skill:选型、搭建与验证
3.1 工具选型:Claude Code、Codex、opencode 的 skills 生态对比
动手之前,先要选一个 agent 框架。我三个主流工具都实际用过,说说感受。
| 工具 | skill 语法 | 上手难度 | 社区生态 | 适用场景 |
|---|---|---|---|---|
| Claude Code | SKILL.md + 自动发现 | 低 | 很丰富 | 日常开发辅助、代码审查 |
| Codex | skills/ 目录 + 指令文件 | 中 | 较多 | 自动化编码任务、批量修改 |
| opencode | skills 插件机制 | 中高 | 快速增长 | 深度定制、多 agent 协作 |
我最终选择以 Claude Code 为主要实验环境,因为它的 SKILL.md 规范最简单清晰,社区里现成的 skill 最多,方便参考学习。同时我也会把 Codex 当作对照环境,检验 skill 的跨工具移植性。
下载和安装 skill 本身也有一套约定。比如很多开源 skills 支持一条命令直接添加:npx skills add <仓库地址> --agent claude-code -g -y。-g表示安装到全局目录,-y表示跳过交互确认。不同的 agent 后端会安装到不同位置,比如 Claude Code 一般放在~/.claude/skills/,Codex 放在~/.codex/skills/。这是我实际安装过程中确认过的路径。
3.2 初始化目录与命名规范
一个 skill 能不能被工具自动发现,目录命名非常关键。Claude Code 的约定是:放在 skills 目录下,每个 skill 一个文件夹,文件夹内必须有 SKILL.md。命名建议用连字符分隔的描述性名称,比如repo-analyzer、code-reviewer、security-auditor。
我用以下命令初始化了一个空项目:
mkdir -p ~/.claude/skills/repo-analyzer cd ~/.claude/skills/repo-analyzer mkdir -p references scripts examples tests touch SKILL.md这里有个坑:如果你把它放在项目的.claude/skills/目录下,它就只对该项目生效;放在用户全局的~/.claude/skills/目录下,则对所有项目生效。我建议先按项目调试,稳定后再迁移到全局,避免污染其他项目。
3.3 编写 SKILL.md:从空模板到可用版本
SKILL.md 是整个 skill 的入口。我一开始模仿社区模板写,后来发现很多描述对模型理解是多余的,反而增加了 token 开销。经过几轮迭代,我总结出一个比较精简的写法:
--- name: repo-analyzer description: 分析任意代码仓库的结构、核心模块、技术栈和潜在问题,输出结构化报告。适用于首次接触一个未知代码仓库的场景。 --- # 代码仓库分析 ## 适用场景 当用户提供一个陌生的代码仓库路径,希望快速了解其架构、技术选型、核心模块时使用。 ## 执行步骤 1. 扫描仓库根目录,读取配置文件(package.json、pyproject.toml、go.mod 等),识别技术栈。 2. 统计目录结构,找出源码目录、测试目录、文档目录、配置文件的位置。 3. 定位核心入口文件(如 main.py、index.js、cmd/main.go)。 4. 分析核心模块之间的依赖关系,绘制模块层级。 5. 检查是否存在明显的坏味道(超大文件、重复代码、循环依赖、裸露的密钥)。 6. 输出 Markdown 格式的分析报告。 ## 报告模板 见 references/report-template.md ## 注意事项 - 不要访问 .git 目录内部的原始对象。 - 对于 Monorepo,先识别子项目边界。 - 如果仓库过大,优先分析构建配置和入口文件,避免遍历所有文件。写完 SKILL.md 之后,我把 report-template 放进 references 目录,又把一个仓库分析的数据采集脚本放进了 scripts 目录。脚本负责提取关键信息,减少模型对大文件的直接阅读量。
3.4 验证:用真实项目测试并记录迭代日志
写完之后,我找了一个中型开源项目做测试。第一次运行的结果并不理想:模型忽略了我定义的报告模板,自己生成了一个不同的结构。我检查日志后发现,原因是 references 目录下的模板文件没有被模型读取到。Claude Code 对 references 目录下的文件不会自动加载,模型需要主动决定要不要去读取。解决方法是在 SKILL.md 的执行步骤里显式写明"请先阅读 references/report-template.md,再按照该模板输出"。加了这一步之后,输出结构马上就稳定了。
这个发现非常重要,model 不会自动加载 references,你必须教它在哪里、何时去读。很多 skill 看起来内容齐全但模型表现不好,根源就在这里。
4. 跑通 demo 后踩过的坑:一次完整的排错链路复盘
4.1 第一个坑:npx skills 安装失败,路径却依然被写入
我第一次尝试安装社区 skill 时,执行了npx skills add sandai-org/vidmuse-skills --agent claude-code -g -y。命令本身运行了一半,出现网络超时提示,我以为失败了,也没在意。结果第二天发现 Claude Code 启动时一直在报错,说加载某个 skill 失败。
排查过程是这样的:我先检查了全局 skill 目录,发现多了一个vidmuse-skills文件夹,但里面是空的。也就是说,这个命令在下载解压之前就先把目录结构创建好了,网络中断导致下载不完整,但目录被留了下来。Claude Code 扫描到空目录,尝试加载,当然就报错。
解决办法很简单:把那 个空目录删掉重新安装。但这件事给我的教训是:用 npx 这类命令安装 skill 时,一定要确认下载完整,别看到命令执行完就觉得万事大吉。最好检查一下安装目录下是否真的存在 SKILL.md 文件,以及文件内容是否完整。
4.2 第二个坑:上下文窗口溢出,skill 内容反而成为负担
项目测试到一个比较大的仓库时,Claude Code 频繁报"上下文溢出"。我开始以为是仓库文件太多导致的,后来通过查看 token 统计发现,很大一部分 token 被 skill 里的 references 文档占用了,而不是被仓库源码占用。
原因是 references 目录下我放了一份很详细的架构分析文档,里面有很多代码片段,光这一份就几万 token。模型在分析仓库时把整份文档都读进去了,加上仓库本身的文件内容,很快就触及上限。
解决方案是做"瘦身":把 references 目录下的文档明确标注为"按需读取",在 SKILL.md 里写清楚只有在处理特定任务时才需要读取对应文档。同时把脚本的输出设计得更精简,只保留关键指标。优化之后,同样的任务 token 消耗下降了约 40%。
4.3 第三个坑:脚本权限不足导致 skill 内部工具调用失败
我的 skill 里有一个脚本用来统计代码行数和文件数量。测试时发现脚本在独立 shell 里能正常运行,但通过 Claude Code 调用时总是报"permission denied"。
一开始我以为是文件权限问题,用 chmod +x 修改了脚本权限,仍然不行。后来检查 Claude Code 的 sandbox 配置才想明白:agent 工具有自己的沙箱环境,外部脚本默认没有执行权限,需要在工具配置里显式允许执行外部脚本。我把脚本调用方式从直接执行改为通过python3 script.py方式调用,问题解决。因为绕过可执行位检查,直接交给解释器执行。
这个坑很隐蔽,因为它和环境配置有关,而不是脚本本身。所以如果你在 skill 里集成了脚本,最好在 SKILL.md 里注明需要哪些运行时依赖,以及是否需要特定的权限配置,这样别人复现你的 skill 时才不会被卡住。
4.4 技能本身的版本管理
随着我给 skill 添加了新功能,一个很现实的问题出现了:怎么管理 skill 的版本?SKILL.md 只是文本文件,不涉及代码编译,但多个版本的迭代还是需要管理。
我的做法是把 skill 仓库单独放到 Git 仓库里管理,每个功能作为一个分支,合并到 main 之后打 tag。同时用 golden 测试集做回归测试——我维护了 5 个测试仓库,每次修改 skill 后都会跑一遍,确保之前的分析结果没有被破坏。这种"skill 即代码"的管理方式一开始有点繁琐,但用久了就会觉得安心:至少你知道每一次改动是有记录的,出了问题也能快速回溯到上一个可用版本。
5. 把 skills 玩出生产力的进阶思路
5.1 从单一 skill 到 skill 组合:多个技能如何协同
单个 skill 解决的是单一任务,但在真实场景中,一个复杂项目往往需要多个 skill 联动。比如我想写一篇代码仓库的技术博客,就需要"仓库分析 skill"产出的报告,加上"技术写作 skill"来生成文章结构,再加上"Markdown 格式规范 skill"来统一排版。
多个 skill 组合时,最大的挑战是避免技能之间的指令冲突。比如两个 skill 都定义了"输出格式",模型就会困惑。我现在的做法是设计一个主导 skill,它负责编排流程,其他 skill 作为被调用的子模块。主 skill 只在某一阶段需要时才加载子 skill 的说明文档,而不是一次性全部加载。
5.2 领域定制:数学建模、渗透测试、前端开发的 skill 化
从热门搜索词里能看到,skills 的应用已经延伸到很多具体领域,比如"数学建模 skills""渗透测试 skills""前端开发 skills"。这些领域有一个共同特点:专业流程清晰,知识体系庞大,非常适合作成技能包。以数学建模为例,一个完整的建模 skill 应该包含:问题分析框架、模型选择决策树、论文排版模板、常见算法代码库。有了这个 skill,模型在建模比赛中的表现会明显好于直接 prompt。
我在前端开发场景也试验过。一个 UI 设计 skill 如果包含了设计规范、组件库说明、响应式布局规则,生成出来的页面代码质量会稳定很多。这说明 skills 本质上是个知识工程问题:你能不能把领域经验结构化,决定了 skill 的上限。
5.3 距离 Karpathy 设想的"通用 agent"还有多远
最后说点更长远的。Karpathy 设想的未来,agent 会拥有一个"技能库",根据任务需求动态组合和调用技能。这个方向我觉得是对的,但目前还有很多问题没有解决:
- 技能发现机制还很原始。现在靠 description 匹配,效果不稳定,经常出现模型不知道该调用哪个技能的情况。
- 技能之间的依赖关系没有标准。A 技能需要 B 技能的输出,这种关系目前只能靠人在编排时手动处理。
- 技能的质量评估缺乏统一标准。什么算一个好 skill?各家有各家的说法,但没有像软件工程那样的成熟度量体系。
这些问题不是短期能解决的,但恰恰说明这个领域还在早期,机会很多。我自己的体会是:与其等生态成熟,不如现在就开始亲手写几个 skill,把技能设计和工程方法跑通。一个能用的技能库,是未来所有 agent 应用的底层资产,这种积累越早开始越有价值。
我在实际把 skills 应用到日常工作之后,最大的收获不是模型输出变稳定了,而是我开始把"教模型做事"当成一项真正的工程来对待。它需要你拆解任务、抽象流程、沉淀知识、设计验证集,这比单纯写 prompt 难,但回报也大得多。如果你正准备入坑,我的建议是从一个你非常熟悉的领域开始,比如你自己的日常工作流程,把它整理成第一个 skill,然后跑通验证循环。技术上的坑不难踩平,真正难的是把你脑子里的隐性知识结构化出来,这个过程本身就会让你对自己手头的工作有更深的理解。