☰
Agent Skills 实战指南:从原理到编写可复用技能包
2026/10/6 9:31:20 网站建设 项目流程

1. 从“skills”这个热词说起:它到底是什么

最近半年,不管是在技术社区、开发者群聊,还是各种工具链的讨论帖里,“skills”这个词出现的频率高得离谱。很多人第一次看到“skills”这个词,脑子里浮现的是招聘网站上的“技能要求”,但在当下的语境里,它指的是一套全新的能力封装机制——Agent Skills。简单说,就是把一段可复用的指令、流程、工具调用逻辑打包成一个标准化的“技能包”,让 AI agent 能够按需加载、按需执行。

你可能会问,这不就是插件吗?不完全是。插件更多是给宿主程序增加功能,而 skills 的核心在于“教会 agent 怎么做一件事”。它更像是一份写给 AI 看的操作手册,里面包含了触发条件、执行步骤、依赖工具、输出格式,甚至还有失败重试的逻辑。一个写得好的 skill,能让 agent 从“能聊天”变成“能干活”。

这套机制最早在 Claude 的生态里被大规模讨论,后来 Codex、Google Cloud 的 agent 体系也陆续跟进。现在你在 GitHub 上搜 “skills”,能翻出成百上千个仓库,有做代码审查的、有做论文写作的、有做分镜脚本的,甚至还有专门用来“自动挖洞”的安全类 skill。热词里提到的 “claude agent skills: a first principles deep dive”、“codex skills”、“agent skills 测试”这些,都是这个生态里的典型话题。

这篇文章适合谁看?如果你是刚接触 agent 开发的工程师,想搞清楚 skills 的目录结构、加载机制和调试方法,那这篇就是写给你的。如果你已经在用 Claude 或 Codex 做日常开发,想把自己重复性的工作流封装成 skill,那更好,我会把实操步骤拆到你能直接抄作业的程度。如果你只是好奇“skills 大全”里到底有什么、值不值得花时间折腾,我也会给你一个务实的判断。

2. 核心机制拆解:skills 为什么这样设计

2.1 从“提示词工程”到“技能封装”的演进逻辑

早期我们用 AI 写代码,靠的是在对话框里反复调提示词。今天写一个“帮我审查这段 Python 代码”的提示,明天写一个“帮我生成单元测试”的提示,每次都要重新描述一遍上下文。这种做法的问题很明显:不可复用、不可版本管理、不可组合。你调好了一个提示词,换一个会话就没了,想分享给同事只能复制粘贴。

skills 的出现,本质上是对“提示词工程”的一次工程化改造。它把提示词从“一次性对话内容”变成了“可持久化的文件资产”。一个 skill 通常是一个目录,里面至少有一个SKILL.md文件,用 YAML frontmatter 声明元信息,用 Markdown 正文描述执行逻辑。agent 在启动时会扫描 skills 目录,根据当前任务匹配对应的 skill,然后加载它的内容作为系统提示的一部分。

这个设计的好处在于:第一,可版本控制,skill 文件可以提交到 Git,谁改了什么一目了然;第二,可组合,一个任务可以同时加载多个 skill,比如“代码审查”加“安全扫描”加“性能分析”;第三,可测试,你可以写测试用例来验证 skill 在给定输入下是否产生预期输出。

2.2 SKILL.md 的结构与字段含义

一个标准的 skill 目录长这样:

my-skill/ ├── SKILL.md ├── scripts/ │ └── helper.py ├── references/ │ └── checklist.md └── assets/ └── template.json

核心是SKILL.md,它的开头必须是 YAML frontmatter:

--- name: code-review description: 对指定代码文件进行结构化审查,输出问题清单和改进建议 version: 1.2.0 author: your-name tags: - code-quality - review ---

name是 skill 的唯一标识,agent 在匹配时会用它来索引。description最关键,它决定了 agent 在什么场景下会触发这个 skill。写得太宽泛,比如“帮助处理代码”,会导致误触发;写得太窄,比如“审查 Python 3.11 中 asyncio 的异常处理”,又会导致该触发的时候不触发。我的经验是,description 里要包含动作、对象和输出三个要素,比如“审查 Python 代码文件,输出按严重程度排序的问题列表”。

正文部分就是写给 agent 的指令。这里有个常见的误区:很多人把正文写成给人看的文档,用了大量“本文将介绍”“首先我们需要”这种叙述性语言。实际上 agent 不需要这些过渡,它需要的是明确的步骤、判断条件和输出格式。我一般会按这个结构来写:

