文章目录
- 前言
- 一、第一个误区:SKILL.md不是一次性全塞进context的
- 二、那SKILL.md写一堆内容,token不就爆了吗
- 三、Claude凭什么靠description就决定加不加载
- 第一,要用第三人称、客观陈述的口吻写
- 第二,要把用户真实会说出口的触发短语列进去
- 第三,触发过度时要加负面条件
- 四、SKILL.md里引用的脚本和资源,是怎么进context的
- 五、面试怎么答SKILL.md的加载机制
- 第一步,先纠正"全量加载"这个前提(30秒)
- 第二步,讲清三级分别是什么、各自什么时候加载(1分钟)
- 第三步,讲description怎么决定触发(30秒)
- 第四步,讲资源是"读"不是"注入"(30秒)
- 写在最后
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/HHX_01
前言
上周有个学员去滴滴面试,回来跟我说:"老师,我凉了。"我说怎么了?他说前面聊得挺顺,自己写过一个Claude Code的Skill,吹得天花乱坠。面试官点点头,问了一个看起来特别基础的问题:“你这个Skill装上之后,SKILL.md是一次性全部读进context的吗?”
学员想都没想:“对啊,装上就加载进去了,Claude才知道这个Skill是干嘛的。”——各位,这就是典型的"我觉得我对了"。就像你追女神,人家回你个"嗯",你觉得你们有戏了。
面试官没接话,停顿了两秒,然后笑了一下,把笔放下:“那我问你——我装30个Skill,每个写两三千字,是不是开局还没说话,context就被塞满了?”
学员愣住了。他确实没想过这个问题。他下意识答:“那……那可能会占用挺多token的吧。”——这回答就像你女朋友问"你错哪了",你说"我哪儿都错了",看似诚恳,实则啥也没说。
面试官摇摇头,拿出手机翻到Anthropic官方文档,转过来给他看:“人家不是全量加载的,是progressive disclosure,渐进式披露。分三级,启动时只加载metadata,正文按需加载,资源文件让模型自己用工具去读。你连第一步都搞错了。”
学员后背一凉。他说那一刻他突然意识到,自己用了一个月的Skill,居然从来没搞懂它最核心的机制是什么。就像你用了一个月洗衣机,突然有人告诉你:“其实那个桶不用每次都装满水。”
面试官还没停,接着追了三连问。这三个问题下去,学员一个都没答利索。这场面试,在他走出会议室的时候,基本就凉了。他回来问我这几个问题到底怎么答。我说这正好是一条特别好的追问链——从"加载机制"一路问到"触发设计"再问到"资源读取",层层往下挖,挖的就是你到底有没有真正理解Skill这套东西是怎么跑起来的。今天我把这条链从头到尾拆一遍。
一、第一个误区:SKILL.md不是一次性全塞进context的
先把面试官那句话掰开。很多人对Skill的理解停留在"装上=加载进上下文",这是把Skill当成了一段固定的system prompt。如果真是这样,那面试官的反问就成立了:装30个Skill,每个两三千字,光这些文件就能把上下文窗口吃掉一大块,模型还没开始干活,token预算先没了一半。
Anthropic的设计显然不会这么蠢。它的核心机制叫Progressive Disclosure(渐进式披露),官方文档里把它列为Skill的第一条设计原则。一句话概括:按需加载,谁用到谁加载,没用到的内容根本不进上下文。
具体分成三级:
第一级 Metadata:YAML frontmatter(name + description),启动时永远加载,进上下文但极小
第二级 Instructions:SKILL.md正文,Claude判断该Skill与当前任务相关时才触发,触发了才进
第三级 Resources:references/、scripts/、assets/里的文件,Claude主动用工具去读时,读了才进
这张表是整篇文章的骨架。先记住一个判断:**任何时候,你的上下文里都不会同时塞着所有Skill的全部内容。**平时躺在上下文里的,只有每个Skill那几十个token的metadata。就像你去KTV,包间里不会同时放着所有歌的完整音频,只有歌单。你想唱《孤勇者》的时候,系统才给你放这首歌。
二、那SKILL.md写一堆内容,token不就爆了吗
这是面试官的第二问,也是最容易暴露理解深度的地方。答案是:不会爆,因为正文(第二级)平时根本不在上下文里。
我们顺着启动流程走一遍。当你在Claude Code里装了一堆Skill,启动的瞬间,进入系统提示的只有每个Skill的第一级metadata——也就是SKILL.md文件最上面那段YAML frontmatter,里面就两个核心字段:
---name:pdf-extractordescription:Extract tables and text from PDF files. Use when the user uploads a .pdf and asks to pull out tables,parse invoices,or convert PDF content to markdown.---这段东西有多大?官方给的量级是每个Skill大约100 token。你装30个,也就3000 token左右,对于动辄20万token的上下文窗口来说,几乎可以忽略。所以Anthropic反而鼓励你装很多个细分的Skill,而不是把功能全堆进一个臃肿的大Skill——因为多装几个的成本,仅仅是多几段metadata而已。就像你微信好友列表有5000人,但你的大脑不会同时想着5000个人的全部人生故事,你只会记得他们的备注名。
真正的大头——SKILL.md正文,停在硬盘上,没进上下文。只有当用户发来的请求命中了某个Skill的description,Claude判断"这个任务跟这个Skill相关",它才会去把那个SKILL.md的正文读进来。
所以这里有一个特别关键的认知:**metadata是常驻的、廉价的;正文是按需的、一次只进一两个的。**一次对话里,通常只有一到几个Skill的正文会被真正加载。哪怕你装了50个Skill,写得再长,只要这次任务只触发其中一个,进上下文的也就那一个的正文。
算笔账就更直观了。假设你装了50个Skill,每个SKILL.md正文都写满到5000词的上限。如果是"全量加载"那套理解,光这些文件就是几十万token,直接把上下文撑爆。但在渐进式披露下,常驻的只有50段metadata,大约5000 token;这次对话触发了2个Skill,再加进去两份正文,也就一万出头token。两种算法差出几十倍——差距全在"按需"这两个字上。这就是为什么面试官敢断定"你连第一步都搞错了":把机制搞反,token预算的量级估计能差一个数量级。
就像你去饭店吃饭,全量加载是"把所有菜都端到你面前",按需加载是"你点啥上啥"。你要是点了50道菜,那确实桌子放不下;但你只点了两道,老板非要摆50道,你是不是觉得老板有病?
这也顺带解释了官方为什么对两个地方有体积限制:
description限制在1024字符以内——因为它是metadata,常驻系统提示,每个字符都在持续占用窗口;
SKILL.md正文建议控制在5000词以内——因为它一旦触发就整个进上下文,太大照样拖慢推理、挤占预算。
换句话说,"token会不会爆"取决于你有没有踩中体积红线,而不取决于你装了多少个Skill。机制本身已经帮你把"装得多"这件事的成本压到了最低。就像你买房,物业费是按面积算的,不是按你买了多少套房算的。你买50套小户型,平时只住一套,物业费只交一套的钱。
三、Claude凭什么靠description就决定加不加载
到这里面试官的第三问就接上了:既然metadata里就name和description两个字段,Claude凭什么靠这么点信息,就能准确判断该不该加载正文?关键全在description怎么写。
Claude在每次收到用户请求时,会拿这次请求去和上下文里所有Skill的description做匹配——本质上是一次语义判断:"这个Skill描述的能力,跟用户现在想干的事,是不是同一件事?“description写得准,它就触发得准;description写得糊,它要么该触发不触发(undertriggering),要么瞎触发(overtriggering)。就像你相亲,介绍人跟你说"这人挺好的”,你去了发现对方是个道士——介绍人没骗你,但描述太模糊,匹配出了偏差。
官方给的description公式是:做什么 + 何时使用(触发条件)+ 关键能力。三个要素缺一不可,而新手最容易漏掉的是中间那个"何时使用"。对比一下就很清楚:
# 不好的写法 —— 太泛,Claude不知道什么时候该用description:Helps with documents.# 不好的写法 —— 只说了做什么,没说何时用description:Creates sophisticated multi-page documentation systems.# 好的写法 —— 做什么 + 何时使用 + 具体触发短语description:Analyzes Figma design files and generates developer handoff docs. Use when the user uploads a .fig file or asks for "design specs","component documentation",or "design-to-code handoff".这里有三个很多人不知道的细节:
第一,要用第三人称、客观陈述的口吻写
description是写给Claude看的"这个Skill是什么、什么时候用它",不是写给用户的广告语,也不是第一人称的自我介绍。“Use when the user asks to…“这种句式就是标准写法——它在帮Claude建立"用户说了X,我就该调用这个Skill"的映射。就像你给室友留便条,写"当你看到冰箱空了,就去买菜”,而不是"我看到冰箱空了,我去买菜”——后者是日记,前者才是指令。
第二,要把用户真实会说出口的触发短语列进去
不要写"处理设计文件",要写用户实际会说的话:“设计规格”“组件文档”“设计转代码”。Claude匹配的是语义,但你给的短语越贴近真实表达,命中率越高。这也是为什么官方建议description尽量用英文——Claude对英文触发短语的匹配更稳定,中文有时会有识别偏差。就像你教老外说中文,你说"我想吃饭"他能懂,你说"俺寻思整点吃的",他就懵了。
第三,触发过度时要加负面条件
如果你的Skill老是在不相关的场景被误触发,可以在description里直接写明边界,比如"仅用于在线支付工作流,不适用于一般金融查询",或者"不适用于简单的数据探索(请改用data-viz Skill)“。把"不该触发的场景"也告诉Claude,它的判断就会收敛。就像你告诉导航"我要去机场,但别走高速”,导航就知道该怎么绕了。
调试description还有个很实用的技巧,官方文档里也提到了:**直接问Claude"你什么时候会用这个Skill?"**它会把它理解的description复述给你听。如果它复述出来的触发场景跟你预期的不一样,那就说明description没写到位,照着它的反馈改就行。就像你让朋友复述你的意思,他说出来的跟你想的差十万八千里,那肯定是你的表达有问题。
四、SKILL.md里引用的脚本和资源,是怎么进context的
这是最后一问,也是把"渐进式披露"理解透了才答得上来的一问。很多人会想当然地以为:既然SKILL.md触发后会被加载,那它references/、scripts/目录里的文件,是不是也跟着一起被加载进来了?
**不是。第三级资源的加载方式,和前两级有本质区别——它不是被"注入"的,而是被Claude主动"读取"**的。
这是什么意思?SKILL.md正文被加载进上下文后,Claude看到的只是文字。如果正文里写了一句"在编写查询前,请查阅references/api-patterns.md,其中包含速率限制和分页模式",那么Claude此刻并没有把那个文件读进来——它只是知道"有这么个文件、在那个路径、讲的是这些内容"。只有当任务真的推进到需要那份文档时,Claude才会调用工具(在Claude Code里就是Read或Bash),把那个文件的内容读进上下文。读进来的也只是它当下需要的那一个文件,而不是整个目录。就像你去图书馆,管理员给你一张书单,书单在桌上,书在书架上。你需要哪本,自己去拿,而不是管理员把整层楼的书都搬到你的桌上。
这个差别在工程上极其重要,它带来两个直接的好处:
**第一,资源文件的体积几乎没有上限。**因为它们不常驻、不自动加载,你可以在references/里放很长很详细的API文档、几百行的示例、大段的错误码表。它们躺在那里不占任何上下文,只在被点名读取的那一刻才花token。这正是官方反复强调的那条最佳实践——**SKILL.md正文只放核心指令,详细内容全部下沉到references/,正文里用链接引用。**就像你写论文,正文只写结论,参考文献里塞满各种资料,评委不会要求你把参考文献全背下来。
**第二,scripts/里的脚本是被"执行"的,不是被"理解"的。**这是Skill设计里一个很精妙的点:对于确定性的逻辑(比如数据校验、格式转换),与其用自然语言在SKILL.md里描述一堆规则让模型去理解和执行——语言解释是不确定的——不如直接写成一个脚本,让Claude用工具去运行它。官方原话是"代码是确定性的,语言解释不是"。所以你会看到很多成熟的Skill,SKILL.md里只写一句"运行python scripts/validate.py --input {文件名}来校验数据",真正的校验逻辑全在那个脚本里。Claude读到这句,就去执行脚本,拿回结果,而不需要把脚本的几百行代码读进上下文逐行理解。就像你让助理去办事,你说"把这份文件复印一份",助理自己去操作复印机;你不会跟助理描述复印机的每一个齿轮怎么转。
把这一层想明白,你就理解了Skill的完整图景:**metadata负责"让Claude知道有这个能力",正文负责"告诉Claude怎么用这个能力",资源和脚本负责"在需要时提供确定性的细节和执行力"。**三级各司其职,每一级只在恰当的时机花恰当的token。这就是渐进式披露的全部精髓。就像一家餐厅:前台负责接待(metadata),厨师负责做菜(正文),仓库负责提供食材(资源)。前台不会把仓库所有食材都搬到厨房,厨师也不会把仓库钥匙挂在脖子上——各干各的,按需调用。
五、面试怎么答SKILL.md的加载机制
如果面试官问到这条链,我建议你按下面这个节奏答,层层递进,把四个点都覆盖到:
第一步,先纠正"全量加载"这个前提(30秒)
开口就说:"SKILL.md不是一次性全部读进context的,Anthropic用的是Progressive Disclosure,渐进式披露,分三级按需加载。"一句话就把基本盘立住了,面试官会知道你懂机制而不是背概念。就像你打架,第一拳就要把对方打懵,后面才好发挥。
第二步,讲清三级分别是什么、各自什么时候加载(1分钟)
Metadata(name+description)启动时常驻、每个约100 token;正文在Skill被判断相关时才加载、建议5000词以内;资源文件由Claude主动用工具读取。顺手抛出结论:“所以装很多Skill也不会爆token,常驻的只有那点metadata。”
第三步,讲description怎么决定触发(30秒)
公式是"做什么 + 何时使用 + 触发短语",第三人称写,列用户真实会说的话,触发过度就加负面条件。能补一句"可以直接问Claude什么时候会用这个Skill来调试",是加分项。就像你考试,答完标准答案再补一句"我还实测过",老师立马觉得你是个实干派。
第四步,讲资源是"读"不是"注入"(30秒)
强调资源文件和脚本是Claude主动调用工具读取/执行的,所以体积没上限,确定性逻辑应该写成脚本而不是写进正文。这一步答出来,面试官基本就确认你是真做过了。就像你去面试厨师,你说"我不仅会炒菜,还知道冰箱里的食材是怎么拿出来的"——这就不只是会做菜了,你是懂厨房管理的。
写在最后
回头看滴滴那位面试官的追问链,它其实没有一个问题是刁难——从"是不是全量加载"到"token会不会爆",到"description怎么触发",再到"资源怎么读取",每一问都是上一问的自然延伸。你只要真正写过一个Skill、被它的触发机制坑过几次,这四个问题是连在一起的、是一口气能答完的。答不上来,恰恰说明只是把SKILL.md当成了一个"写指令的文件",没去想它背后那套加载逻辑。就像你开车,你会踩油门,但你不一定会换轮胎;真正懂车的人,两者都会。
背答案的人和真正做过的人,说话方式完全不一样。前者说"SKILL.md会按需加载,用了progressive disclosure",后者会说"我装了二十多个Skill实测过,常驻上下文的只有每个约100 token的metadata,正文一次对话通常只触发一两个;有一次我的description写得太泛,Claude在不相关的请求里反复误触发,我加了一句负面条件、把触发短语换成用户真实说法之后才收敛"。
面试官三句话就能听出来你是哪种人。就像你相亲,一个人说"我挺会照顾人的",另一个人说"我上周刚给发烧的女朋友熬了三天粥,还学会了怎么挑梨"——你觉得哪个更可信?
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/HHX_01