1. 面试官追问的“还有呢”,到底在问什么
“如何设计 Skill 来降低 Token 消耗?”——如果你只答“渐进式加载”,面试官大概率会继续追问。不是这个答案错了,而是它太顶层了。渐进式加载回答的是“什么时候加载”,但面试官想听的是“加载什么、加载多少、怎么组织”。
我复盘过这个场景:一个 Skill 被触发时,真正进入上下文的东西分三层。第一层是元数据,也就是 name 和 description,这部分常驻上下文,每次对话都在消耗 Token;第二层是 SKILL.md 正文,Skill 被触发时才加载;第三层是捆绑资源,比如 references 目录下的参考文件、scripts 目录下的脚本,只有被显式读取时才进入上下文。
很多人只记住了“按需加载”这四个字,却没意识到:description 是永远在付费的,正文是触发时一次性付费的,资源文件是用到才付费的。三层结构搞清楚了,你才知道该在哪一层做减法。这篇就围绕 SKILL.md 的元数据配置和 Description 精简写法,给出一套可以直接复制的骨架,顺带把渐进式加载的验证动作和 Token 对比记录方式讲清楚。适合正在做 AI 工具接入、需要统一管理 Key/API 通道的开发者,也适合准备面试时想把答案从“一个点”扩展成“一套体系”的人。
2. 前置:统一 Key/API 通道与 Skill 配置的关系
在讲 SKILL.md 骨架之前,先说清楚一个前置条件。Skill 本身不负责模型调用,它是一份给模型看的“操作说明书”。真正发起请求、消耗 Token 的是背后的 API 通道。如果你在本地同时接了好几个模型供应商,每个 Skill 里都硬编码不同的 base_url 和 key,那 Token 统计和成本核算会非常混乱。
我自己的做法是:所有 Skill 统一走一个 API 通道,base_url 指向https://taotoken.net/api,key 在控制台统一生成和管理。这样 Skill 里不需要关心“这次调用走哪个供应商”,只需要关心“这次任务需要加载哪些内容”。Token 消耗的对比记录也能在一个地方看,不用来回切换后台。
具体操作上,你可以在 TaoToken 控制台创建一个 API Key,然后在环境变量里配置:
export TAOTOKEN_API_KEY="sk-你的key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"Skill 的 SKILL.md 里不写 key,只写“调用模型时使用环境变量中的 TAOTOKEN_API_KEY”。这样做的另一个好处是:当你需要对比不同 Skill 设计的 Token 消耗时,模型和通道是同一个变量,差异只来自 Skill 本身的结构。
如果你还没有 Key,可以先到控制台生成一个,再回来跟着下面的骨架配置。模型对话入口可以用来快速验证通道是否通,API Keys 页面用来管理 key 的权限和额度。
3. 可复制的 SKILL.md 骨架与 Description 精简写法
3.1 SKILL.md 的目录结构
一个 Token 友好的 Skill,目录结构应该是这样的:
my-skill/ ├── SKILL.md ├── references/ │ ├── aws.md │ ├── gcp.md │ └── azure.md └── scripts/ └── format_output.pySKILL.md 只放核心指令和“什么时候读哪个文件”的判断逻辑。references 放按场景拆分的参考文档。scripts 放确定性操作的脚本。这样正文不会臃肿,资源文件也不会自动进上下文。
3.2 SKILL.md 正文骨架
下面是一个可以直接复制的骨架,控制在 500 行以内,重点在“判断逻辑”而不是“内容堆砌”:
--- name: cloud-deploy-helper description: 当用户需要部署到云平台时使用。根据用户指定的平台读取对应参考文件,执行部署脚本。 --- # Cloud Deploy Helper ## 触发条件 当用户提到“部署到 AWS/GCP/Azure”或“云平台部署”时触发。 ## 执行流程 1. 确认用户指定的云平台。 2. 根据平台读取对应参考文件: - AWS: 读取 references/aws.md - GCP: 读取 references/gcp.md - Azure: 读取 references/azure.md 3. 如果需要格式化输出,执行 scripts/format_output.py。 4. 不要一次性读取所有参考文件,只读用户指定的那一个。 ## 注意事项 - 参考文件按需读取,不要预加载。 - 脚本直接执行,不要把脚本内容读进上下文。这个骨架的关键点:正文里没有 AWS/GCP/Azure 的具体部署步骤,那些都在 references 里。正文只告诉模型“什么时候读哪个文件”。这样 Skill 被触发时,进入上下文的只有这份正文,大概几十行,而不是三个平台的完整文档。
3.3 Description 精简写法
Description 是常驻上下文的,所以它必须精简。写法上只回答两个问题:什么时候触发、做什么。不要写实现细节,不要写工作流程,不要写举例超过三个。
反面写法:
description: 这个 Skill 用于帮助用户部署到云平台。首先需要确认用户使用的是 AWS、GCP 还是 Azure,然后根据平台读取对应的参考文件,参考文件里包含了详细的部署步骤,包括创建实例、配置网络、设置安全组、安装依赖、启动服务等。如果用户没有指定平台,需要询问用户。部署完成后还需要验证服务是否正常运行。正面写法:
description: 当用户需要部署到云平台时使用。根据用户指定的平台读取对应参考文件并执行部署。正面写法只有一句话,但触发场景和功能都说清楚了。反面写法把整个工作流程都塞进去了,每次对话都在为这些用不上的信息付费。你可以这样操作:写完 description 后,问自己“这句话在 Skill 没被触发时有用吗?”如果没用,就删掉。
3.4 用脚本替代大段说明文字
对于格式转换、文件处理这类确定性操作,直接提供脚本比写长篇指令省 Token。比如你需要把输出格式化成 JSON,不要在 SKILL.md 里写“首先读取文件,然后按行分割,再提取字段……”,而是写“执行 scripts/format_output.py”。脚本内容不会进入上下文,只有“执行这个脚本”这一句话会。
# scripts/format_output.py import json import sys def format_output(data): return json.dumps(data, ensure_ascii=False, indent=2) if __name__ == "__main__": input_data = json.loads(sys.stdin.read()) print(format_output(input_data))SKILL.md 里只需要一行:“格式化输出时执行python scripts/format_output.py。”
4. 验证请求与 Token 对比记录方式
4.1 验证渐进式加载是否生效
配置完成后,你需要验证三件事:元数据是否常驻、正文是否只在触发时加载、资源文件是否只在读取时进入上下文。
验证动作一:不触发 Skill,发一条普通消息,观察 Token 消耗。这时候只有 description 在上下文里,消耗应该很低。
验证动作二:触发 Skill,但不指定平台,观察 Token 消耗。这时候正文进入上下文,但 references 不应该被读取。
验证动作三:触发 Skill 并指定平台,观察 Token 消耗。这时候正文加对应平台的参考文件进入上下文,其他平台的参考文件不应该被读取。
你可以用同一个问题分别测试“精简 description”和“臃肿 description”的 Skill,记录每次请求的 prompt_tokens。实测下来,臃肿 description 每次对话多消耗的 Token 可能不多,但高频触发时累积起来差距很明显。
4.2 Token 对比记录表
建议用一个简单的表格记录对比数据:
| 场景 | description 长度 | 正文行数 | 是否读取 references | prompt_tokens |
|---|---|---|---|---|
| 未触发 | 1 句 | 0 | 否 | 记录值 |
| 触发未指定平台 | 1 句 | 约 30 行 | 否 | 记录值 |
| 触发指定 AWS | 1 句 | 约 30 行 | 仅 aws.md | 记录值 |
| 触发指定 GCP | 1 句 | 约 30 行 | 仅 gcp.md | 记录值 |
记录方式:在 API 返回的 usage 字段里取 prompt_tokens,每次请求后记下来。对比“精简 description”和“臃肿 description”两组数据,你就能看到差异。如果走统一通道,可以在控制台或日志里集中查看,不用每个供应商单独统计。
4.3 用模型对话快速验证
如果你只是想快速验证 Skill 的触发逻辑和 Token 消耗,可以用模型对话入口发几条测试消息。比如先发“你好”看未触发时的消耗,再发“帮我部署到 AWS”看触发后的消耗。这样不用写完整代码就能拿到对比数据。
5. 本篇常见错排查
5.1 Description 写成了 README
这是最常见的错误。description 里塞了工作流程、实现细节、多个举例,导致每次对话都在为这些信息付费。排查方法:把 description 单独拿出来,数一下字数。如果超过 100 词,大概率有冗余。精简到“什么时候触发 + 做什么”两句话即可。
5.2 SKILL.md 正文超过 500 行
正文超过 500 行时,触发一次就加载一次,Token 成本很高。排查方法:打开 SKILL.md,看有多少内容是“只在特定场景下才需要”的。把这些内容拆到 references 里,正文只保留判断逻辑。比如三个平台的部署步骤,不应该都写在正文里。
5.3 references 文件被一次性全部读取
即使拆了 references,如果 SKILL.md 里写“读取 references 目录下的所有文件”,那还是全部加载。排查方法:检查正文里的读取指令,确保是“根据用户指定的平台读取对应文件”,而不是“读取所有参考文件”。验证时观察 Token 消耗,如果指定 AWS 和指定 GCP 的消耗差不多,说明可能都读了。
5.4 脚本内容被读进上下文
有些人把脚本内容直接贴在 SKILL.md 里,然后说“执行这段代码”。这样脚本内容就进了上下文,失去了用脚本省 Token 的意义。排查方法:确认 SKILL.md 里只有“执行 scripts/xxx.py”这样的指令,没有脚本的具体代码。
5.5 元数据和正文混在一起
name 和 description 是元数据,常驻上下文;正文是触发时才加载。如果把它们混在一起写,可能导致元数据部分变得臃肿。排查方法:确认 SKILL.md 的 frontmatter 里只有 name 和 description,其他内容都在正文里。
5.6 统一通道配置错误导致 Token 统计混乱
如果 Skill 里硬编码了不同的 base_url,Token 消耗会分散在多个后台,难以对比。排查方法:确认所有 Skill 都走同一个 API 通道,base_url 统一指向https://taotoken.net/api。这样 Token 对比记录才能在一个地方完成。如果接入时遇到报错,可以先查接入文档,再检查 key 和 base_url 是否匹配。
6. 把 Skill 设计当成一套分层体系
回到面试那个问题:“如何设计 Skill 来降低 Token 消耗?”现在你可以这样回答:不是只有一个渐进式加载,而是一套分层设计。元数据层用精简的 description 控制常驻成本;正文层控制在 500 行以内,只放判断逻辑;资源层按场景拆分 references,用到才读;确定性操作下沉到 scripts,不占上下文。四层各司其职,Token 消耗自然可控。
如果你正在做 AI 工具接入,建议先把统一 Key/API 通道配好,再按上面的骨架写一个 Skill,用模型对话发几条测试消息,记录 prompt_tokens 对比。跑通之后,再把这个骨架复制到其他 Skill 上。长期做编码或 Agent 的话,可以考虑 Coding Plan,把多个 Skill 的调用统一管理起来,Token 消耗和成本核算会更清晰。