1. 当 Agent 能力越堆越多,为什么反而变笨了
如果你最近在 Claude Code、Cursor 或者 OpenCode 里给 AI Agent 加过能力,大概率遇到过这个场景:一开始只挂两三个工具,Agent 干活又快又准;后来你把团队里所有脚本、规范、模板都塞进系统提示词,结果它开始答非所问,明明该调用 A 技能却调了 B,甚至把不相关的流程也硬套进来。
问题不在模型,而在组织方式。所有能力都平铺在上下文里,Agent 每次启动都要把全部内容读一遍,token 消耗暴涨,注意力被稀释,调用自然混乱。这就像你给一个新员工一本没有目录、没有章节、所有内容糊在一起的万字手册,他找一条报销规则要翻半小时。
Agent Skills 想解决的就是这件事。它把能力拆成一个个独立文件夹,每个文件夹里放一份SKILL.md作为入口,Agent 启动时只读每个技能的name和description,相当于先看目录;等任务真正匹配到某个技能,才加载完整正文。这个机制叫渐进式上下文加载(Progressive Disclosure),是 Skills 区别于普通提示词模板的核心。
这篇面向已经在用 Claude Code 等工具、想让 Agent 能力可维护的开发者。我会先讲清楚SKILL.md的目录骨架,再给出技能注册配置的可复制片段,最后演示新增一个技能后怎么验证 Agent 能正确命中它。全程围绕“带目录说明书”这个思路展开,不堆概念。
2. 前置准备:TaoToken 接入与 Skills 运行环境
在动手写技能之前,得先让 Claude Code 这类工具能稳定跑起来。我自己的做法是通过 TaoToken 统一接入模型,好处是 API Key 和接入地址集中管理,后面切换模型或做多技能验证时不用反复改配置。
TaoToken 的官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数,配置时直接填这个。
你需要先拿到 API Key。登录后进入控制台,在 API Keys 页面创建一个新 Key,复制保存。这个 Key 就是后面settings.json里的ANTHROPIC_AUTH_TOKEN。
Claude Code 的配置目录在用户主目录下的~/.claude/。如果目录不存在就手动创建。核心是settings.json,它负责告诉 Claude Code 用哪个后端、超时多久、是否关闭非必要流量。下面是我实测可用的配置片段:
{ "env": { "ANTHROPIC_AUTH_TOKEN": "你的 TaoToken API Key", "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1 } }这里ANTHROPIC_BASE_URL填 TaoToken 的 API 地址,API_TIMEOUT_MS设大一点,因为技能执行时可能涉及脚本运行和多次模型往返,超时太短会中途断掉。CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC设为 1 可以关掉一些非必要的遥测请求,让日志更干净。
另外还要处理首次登录引导。在~/.claude.json里加上:
{ "hasCompletedOnboarding": true }这样启动时不会卡在登录流程。配置完成后,在终端执行claude能正常进入对话,就说明后端通了。如果这一步报 401 或连接超时,先检查 Key 是否复制完整、API 地址有没有多带斜杠。
提示:TaoToken 的接入文档在 https://taotoken.net/doc ,里面有各语言 SDK 和常见报错说明,配置卡住时可以先翻这里。
3. SKILL.md 目录骨架与技能注册配置
Skills 的本质是一个文件夹,SKILL.md是必须的入口文件,其余目录都是可选的资源。一个标准的技能目录长这样:
my-skill/ ├── SKILL.md # 必须:元数据 + 执行说明 ├── scripts/ # 可选:可执行脚本 ├── references/ # 可选:参考文档 └── assets/ # 可选:模板与资源SKILL.md的结构分两部分:顶部的 YAML frontmatter 和下面的 Markdown 正文。frontmatter 负责技能发现与匹配,正文负责执行说明。骨架如下:
--- name: bill-analysis description: 读取账单截图,OCR 提取文字,清洗后导出报销用 CSV。当用户需要汇总账单、生成报销单时使用。 --- # 账单分析 ## 何时使用 当用户提供账单图片或文件夹路径,并要求汇总、报销、导出表格时使用本技能。 ## 执行步骤 1. 读取输入路径下的 png、jpg、pdf 文件 2. 调用 OCR 提取文字 3. 抽取商户名称、消费日期、金额、支付方式 4. 去重并导出 CSV,表头为:序号 | 商户名称 | 消费日期 | 金额(元) | 支付方式 | 备注 ## 注意事项 - 金额统一保留两位小数 - 日期格式统一为 YYYY-MM-DD - 无法识别的条目单独列出,不要丢弃name和description是 Agent 启动时唯一会读到的字段,所以 description 要写清楚“做什么”和“什么时候用”,这是命中率的关键。正文只在技能被激活后才加载,可以写得很细。
技能注册有两种方式。一种是放在 Claude Code 默认扫描的技能目录下,通常是~/.claude/skills/,每个技能一个子文件夹。另一种是在项目根目录建.claude/skills/,只对当前项目生效。我一般把通用技能放全局,项目专属的放项目里。
注册后可以用一个清单文件做索引,方便自己管理:
{ "skills": [ { "name": "bill-analysis", "path": "~/.claude/skills/bill-analysis", "enabled": true }, { "name": "commit-work", "path": "~/.claude/skills/commit-work", "enabled": true } ] }这个清单不是 Claude Code 强制要求的,但当你技能多了以后,用它来记录哪些启用、哪些停用,比翻目录快得多。
4. 验证请求:新增技能后 Agent 能否正确命中
写完技能不算完,得验证 Agent 真的会在合适的时候调用它。我新增一个“日志分析”技能来演示完整流程。
先创建目录和文件:
mkdir -p ~/.claude/skills/log-analysis然后写入SKILL.md:
--- name: log-analysis description: 分析应用日志文件,统计错误类型、出现频次和首次出现时间。当用户提供 .log 文件并要求排查错误、统计异常时使用。 --- # 日志分析 ## 何时使用 用户提供日志文件路径,要求统计错误、定位异常、分析频次时使用。 ## 执行步骤 1. 读取指定 .log 文件 2. 用正则匹配 ERROR、WARN、FATAL 级别行 3. 按错误信息聚合,统计出现次数 4. 记录每条错误的首次出现时间 5. 输出 Markdown 表格:错误信息 | 级别 | 次数 | 首次出现 ## 注意事项 - 大文件按行流式读取,避免一次性载入内存 - 时间戳格式不统一时先归一化保存后重启 Claude Code,让它重新扫描技能目录。然后发一条测试请求:
帮我分析 /tmp/app.log,统计里面的错误类型和出现次数如果命中成功,Agent 会先说明它要使用 log-analysis 技能,然后按步骤执行,最后输出一张错误统计表。如果它没有调用技能,而是自己临时写了一段分析逻辑,说明 description 没匹配上,需要调整措辞,把用户可能说的关键词(日志、错误、统计、排查)都覆盖进去。
再测一个反向用例,确认不会误触发:
帮我分析一下这段 Python 代码的性能这条请求里没有日志文件,也没有排查错误的需求,Agent 不应该调用 log-analysis。如果它调用了,说明 description 写得太宽泛,需要加上“当用户提供 .log 文件时”这类限定条件。
实测下来,命中率主要取决于 description 的精准度。我的经验是把“做什么”和“触发条件”分开写,触发条件里尽量包含用户的原话词汇。
5. 本篇常见错排查
技能不生效时,按下面几个方向逐个排查。
技能没被扫描到。检查目录层级是否正确。Claude Code 扫描的是~/.claude/skills/下的直接子目录,每个子目录里必须有SKILL.md。如果你把技能放在~/.claude/skills/foo/bar/SKILL.md,它可能扫不到。用ls ~/.claude/skills/*/SKILL.md确认每个技能入口都在。
frontmatter 格式错误。YAML 对缩进和冒号很敏感。name和description必须顶格,冒号后面要有空格。如果 description 里含冒号,要用引号包起来。可以用在线 YAML 校验工具过一遍,或者直接看 Claude Code 启动日志里有没有解析报错。
description 匹配不上。这是最常见的问题。Agent 只靠 name 和 description 做匹配,正文它看不到。所以 description 要写成“用户会怎么描述这个需求”的样子,而不是“这个技能技术上做了什么”。比如写“当用户需要汇总账单、生成报销单时使用”,比写“基于 OCR 的账单处理”命中率高得多。
技能之间互相抢。如果两个技能的 description 覆盖了相似场景,Agent 可能随机选一个。解决办法是在 description 里加排他条件,比如“仅当输入为图片时使用”“仅当涉及 Git 提交时使用”。
脚本执行失败。如果技能正文里调用了scripts/下的脚本,要确认脚本有执行权限,依赖也装好了。Skills 比 MCP 更依赖本地环境,脚本路径写相对路径时,基准目录是技能文件夹本身,不是项目根目录。
改了 SKILL.md 不生效。Claude Code 在启动时加载技能元数据,改完要重启。如果只想快速验证,可以退出当前会话重新进。
注意:排查时优先看 Claude Code 的启动输出,它会打印加载了哪些技能。如果某个技能没出现在列表里,问题一定在目录结构或 frontmatter,而不是 description。
6. 把技能组织成可检索的目录,才是长期解法
回到开头那个问题:能力堆叠后 Agent 变笨,根因是上下文没有分层。Skills 用SKILL.md做入口、用 frontmatter 做索引、用渐进式加载做按需读取,本质上是给 Agent 装了一份带目录的说明书。目录负责“找得到”,正文负责“做得好”,两者分开,上下文就不会膨胀。
如果你打算把这套东西用在长期编码或 Agent 工作流里,建议配合 Coding Plan 来管理调用额度,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。日常验证模型对技能的理解是否到位,可以直接在模型对话里试,地址是 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。需要新建或轮换 Key 时去 API Keys 页面: https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
我自己的习惯是每加一个技能,先写 description,再写正文,最后一定跑一遍正向和反向用例。description 改三遍以上是常事,但改完之后 Agent 的调用准确率会明显不一样。技能多了以后,维护那份清单文件比什么都重要,它就是你这份说明书的目录页。