文档大纲

实战Token消耗优化:帮你节省2/3的大模型花费

如果你每天都在跟 AI 编程工具打交道,这条账单值得你花三分钟看一眼。实测下来,最贵的不是"模型不够聪明",也不是"上下文太长",而是一件很反直觉的事:模型被调用的次数。这篇把一份真实账单拆到了最底层——哪部分钱花在了重复劳动上,哪部分是可以立刻回收的,以及一次把 5 小时额度烧穿的事故是怎么发生的。

最近高强度使用 AI 编程助手:5小时的Max版token plan一般在几十分钟就会烧完。最高一天消耗了20亿token。额外购买积分,经常性一小时就烧掉200以上。这可还是定价比较低的国产大模型,已经相当肉疼了。

对问题进行了分析诊断后,才发现,绝大多数token都是没有产出的浪费。经过优化后,同样的工作量,token消耗降低了至少2/3。本文把我的经验教训分享出来,希望也能帮助你节约token支出。

统计口径:2026-09-29 至 2026-10-26,合计 27.6 天、182 个会话、897 轮对话、40,436 次 LLM 调用。

一页纸结论

结论性质
Token 账单 ≈ 调用次数 × 每次上下文大小,与「回答有多长」几乎无关【实测】
放大器是调用次数(37.2×),不是上下文膨胀(3.2%)【实测】
每次调用的固定底座 42,608 tokens(TOOLS/SKILLS/MEMORY/SYSTEM_PROMPT)占 21.3%【实测】
技能目录 149 条,27.6 天里只被显式调用 39 次(21 个技能)【实测】
「装了但没用」的可回收项合计约 10% 的历史总消耗【实测+推断】

1. 总账

1.1 优化前后对比

维度数值
优化前1周日均消耗1.5B tokens
最高2B tokens / 天(明显恶化)
每轮 LLM 调用次数p50 = 16、p75 = 45、p90 = 125、p99 = 393、max = 743、均值 45.1

【实测】在优化前,cache_read 占 97.5% 意味着:钱花在必须重复发送的上下文上,不是花在写出的文字上。

2. 决定性分解:放大器是「调用次数」

【实测】两个对照实验推翻了「上下文太大」这个直觉:

假设推算结果结论
每轮只调用 1 次 LLM0.22B(少 37.2×)✅ 真正的放大器
上下文在轮内完全不增长只少 3.2%❌ 上下文膨胀不是主因

推论:省 token 的优先级是 ①减少调用次数 → ②压低每次调用的固定底座 → ③压低上下文体积。

措施封顶节省
calls/turn 压到 ≤10省 82%
去掉全部固定底座省 21%
上下文体积砍一半省 3~17%

3. 上下文成分解剖

【实测】22,682 条 context_usage 记录,按时间桶取均值:

成分插件移除后 30min最近 24h前 7 天前 20 天
TOOLS26,49126,53919,49422,505
MESSAGES117,754167,552148,324152,728
MEMORY6,7566,5954,9174,113
SKILLS4,9034,8384,8224,679
SYSTEM_PROMPT4,4584,4363,6343,822
OTHER03,2892,7371,388
固定底座合计42,60844,40840,86739,948

固定底座 × 40,436 次调用 = 1.72B = 21.3% 的总消耗。

3.1 压缩的真实效果(常被高估)

【实测】压缩后上下文从 359k 降到 51k(14%),但那 51k 里 81.8% 是固定开销,工具结果只剩 ~9,257 tokens。 ⇒ 调 toolResultCompaction 的收益远小于想象,因为工具结果文本本来就小(p50 = 349B)。

4. 图片:610MB base64 钉在上下文里

4.1 图片是怎么计费的

【实测】507 张图 / 610.8MB base64 = 快照字节的 79.5%;405 张来自 read(均 1.48MB/张)。读图后 usedTokens 跳变 +6,318 ~ +26,042 ⇒ 按 image token 计费并永久驻留。

4.2 正确使用图片

不是不能使用图片/截图,一定要让大模型从图片中获取信息后,不再反复因读图而消耗token,这个非常重要!

5. 审计「装了但没用」:装了就花钱

对象每次调用固定付出是否「不调用就不付」
技能目录行 – <name>: <description>,实测 SKILLS 分项 4,903 tokens/次(合计 198M ≈ 2.5%)✅ 正文是懒加载的 —— SKILL.md 只在 skill 工具被调用时载入。不调用不付正文钱,只付目录行那一行
工具每个启用工具的完整 JSON schema,实测 TOOLS 分项 26,539 tokens/次(合计 1.07B ≈ 13.3%)❌ 没有「不调用就不付」的机制。schema 每次调用都全量发送

6. 优化方案

6.1 配置收紧 config.yaml

键原值新值作用
toolResultCompaction.maxInlineKiB6432工具结果更早落盘
toolResultCompaction.mcpDetailsMaxInlineKiB3216MCP 详情更早落盘
toolResultCompaction.watermarkKiB25664压缩更早触发 ⇒ 图片更早离场
toolResultCompaction.minSavingsKiB25664同上
toolResultCompaction.keepRecentRounds52保护的历史轮次更少
requestMedia.image.maxwidth/maxheight20001280图片 base64 更小
contextManagement.compactionTriggerAt(默认 95%)0.5上下文到 50% 就压缩

