[控场AI]
· 9 分钟阅读· 4,675 字

Claude Code技能描述预算实测:规则与现实的三大偏差

Claude Code技能描述预算实测:规则与现实的三大偏差

实测发现 Claude Code 技能清单预算按字符计、全角字符双倍计,规则与文档推导严重不符。

一位开发者用 Claude Code 2.1.296 实测了技能清单预算机制,推翻了团队沿用的仓库规则。实验通过 `claude -p` 单轮运行并读取 transcript 的 `skill_listing` 附件直接计数,发现在三个维度上出错:预算应按 30,000 字符而非 10,000 计算、1,536 上限同时覆盖 `description` 和 `when_to_use`、溢出后技能名称保留而非彻底失效。更具决定性的是日文描述被按双倍字符计数,同等预算下可容纳技能数只有英文的一半;而单条 1,536 的上限却按单字符计。真实清单含插件与自带技能共 64 条、已占约 94% 预算,项目测试只覆盖其中 9 条,`/skill-doctor` 的 token 估算也低估日文成本约 2.5 倍。

每个回合,Claude Code 都会把一份技能名称与描述清单交给模型,模型据此判断何时自行调用某个技能。这份清单是有预算上限的,一旦溢出,部分技能描述就会被丢弃。一位开发者在自己的仓库里为此写了一条提交规则和一个强制检查,两者都基于官方文档,却从未做过实测。本周他们用 Claude Code 2.1.296 真正测了一次,结果发现规则在三个维度上同时出错:计量单位错了、覆盖范围错了、对照数字也错了。

据该开发者在 DEV Community 上分享的实测记录,他们团队用 Claude Code 2.1.296(模型 claude-opus-5-5,100 万 token 窗口)搭建了极简测试目录,只保留 .claude/skills/,通过 claude -p 单轮运行并读取 transcript 中的 skill_listing 附件来计数。这一实验设计绕开了此前"相信汇总报表"的做法,直接对数出模型实际收到的清单。

三个偏差:单位、范围与阈值

第一处偏差是单位。文档说预算按模型上下文窗口的 1% 缩放,但这个 1% 从未被换算成字符;上下文窗口以 token 计,而清单预算以字符计。该团队直接把 100 万 token 的 1% 写成 10,000 字符,埋下了错误。

第二处偏差是范围。文档中 1,536 的上限同时适用于 description 和 when_to_use 两个字段,测试却只读取 description。目前没有技能使用 when_to_use,所以暂时一致,但任何新增该字段的技能都会绕过检查。

第三处偏差是后果描述。团队规则写的是"描述被丢弃的技能将不再触发",而文档的措辞是名称保留、技能仍可被调用,只是模型"不太可能"主动选择它。规则把影响写得比文档更严重。

配图:实验输出显示日文技能集按 87,238 字符对 30,000 预算计数,最终仅发送 40 条中的 11 条描述

什么是技能清单预算(skill_listing budget)

Claude Code 中的“技能”(skill)是一份声明式的 Markdown 文件,放在 .claude/skills/ 或由插件、账户级配置提供。每个回合开始前,Claude Code 不会把技能全文交给模型,而只发送一份清单:技能名称加一段简短描述,让模型据此判断是否需要主动加载某个技能。

这份清单本身也占用上下文窗口,因此设有一个上限,超过后部分技能的描述会被裁掉,只保留名称。理解这一点的关键在于:清单预算并不等于整个上下文窗口,而是其中一个很小的子预算;同时它按字符计而非按 token 计,与模型的 token 计量体系是两套账。

日文描述:被翻倍计数的隐藏成本

该团队的技能描述用日文撰写,这一点比预想的更具决定性。

实验对比了两个各含 40 个技能的目录,每个描述恰好 1,000 字符,一组英文、一组日文。调试日志显示,英文组被计为 47,238 字符,日文组被计为 87,238 字符,正好多出 40,000,即每条 1,000 字符的日文描述多算 1,000。也就是说,Claude Code 把每个日文字符当作两个来计算。

释放出的清单印证了这一点:英文组发送了 40 条中的 22 条描述,共 29,204 字符;日文组只发送了 11 条,共 18,182 字符,若按双倍计数则相当于 29,182,刚好卡在预算之下。同样的预算,日文描述能容纳的技能数量只有英文的一半。

你可能没注意到,单条描述的上限却按另一套规则计数。实验给一个技能设置 1,997 字符的日文描述,模型收到的是前 1,535 字符加省略号,共 1,536 字符。这说明 1,536 的上限按单字符计数,而总预算按双字符计数。

全角与半角字符的编码差异

在 Unicode 中,英文字母、数字和常见标点属于半角(halfwidth)字符,而日文假名、汉字,以及中文、韩文文字都属于全角(fullwidth)字符。它们在视觉宽度上通常相当于两个半角字符,在 UTF-8 编码下也往往占用 3 个字节而非 1 个字节。

这就是双倍计数出现的土壤:如果 Claude Code 内部用类似 East Asian Width 的属性来估算“显示宽度”,那么一个日文字符会被折算成两个单位。需要强调的是,这与真正的分词器行为并不一致——现代 BPE 分词器对日文字符的 token 化效率因模型而异,通常远高于“一个字符等于两个 token”的粗糙换算,这也解释了为什么 /skill-doctor 的估算和实测 token 数会对不上。

清单实际长什么样:94% 已满

测试只统计了项目内技能,但真实清单里还包含插件、账户级技能和 Claude Code 自带的技能。