## 执行步骤 1. 读取用户指定的文件路径,如果路径不存在,返回错误信息并终止。 2. 按以下维度逐行检查: - 变量命名是否符合 snake_case - 是否有未处理的异常分支 - 是否存在硬编码的密钥或令牌 3. 对每个发现的问题,记录行号、问题类型、严重程度(高/中/低)。 4. 按严重程度降序排列,输出 Markdown 表格。 ## 输出格式 | 行号 | 问题类型 | 严重程度 | 建议 | |------|----------|----------|------| | 12 | 命名不规范 | 低 | 改为 user_name |

2.3 加载机制:agent 怎么找到并执行 skill

不同平台的加载机制略有差异,但核心逻辑大同小异。以 Claude 的 agent 体系为例,skills 通常放在项目根目录的.claude/skills/下,或者用户主目录的~/.claude/skills/下。agent 启动时会递归扫描这些目录,读取每个SKILL.md的 frontmatter,建立一个“技能索引”。

当用户发起一个任务时,agent 会先做一次意图匹配:把用户输入和所有 skill 的 description 做语义相似度计算,选出 top-k 个候选 skill。然后根据任务的复杂度,决定是加载一个还是多个。加载之后,skill 的正文内容会被拼接到系统提示里,agent 就“学会”了这个技能。

这里有个细节值得注意:skill 的加载是有 token 成本的。一个写得啰嗦的 skill 可能占用几千个 token,加载三四个就把上下文窗口吃掉一大半。所以我在写 skill 时,会尽量把通用知识放到references/目录里,正文只保留执行逻辑,需要时再让 agent 去读参考文件。这样既保证了灵活性,又控制了上下文开销。

3. 实操:从零写一个可用的 skill

3.1 环境准备与目录初始化

假设你要写一个“自动生成单元测试”的 skill。第一步是确定存放位置。如果你用的是 Claude Code,推荐放在项目根目录的.claude/skills/下,这样团队里每个人拉取代码后都能直接用。如果是个人常用技能,放在~/.claude/skills/下更合适。

初始化命令很简单:

mkdir -p .claude/skills/unit-test-gen/scripts cd .claude/skills/unit-test-gen touch SKILL.md

如果你用的是 Codex 体系,目录名可能是.codex/skills/,具体以你所用工具的文档为准。热词里提到的 “claude 国内安装 skills 官方市场” 和 “skills 下载平台有哪些”,其实指的就是从社区仓库克隆现成的 skill 目录,放到对应的 skills 路径下即可。我一般会先建一个vendor/目录来存放第三方 skill,方便后续更新和替换。

3.2 编写 SKILL.md 的完整示例

下面是我实际在用的一个单元测试生成 skill 的完整内容,你可以直接复制修改:

--- name: unit-test-gen description: 为指定的 Python 函数或类生成 pytest 单元测试,覆盖正常路径、边界条件和异常分支 version: 1.0.0 tags: - testing - python - pytest ---

正文部分:

## 前置检查 1. 确认用户提供了目标文件路径和函数名。如果缺少任一信息,询问用户补充。 2. 读取目标文件,定位到指定函数或类。如果找不到,返回“未找到目标符号”并终止。 ## 生成规则 1. 为每个公开方法生成至少三个测试用例: - 正常输入下的预期输出 - 边界值(如空列表、零、最大整数) - 异常输入(如 None、类型错误) 2. 使用 pytest 风格,测试函数命名格式为 `test_<函数名>_<场景>`。 3. 如果目标函数依赖外部服务,使用 `unittest.mock` 进行打桩,不要发起真实网络请求。 4. 生成的测试文件放在与被测文件同级的 `tests/` 目录下,文件名格式为 `test_<原文件名>.py`。 ## 输出要求 - 只输出测试代码,不要输出解释性文字。 - 代码块语言标注为 python。 - 如果目标函数已有测试文件,追加新用例而不是覆盖。

写完这个文件后,你可以用npx来快速验证 skill 是否被正确加载。热词里提到的 “claude mcpservers npx” 和 “npx playwright install 失败”,其实反映了一个常见场景:很多 skill 依赖外部工具链,比如 Playwright 用于浏览器自动化。如果你的 skill 里调用了npx playwright,而本地没有安装浏览器二进制,就会报错。解决办法是先手动执行npx playwright install chromium,把依赖装好,再让 agent 去调用。

