
本文摘要Skill 扩到三十个后响应变慢、单次可改文件变少上下文预算被挤占。用可复算的成本台账脚本拆出每个 skill 的 token 占用与代码余量。一、问题与结论同一个仓库里.agents/skills从个位数扩到 30 个后仍是那条任务给 X 模块补一个错误分支测试单次会话能改动的文件数下降响应里出现与任务无关的 skill 引用。这类体感同时混着对话历史累积、模型波动、skill 注入三种来源不能直接归因。慢是真实成本但它由两笔可算的账决定skill 文件的静态 token 占用以及 harness 在启动或命中时的注入开销。不给“多少个 skill 合适”的阈值——阈值随 skill 厚度与注入方式变化跨项目不通用给的是一张能在你仓库里复算的成本表和一套控制变量的测量流程。先锁三件事claude --version或codex --version记下版本号git rev-parse --short HEAD锁定仓库状态find .agents/skills -maxdepth 1 -type d | wc -l记下 skill 目录数。版本变化会改写 skill 的发现路径、frontmatter 解析与描述注入方式跨版本读数不能混用。二、排查与选择依据先定测量设计再跑数字。自变量只留 skill 数量固定模型、同一份业务任务、同一份仓库状态每档强制新会话按 3 → 10 → 20 → 30 加载各跑三次取中位数续会话单独开一组对照不与新会话混算。三类读数各有取法token 消耗用 SDK 的 token 计数接口或当前版本提供的上下文用量查看命令命令名随版本变化先查帮助启动耗时用time包住会话启动噪音大只作量级参考任务产出用git diff --numstat它是“变笨”最直观的后果指标。归因要做对。skill、instincts、memory 是三本账ECC 的组成即 skills, instincts, memory, securitymemory 常驻内容的占用不要记到 skill 头上。脚本给出的静态估算 token 与实测 prompt token 的差值才是 harness 的注入/检索开销。若要对比“显式点名 skill”与“默认全量可见”自测口径为每 10 个任务统计失败测试数与 review 缺陷数缺陷分“约束过窄漏改分支”与“无关引用、越界改动”两类随上下文增长的趋势另行记录。以上均为待测项不给预设结论。替代方案与取舍做法选择条件代价不该用的边界拆瘦 skill 外置文档描述常驻注入、命中率低每次命中多一轮读取总量已很小或 harness 本就按需检索合并同类 skill同域 skill 多如十余个迁移脚本单个 skill 变厚检索粒度变粗各 skill 维护人与更新节奏不同保留插件/常驻注入规范必须每次在场安全、合规固定成本随总量线性涨skill 体积超过预算十分之一移入 memory/instincts长期不变的规范类指令不参与按任务检索易被忽略需按任务触发的步骤型指令不该用拆分方案的情况成本表显示留给代码的余量充足、skill 总量本身很小或大部分内容是强约束规范——拆分只增加维护面。三、关键原理注入时机决定成本曲线。若当前版本把 skill 描述在会话开始就塞进 prompt成本随 skill 总量线性增长每轮都在若按需检索成本落在命中时刻。先确认是哪一种再决定测什么。估算偏差。chars/4粗估在中文与代码片段上偏差可达两位数百分比。估算只做排序与量级对外报数必须用 tokenizer 结果并注明计数方式。预算账的两面。prompt token 占用上升留给代码与工具输出的余量下降单会话可处理的文件数随之下降常驻的 skill 描述还会诱导模型引用无关内容。慢与笨是同一笔预算账的两面。两个常见的测量翻车点一是把估算 token 当实测 token 写进结论方向对但数字错读者按数字取舍就会翻车二是新会话与续会话混测prompt token 增量里混着历史消息累积甚至因续会话不重复注入而得出“skill 不花钱”的反向结论。四、可运行示例环境Python 3.9在仓库根目录执行skill 目录为.agents/skills候选还包括~/.claude/skills。输入上下文预算 token 数默认120000。操作步骤保存脚本为skill_cost_ledger.py执行python3 skill_cost_ledger.py 120000。#!/usr/bin/env python3# skill_cost_ledger.py# 用法: python3 skill_cost_ledger.py [上下文预算token数]importsysfrompathlibimportPath CANDIDATES[Path(.agents/skills),Path(.agents),Path.home()/.claude/skills]TEXT_EXT{.md,.txt,.yaml,.yml,.json,.py,.sh}deffind_root():forpinCANDIDATES:ifp.is_dir()andany(p.rglob(*)):returnp sys.exit(f未找到 skill 目录候选:{[str(c)forcinCANDIDATES]})defestimate_tokens(text:str)-int:# 粗估非中文约 4 字符/token中文约 1.5 字符/tokencjksum(1forchintextif\u4e00ch\u9fff)otherlen(text)-cjkreturnint(other/4cjk/1.5)defmain():budgetint(sys.argv[1])iflen(sys.argv)1else120_000rootfind_root()rows[]groups{}forfinsorted(root.rglob(*)):iff.is_file()andf.suffixinTEXT_EXT:keyf.parent.relative_to(root).parts[0]iff.parent!rootelsef.name groups.setdefault(key,[]).append(f)forname,filesingroups.items():text\n.join(f.read_text(errorsignore)forfinfiles)rows.append((name,len(files),len(text.splitlines()),estimate_tokens(text)))totalsum(r[3]forrinrows)print(f{skill:28}{文件:4}{行:7}{est_tokens:12}{预算占比:10})forname,nf,nl,tkinsorted(rows,keylambdar:-r[3]):print(f{name:28}{nf:4}{nl:7}{tk:12}{tk/budget*100:9.1f}%)print(f\nskill 合计 est_tokens :{total}({total/budget*100:.1f}%))print(f预算{budget}留给代码/对话的余量:{budget-total})if__name____main__:main()预期输出格式示意未验证skill 文件 行 est_tokens 预算占比 api-error-handling 1 212 1180 1.0% db-migration-guide 2 405 2260 1.9% skill 合计 est_tokens : 31240 (26.0%) 预算 120000留给代码/对话的余量: 88760实际输出以你本机跑出的表为准。验证方法把est_tokens合计与上下文用量查看命令给出的 prompt token 对账差值即注入开销任务产出用git diff --numstat复核。常见失败脚本退出并打印未找到 skill 目录。原因是 skill 放在.claude/skills不在CANDIDATES里把Path(.claude/skills)追加进CANDIDATES即可。五、验证结果与边界已验证的只有结构性事实skill 是文件级内容mattpocock/skills说明其以.agents目录下的文件形态存在体积可直接度量开销来源不止 skillECC 把 skills、instincts、memory、security 并列在同一套体系里必须分开记账同一份 skill 在 Claude Code 与 Codex 上的发现路径与注入时机不同数字不可横向复述。所有 token 数、耗时、缺陷率均为未验证项需按第四节流程在本地取值。适用边界命中率低、体积大、可外置的 skill 才值得拆瘦必须每次在场的安全与合规约束保留插件或常驻注入更可靠。拆分换来的可变成本以“命中才付”为前提命中频繁时它反而更贵。参考资料mattpocock/skillsaffaan-m/ECC