基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
编程提效2026-11-04 20:35

Claude Code 用量分析揭示上下文成本

dev.to · AI#Claude Code#上下文管理#成本优化
Editor brief · 编辑速览

作者解析 30 天本地会话日志,发现 445.7 亿 token 中约 97% 是缓存读取,子代理占按 API 标价折算成本的 58%。该样本中,限制工具输出的预估收益低于削减启动上下文;折算金额并非其订阅实际账单。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

Claude Code 写代码时,开销最大的一项可能是反复读取已经看过的上下文。作者分析了自己约 30 天的本地日志:44.57B tokens 中,97.03% 用在缓存重读,真正的输出只占 0.27%。

这份分析的价值在于纠正优化顺序:先检查每个 agent 启动时背着多少材料、会话拖了多久,再考虑截断工具输出。不过,这是一名重度使用子代理的开发者的样本,节省比例也只是模拟结果,不能直接当成团队预算承诺。

缓存已经很便宜,为什么还是最大开销

作者统计了 192,178 次 API 请求、889 个主会话和 5,696 个子代理。期间 Claude 输出约 1.22 亿 tokens,却读取了约 430 亿 tokens。

原因在于会话的工作方式:每一步请求都会再次发送上下文。工具返回的文件内容、此前生成的代码、常驻指令,进入会话后都会被后续请求反复读取。

一次工具调用的成本,还取决于它的结果会在上下文里留多久。

按 API 标价折算,作者这个月的用量约值 $15,290,其中缓存读取占 56.6%,缓存写入占 31.7%,输出占 11.6%。作者使用订阅,这不是实际账单。

缓存本身仍然划算。同样的 43.24B tokens,如果按普通输入计价,作者估算约需 $133,000;缓存把这一项压低了约 15 倍。问题出在累计读取量。

长会话尤其明显:超过 200K tokens 上下文的请求占 41.7%,却贡献了 59.6% 的成本。最长的一个会话跑了 2,436 次请求,单独占整月成本的 2.3%。

先把日志算对,再找哪些工具留下了长尾

日志不能逐行直接相加。一个 API 响应可能按内容块写成多行 JSONL,每行都重复同一个 usage 对象,必须按 message.id 去重。

作者的日志里有 400,880 行 assistant 记录,实际只有 192,178 次请求。直接求和会得到 93.0B tokens,是真实约 44.6B 的 2.09 倍;恢复会话还让 287 次请求出现在两个文件中。

下面这段代码读取本地日志,并按响应 ID 汇总用量:

import glob, json, os, time
from collections import Counter

cutoff = time.time() - 30 * 86400
requests = {}  # message.id -> usage
root = os.path.expanduser("~/.claude/projects/**/*.jsonl")

for path in glob.glob(root, recursive=True):
    if os.path.getmtime(path) < cutoff:
        continue
    for line in open(path, errors="ignore"):
        if '"usage"' not in line:
            continue
        try:
            row = json.loads(line)
        except json.JSONDecodeError:
            continue
        msg = row.get("message") or {}
        if row.get("type") == "assistant" and msg.get("usage") and msg.get("id"):
            requests[msg["id"]] = msg["usage"]  # last line wins

totals = Counter()
for usage in requests.values():
    for key in ("input_tokens", "cache_creation_input_tokens",
                "cache_read_input_tokens", "output_tokens"):
        totals[key] += usage.get(key) or 0

print(len(requests), totals)

重点看 requests[msg["id"]] = msg["usage"]:它负责跨内容块、跨文件去重。另一个边界是 os.path.getmtime(path),它筛选整个文件,没有逐条按时间截取,所以结果略高于严格的 30 天窗口。作者处理 21GB 日志约用了 35 秒。

费用还要按每次请求的模型分别计算。原文采用的 Opus 5.5、Sonnet 5.5 缓存读价均为每百万 tokens $0.20,5 分钟和 1 小时缓存写入分别按普通输入价的 1.25 倍、2 倍计算。

算清总量后,作者又估算了工具结果的后续重读开销。结果中位数只有 865 tokens,却会被重读 23 次,平均存续 42.8 次请求。最极端的一次 MCP 资源读取返回 15,183 tokens,此后又留了 334 次请求,累计产生 507 万缓存读取 tokens,约值 $1。