3.3 调试与验证:怎么知道 skill 生效了

写完 skill 后,不要直接扔给 agent 跑复杂任务。我习惯先用一个最小可复现的输入来验证。比如对于上面的单元测试 skill,我会准备一个简单的 Python 文件:

def add(a, b): if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): raise TypeError("参数必须是数字") return a + b

然后对 agent 说:“用 unit-test-gen 技能为 add 函数生成测试。” 如果 agent 正确加载了 skill,它应该输出三个测试用例,分别覆盖正常相加、边界值(比如 0 和负数)、以及类型错误。如果它只是泛泛地写了一个测试,说明 skill 的 description 没有匹配上,或者加载路径不对。

排查加载问题的顺序是:第一,确认SKILL.md的 frontmatter 格式正确,YAML 对缩进敏感,一个 tab 就能让解析失败;第二,确认目录层级没有多一层或少一层,有些工具要求 skill 目录直接放在 skills 根目录下,不能再嵌套;第三,查看 agent 的启动日志,通常会打印“loaded N skills”之类的信息,如果数量不对,说明扫描路径有问题。

4. 进阶玩法:组合、测试与性能优化

4.1 多 skill 组合与优先级管理

单个 skill 能做的事有限,真正强大的是组合。比如你可以同时加载“代码审查”“安全扫描”“性能分析”三个 skill,让 agent 对同一个文件做多维度检查。但这里有个坑:不同 skill 的指令可能冲突。比如 A skill 要求输出 JSON,B skill 要求输出 Markdown,agent 就会懵。

我的做法是在每个 skill 的 frontmatter 里加一个priority字段,数值越小优先级越高。当冲突发生时,agent 按优先级决定听谁的。另外,我会在项目根目录放一个skills.config.json,显式声明哪些 skill 可以同时加载、哪些互斥:

{ "combinations": [ { "skills": ["code-review", "security-scan"], "mode": "sequential" }, { "skills": ["unit-test-gen", "coverage-report"], "mode": "parallel" } ], "exclusive": [ ["format-json", "format-markdown"] ] }

这个配置文件不是所有平台都支持,但你可以把它作为团队约定,写在 README 里,让每个人手动遵守。

4.2 为 skill 写测试用例

热词里有个词叫 “agent skills 测试”,这说明大家已经意识到 skill 也需要测试。我通常用两种方式:单元测试和端到端测试。

单元测试针对 skill 里的脚本。比如你的 skill 包含一个scripts/parse_ast.py,那就用 pytest 给它写测试,验证输入输出是否符合预期。这部分和普通 Python 测试没区别。

端到端测试更关键:准备一组输入样本,让 agent 加载 skill 后执行,检查输出是否包含预期关键词。比如对于代码审查 skill,我会准备一个故意包含漏洞的文件,然后断言 agent 的输出里必须出现“硬编码密钥”和“未处理异常”这两个词。如果没出现,说明 skill 的指令不够明确,需要调整。

我一般会把端到端测试写成 shell 脚本,放在tests/e2e/下:

#!/bin/bash output=$(agent run --skill code-review --input tests/fixtures/vulnerable.py) if echo "$output" | grep -q "硬编码密钥"; then echo "PASS" else echo "FAIL: 未检测到硬编码密钥" exit 1 fi

4.3 控制 token 开销的实用技巧

前面提到 skill 加载会消耗 token,这里展开说几个我实测有效的优化手段。

第一,把长文档拆到 references 目录。正文只保留“什么时候读哪个文件”的指令,比如“如果用户要求检查安全合规性,读取 references/security-checklist.md”。这样 agent 只在需要时才加载大文件。

第二,用表格代替段落。同样的信息,表格比段落节省 30% 到 50% 的 token。比如检查项列表,用表格写“检查项 | 判断条件 | 严重程度”,比用三段话描述要紧凑得多。

第三,避免重复描述。如果你有多个 skill 都需要“读取文件”这个步骤,不要在每个 skill 里都写一遍,而是抽出一个公共 skill,让其他 skill 通过depends_on字段引用它。这样公共部分只加载一次。

第四,定期清理未使用的 skill。我见过一个项目里堆了四十多个 skill,agent 每次启动都要扫描一遍,光索引就吃掉不少 token。后来我按季度做一次清理,把三个月没触发过的 skill 归档到skills-archive/目录,启动速度明显提升。