在 2026-10-12 的主会话中(Claude Code 2.1.286,Opus 5.5,100 万窗口),首个 skill_listing 附件包含 64 个条目、26,791 字符,且每条描述都还在。若按实验中全角字符双倍计数,这相当于 30,000 预算中的 28,119,占 94%。

团队自己的 9 个技能只占其中最小部分:2,484 字符,双倍计数 3,702。以 anthropic-skills: 为前缀的 13 个条目占 9,502 字符;Claude Code 及账户自带的 18 个占 8,094;一个记忆插件的 21 个技能占 6,343。按实验计数规则,清单只剩约 1,881 单位、约 940 个日文字符的余量,而团队测试当时还允许再添加 7,696 字符。测试并没有算错自己的 9 个技能,它只是在测量一份已被他人技能填满大半的预算中的一小块。

插件技能与账户级技能从何而来

除了仓库里手写的 .claude/skills/,Claude Code 的清单还会纳入三类外部来源:以 anthropic-skills: 为前缀的官方技能、账户级别配置的技能,以及通过插件(plugin)安装的技能。这些技能不在你的仓库里,也不会随项目提交,但同样参与清单预算竞争。

这意味着项目内的检查脚本天然存在盲区:它只能看到自己仓库中的技能,无法感知平台上其他来源已经吃掉了多少预算。要审计真实占用,只能从会话本身的 transcript 中读取 Claude Code 实际发送的 skill_listing 附件,因为那才是模型真正看到的那份清单。

五周的 /skill-doctor 报告揭示了什么

自 2026-09-09 起,团队每周运行一次 /skill-doctor 并把结果追加到 state/skill-doctor-reports.jsonl。五份报告(2026-09-09、09-21、09-30、10-05、10-12)显示,清单总计从 3,060 token 增长到 3,270 token,记忆插件从 1,780 增至 2,230。调用次数也随工作变化:处理回复的技能从 16 次增至 54 次,每周技能从 1 次增至 30 次。

但报告中的 context 列并不可靠。团队发现,对于 10-12 的九个项目条目,该数字与条目的字符数除以 3 的结果相差不超过 6 token。一个 612 字符的英文描述被标为 210 token,一个 94% 为日文的 162 字符描述被标为 50 token——真正的分词器不会把两者等同对待。

配图:实验输出显示无项目技能时首请求为 19,182 token,8 条日文描述增加 1,508 token,同长度英文仅增加 567 token

日文描述的真实 token 成本

为获得真实数字,团队把 8 个已提交的日文描述复制到实验目录,对比空目录的首请求输入 token。每组配置运行两次,重复结果相差不超过 1 token。

日文描述增加 1,508 token,英文对照组增加 567 token,而 /skill-doctor 对这 8 行的估算是 610——正好接近英文对照组,对真实成本的低估约为 2.5 倍。在溢出场景下同样如此:日文清单携带 11 条描述增加 10,515 token,英文清单携带 22 条描述增加 6,921 token,即描述条数减半却多耗 52% 的 token。

Claude Code 的双倍计数在这里反而更接近现实:按比例推算,30,000 单位的日文清单约合 15,000 字符、约 12,000 token,同预算的英文约 9,000 token,两种语言的预算 token 成本处于同一量级。真正漏算的是团队自己的测试。

为什么“字符数除以 3”的 token 估算会失真

不少工具用“英文字符数 ÷ 3 ≈ token 数”这一经验公式做快速估算,对英文文本大致可用,但一旦混入日文、中文或韩文就会显著低估。原因是分词器对 CJK 文本的切分粒度更细,一个汉字常被拆成一到多个 token,且不同模型的分词表差异较大。

更可靠的做法是直接测量:把待测描述加入 claude -p 的单轮请求,对比空目录与含描述目录的首请求输入 token 差值,并重复运行以确认稳定。本文团队正是用这种方式得到日文 1,508 token、英文 567 token 的真实数字,与工具估算的 610 相差约 2.5 倍。

测试的三处失效

该检查能捕获空描述、过短描述和超过 1,536 字符的描述,这部分与 Claude Code 的行为一致。但总数统计不准:日文字符只算一次,导致已提交的 1,692 字符实际相当于 2,894;它只覆盖清单 64 个条目中的 9 个,其余 55 个位于仓库外的插件和 Claude Code 自身;它对照的是 10,000,而真实预算是 30,000。一个只用了四分之一额度就通过的测试,对一份已满 94% 的清单无话可说。

真正能看到真实清单的是会话本身。transcript 记录了 Claude Code 发送的 skill_listing 附件,数一数其中缺少描述的条目就能直接发现溢出,调试日志也会在发生时发出警告。团队尚未修改测试,但他们已经知道该盯住哪个数字——而这个数字并不存放在仓库里。

对写非英文描述的开发者的启示

这项实测的核心价值在于提醒:围绕 token 预算的规则不能从文档中的百分比直接推导为字符数。如果你的技能描述使用日文、中文或韩文,或以全角字符为主,你实际可用的清单容量可能只有英文用户的一半。团队呼吁其他开发者在自己的机器上验证:最近一次 transcript 中的 skill_listing 有多少条目、多少条目丢失了描述、以及 Claude Code 是否同样将全角字符按双倍计数。这些数据将帮助判断双倍计数是普遍机制还是特定版本的行为。

#Claude Code#技能描述预算#skill_listing#token预算#日文字符计数#skill-doctor#上下文窗口
分享:

相关推荐