Bash 占可归因工具重读量的 67%。其中 cat、sed、head、tail、awk、nl、wc 这些读文件命令共调用 42,453 次,贡献 4.22B 重读 tokens。相比之下,Read 调用 29,968 次;Shell 读文件的次数是它的 1.4 倍,重读开销是 1.6 倍。

这不能证明 Bash 单次读取更贵,只能说明作者的使用方式里,它调用得多。Write 同样会留下上下文:文件虽然落盘了,作为工具输入的文件正文仍可能被后续读取。

真正该先减的,是每个代理开工前的行李

子代理占作者总成本的 58%。它们第一次调用工具之前,上下文中位数已经达到 68,815 tokens,而整个生命周期的请求数中位数只有 15 次。

作者把启动上下文的开销拆开计算:首次缓存写入 $923,后续重读 $1,934,首次缓存读取 $17,合计 $2,874,占整月 18.8%。首次请求中,只有约 22% 的 tokens 命中缓存。

作者的全局 CLAUDE.md 有 25KB,每个 agent 还要携带工具定义和技能列表。指令只写过一次,但会被许多代理反复处理。

全部缓存读取中,启动上下文占 32.2%,工具结果占 34.4%,剩余 33.4% 包含 assistant 文本、注入提醒和未能归因的内容。

缓存过期反而没那么突出。作者识别出 649 次缓存重建,重写 183.7M tokens,占全部缓存写入的 15.3%,估值约 $740,占总成本 4.8%。其中 257 次发生在前一次请求后不到 5 分钟,另有 61 次与模型切换重合,不能全部归咎于空闲过久。

作者的模拟里,精简启动上下文,比统一截断工具结果更划算。

工具输出限制为 5K tokens,估算节省约 2.4%,却要截断超过 10,000 条结果;启动上下文减少 10K tokens,估算能节省约 3.8%。2K 上限看起来更省,但接近五分之一的调用会丢失部分数据。代理可能因此再跑命令,模拟没有计算这笔补偿开销。

我的判断

这份分析最有用的地方,是把「输出了多少代码」和「实际处理了多少上下文」分开了。对大量使用 agent 的团队,常驻规则、工具返回和会话长度,都应进入成本审查。

但工具归因属于估算。作者根据相邻请求的上下文增量,按工具内容字符数分摊,以字符数除以 2.5 限制估计值,再累计到上下文下降超过 30% 为止。它无法精确还原每段内容的缓存生命周期,而且约三分之一读取没有归因。

因此,前 1% 工具调用贡献 17.4% 重读开销、前 10% 贡献 58.4%,适合用来定位重点排查对象,不宜当作精确账目。

精简指令也有代价。如果删掉的是必要约束,返工可能抵消节省。相比统一截断,按任务加载相关规则、让工具返回更聚焦的内容,更容易保留信息完整性,但原文没有提供这些替代做法的对照数据。

作者也没有做 A/B 实验。3.8% 和 2.4% 应当作为优化顺序的参考,效果仍需在自己的任务上验证。

能拿来做什么

  • 先用日志建立用量基线,按 message.id 去重,分别统计普通输入、缓存写入、缓存读取和输出;费用计算保留模型维度,并明确时间窗口的误差。
  • 审查全局 CLAUDE.md,优先找出每个子代理都会携带、实际却很少用到的规则,把任务专属材料移到需要时再加载的位置。
  • 前端或 Node 排障时,检查 AI 是否反复整段读取同一文件或输出完整日志,优先让查询范围贴近当前问题,并观察是否引发额外调用。
  • 对跨越多个任务、上下文超过 200K tokens 的会话,考虑整理必要结论后开启新会话,同时记录信息遗漏和返工,避免只看 token 降幅。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
Agent 写入有日志,也未必能撤销
下一篇
直接修改模型权重能否修复推理循环

资讯速览

dev.to · AI · 2026-11-04 20:35

AI 评分 8.0 / 10

相关标签

#Claude Code#上下文管理#成本优化

继续阅读

  • 用视觉模型和家庭助手记录口岸拥堵
  • Agent 写入有日志,也未必能撤销
  • 直接修改模型权重能否修复推理循环
  • 用 LibreChat 搭建多租户 AI 服务
  • Helm配置更新成功为何应用仍用旧值