5. 常见问题与排查速查表

5.1 skill 不触发或误触发怎么办

这是最高频的问题。表现是:你明明写了 skill,agent 却不用;或者你只是随便聊一句,agent 却加载了一堆无关 skill。

排查思路分三步。第一步,检查 description 的语义覆盖范围。你可以把 description 和用户输入分别做 embedding,算一下余弦相似度。如果低于 0.7,基本不会触发;如果高于 0.9,可能误触发。第二步,检查是否有多个 skill 的 description 高度相似,导致 agent 选择困难。解决办法是给每个 skill 加一个exclusive_group字段,同一组内只允许一个被加载。第三步,检查 agent 的匹配阈值配置,有些平台允许你调整触发灵敏度,默认值可能偏保守。

我自己的经验是,description 里最好包含一个否定条件。比如“审查 Python 代码,但不处理 Jupyter Notebook 文件”。这样能有效减少误触发。

5.2 依赖工具安装失败的典型场景

热词里 “npx playwright install 失败” 是个典型。很多 skill 依赖外部命令行工具,比如 Playwright、FFmpeg、ImageMagick。如果这些工具没装好,skill 执行到一半就会报错。

我的做法是在 skill 目录下放一个setup.sh,把所有依赖安装命令写进去:

#!/bin/bash set -e npm install -g playwright npx playwright install chromium --with-deps pip install -r requirements.txt

然后在SKILL.md的前置检查里加一条:“如果检测到依赖缺失,提示用户先运行bash setup.sh。” 这样比让 agent 自己猜要可靠得多。

另外,网络环境不稳定时,npx下载可能超时。可以配置镜像源或者提前把包缓存到本地。具体方法因环境而异,核心思路是把不确定性前置解决,不要让 agent 在运行时去处理网络问题。

5.3 输出格式不稳定的修正方法

同一个 skill,有时候输出 Markdown 表格,有时候输出 JSON,有时候又变成纯文本。这种不稳定性通常是因为指令不够具体。

修正方法是:在SKILL.md里给出完整的输出模板,而不是只描述格式要求。比如不要写“输出一个表格”,而是写:

## 输出模板 严格按以下格式输出,不要添加额外说明: | 行号 | 问题 | 严重程度 | |------|------|----------| | {line} | {issue} | {severity} |

把占位符写清楚,agent 的发挥空间就小了,一致性自然就上来了。如果还是不稳定,可以在 skill 里加一句“如果输出不符合模板,重新生成一次”。

5.4 速查表

问题现象可能原因排查动作解决方式
skill 不触发description 太窄检查语义相似度放宽 description,加入同义词
skill 误触发description 太宽检查是否有否定条件加入排除场景,设置 exclusive_group
加载报错YAML 格式错误用 yamllint 检查修正缩进,避免 tab
依赖缺失未安装外部工具查看错误日志编写 setup.sh 并前置执行
输出格式乱指令不具体对比多次输出提供完整输出模板
token 超限skill 太冗长统计 token 数拆分到 references,用表格替代段落

6. 我对 skills 生态的一些个人判断

折腾了几个月 skills 之后,我最大的体会是:写 skill 的难度不在于技术,而在于“把隐性知识显性化”。你脑子里知道怎么审查代码、怎么生成测试、怎么做安全扫描,但要把这些步骤拆成 agent 能执行的指令,需要你对流程有非常清晰的认识。很多 skill 写得不好,不是因为作者不懂技术,而是因为作者默认了很多前提条件,没有写出来。

另一个感受是,skills 的复用价值被低估了。热词里 “skills 大全”“skills 推荐”“codex 好用的 skills” 这些搜索词,说明大家有很强的“找现成”需求。但现成的 skill 往往和你的项目上下文不匹配,直接拿来用效果一般。我的建议是:先找几个高质量的 skill 作为参考,理解它们的结构,然后基于自己的实际工作流改写。改上三五个之后,你就能形成自己的 skill 模板库了。

最后分享一个小技巧:我会在~/.claude/skills/下放一个_template/目录,里面是空的SKILL.md骨架,包含 frontmatter 和常用的章节标题。每次要写新 skill,直接复制这个模板,改改 name 和 description,十分钟就能出一个初版。这个习惯让我从“想写 skill”到“写完 skill”的周期缩短了一大半。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询