6.2 三段 Hook 架构

UserPromptSubmit ─┬─ context_guard_hook  (≥70% 上下文时提示 /new)
                  └─ handoff_hook         (记录指令)
SessionStart ─────┬─ context_guard_hook
                  └─ handoff_hook         (注入铁律 + 交接卡)
PreToolUse ──────── tool_budget_hook       (调用预算:≥30 提醒,可硬 deny)
Stop ────────────── handoff_hook           (自动写交接卡)

【实测】tool_budget_hook 已在本会话第 30 次调用时真实触发。 【实测】handoff_hook 自测 14/14 通过;5MB 级 transcript 回归 148ms(只读文件尾部)。

6.3 状态外置「铁律」机制(L4)

三件套,每轮自动运行:

  1. Stop 事件 → 写 maintenance/task-state/LATEST.md(目标 / 最近进展 / 涉及文件指针 / 下一会话须知)
  2. SessionStart 事件 → 注入铁律 + 交接卡路径与摘要 ⇒ 新会话自动接力
  3. PreToolUse 事件 → 调用预算硬护栏

关键设计:交接卡由 Stop 事件「持续刷新」,与 /new 的时机无关。 ⇒ 「/new 前要做什么才不中断任务」这个问题本身被消解了 —— 任何时刻切走,卡片都已是最新。

7. 问答附录

Q1 L4 状态外置如何自动化并形成铁律?

见 §6.3。三层结构:规则注入(SessionStart/UserPromptSubmit)→ 硬拦截(PreToolUse deny)→ 产物落盘(交接卡)。

Q2 使用 /new 前该做什么才不中断任务?

不需要做任何事(已验证:Stop 事件持续刷新卡片)。唯一注意:卡片里的「目标」取自最近一条指令,你刚改主意还没说出口的部分新会话看不到 —— 补一句即可强制刷新。

Q3 新会话可以接力任务吗?

可以。 SessionStart 自动把交接卡路径 + 摘要注入新会话第一轮上下文,Agent 会先读它再动手。 【实测】e2e 注入文本 = 铁律 3 条 + 卡片路径 + 卡片摘要。

Q4 /new 是原窗口继续还是必须用 +?

  • 【实测】桌面端把 /new(及 /clear)映射为动作 new_chat;/compact → summarize;/fork = 复制成新会话且保留上下文(不减体积,别拿它当省 token 手段)。
  • 【未验证】new_chat 在 UI 层是「当前窗口换一条会话」还是「并列开新窗口」——源码只给了动作名,界面表现未实测。
  • 【实测】两者都会触发 SessionStart,接力都成立。要跟旧会话对照就用 +。

Q5 图片读过后如何从上下文清掉?

自动压缩时 archiveImages() 会把图片换成文字收据,不需要手工清。

Q6 长会话压调用次数(非技术版)

把一次问答想成一场很长的会议。每翻一页资料,整本会议记录就要重新复印一份寄给记录员 —— 复印费就是 token。

  • 会议越久,每页复印越贵(上下文变大)→ 小头。
  • 真正的开销是记录员被打断的次数:你每追问一句、他每翻一次文件,整本记录重印一遍。被打断 100 次 = 复印 100 次整本。

所以第一招不是「少说话」,是「少打断」:

  1. 一句话把事说全,别挤牙膏式追问;
  2. 让他一次把清单拉完(一次 grep 拿全部,而不是一条一条试);
  3. 长表格、长日志让他写成文件,你只拿结论和路径;
  4. 截图、整段代码、大文件别反复贴;
  5. 事说清就让他做完,别做一半插话问「到哪了」。

经验值:一轮问答让他来回动手 10 次以内,比 100 次省约 8 成。

8. 总结

任何"一次对话 = 一次模型调用 + 一份固定上下文"的工具,都逃不开下面这三条:

  • 固定底座是刚性的。
    • 工具定义、系统提示、技能目录,无论你这一轮说了什么,都会被整份发出去。你以为"这次只问了一句话",实际账单付的是"一整套工具 + 全部历史 + 全部规则"。
    • 不要看到好工具就安装,把工具数量控制在够用就行,一定要记住:每个启用的工具都是每次调用的固定开销。
  • 调用次数是乘数。
    • 本次实测里,把每轮调用次数压到10次以内,可以砍掉约82%的总消耗;把上下文体积砍一半,只能省3%到17%。两个数字差了一个数量级。
    • 给调用次数设一个硬上限
    • 把长表格和长日志落盘成文件只让模型读结论
    • 在上下文接近阈值时主动开新会话
  • 缓存读取是"重复劳动"的钱。
    • 它便宜,但量大到足以把token 消耗烧穿10倍;
    • 本地 93.6% 的重复上下文在任何口径下都是纯浪费。
    • 先砍上下文体积(autoCompactWindow、块预算),再谈调优。
阅读量: 135