目录
并行运行好几个 Claude Code 会话时,每周额度会比预想的掉得更快。你想知道是哪个会话在吃额度,可打开 /usage 也找不到答案。
先说结论:截至2026年9月,没有任何官方界面会显示每个会话各占了多少用量。/usage 给出的是当前会话的数字,以及把整个套餐的消耗按技能、子智能体、插件、MCP 服务器拆分后的百分比。想按会话来看,就得自己汇总保存在本机上的对话日志。
不过,这些日志如果直接去数,就会数错。我在自己的机器上实测了最近 7 天的日志,把各行直接相加得到的总量是正确值的 2.06 倍。更麻烦的是,即使只看用量最多的 12 个会话,误差倍数也在 1.30 倍到 3.02 倍之间参差不齐,连排名都会变。本文依次介绍官方界面能看到什么、正确的计数方法、一个约 50 行的汇总脚本,以及实测结果。
最近 7 天,是哪些会话用掉的
我机器上的 29 个会话,按 API 价格换算加权。官方界面不会给出这份明细
来源:我的实测(截至2026年9月15日的最近 7 天;对象是在 Windows 桌面应用中运行的会话,用本文的汇总脚本算出)
1. 官方界面能看到什么、看不到什么
与用量相关的主要官方显示如下(截至2026年9月)。它们都不显示每个会话的占比。最接近的是 /usage 的套餐明细,但它的维度是“用在了哪个功能上”,而不是“哪个会话用的”。
| 查看位置 | 能看到什么 | 按会话的占比 |
|---|---|---|
/usage 的 Session 栏 | 当前会话的 token 数与估算费用(按模型)。执行 /clear 后归零。文档注明它“面向 API 用户”,并说对 Claude Max 和 Pro 订阅用户而言“会话费用这个数字与计费无关” | ✕ 仅当前会话 |
/usage 的套餐用量明细(Pro、Max、Team、Enterprise) | 最近 24 小时或 7 天的用量,按技能、子智能体、插件、MCP 服务器以百分比列出。用 d 和 w 切换。从 v2.1.242 起,还会“为最近运行过的最重的 /loop 或其他定时任务各加一行,按 token 总量排序” | ✕ 按功能、按定时任务,不是按会话 |
| 桌面应用的用量环 | 该会话的上下文窗口用量,以及当期的套餐用量。文档写道“套餐用量在你所有的 Claude Code 界面之间共享” | ✕ 整个套餐的数字 |
| claude.ai 的 Settings > Usage | “5 小时会话与每周用量上限”的进度条,以及各自的重置时间 | ✕ 整个套餐的数字 |
/insights | 分析本机近期会话的 HTML 报告(在哪些项目里做什么、在哪里卡住了)。文档称它是“一份关于你如何工作的报告,而不是关于你用了多少 token” | ✕ 不显示 token 数 |
| Team、Enterprise 的分析面板,Claude Console | 按用户、按模型的花费 | ✕ 以用户为单位 |
| OpenTelemetry(导出监控数据) | token 与费用指标默认带有会话 ID | ✓ 但需要自己准备收集端 |
来源:Claude Code 官方文档《Manage costs effectively》(/usage、/insights、面向组织的面板)、Claude Code 官方文档《Desktop》(用量环)、Claude 帮助中心《Usage limit best practices》(设置中的用量页面)、Claude Code 官方文档《Monitoring》(OpenTelemetry)
官方的“会话上限”说的不是对话会话
在 claude.ai 的用量页面上,“会话”指的是5 小时的用量窗口,与你在 Claude Code 里逐个打开的对话会话毫无关系。本文所说的“会话”一律指后者:侧边栏里列出的每一项。
关于 /usage 的套餐明细,文档还写了一件重要的事:“这些数字是近似值,根据本机的本地会话历史计算,因此不包含其他设备或 claude.ai 上的用量。”也就是说,就连官方的明细,追根溯源也来自你本地的日志。自己去读同样的日志,就能沿着官方界面没给出的那个维度——会话——来汇总。如果你已经撞上上限、想确认还剩多少,请参阅Claude Code usage limit reached 成因与对策。
2. 答案就在本地的对话日志里
Claude Code 会把每段对话的完整记录保存为 JSONL(每行一个 JSON 对象),一个会话一个文件。存放位置在官方文档里写明了。
消息、工具调用,连工具结果都全部记在里面。Windows 上是 C:\Users\<用户名>\.claude\projects
子智能体的对话保存在与主体分开的文件里。父日志过期被删除时,它们也会一起被删除
在终端里使用的会话,超过 cleanupPeriodDays(默认 30 天)就会被删除。在桌面应用(或 Cowork)中开始或最近一次继续的会话,从 v2.1.248 起无论多久都会保留
来源:Claude Code 官方文档《Explore the .claude directory》
在我的机器上,<项目> 文件夹的名字是把工作文件夹绝对路径中的符号替换成 - 之后的字符串(D:\work\site-a 就变成 D--work-site-a)。从桌面应用的 Code 标签页运行的会话也写在同一位置,并且每一行都记录着 "entrypoint":"claude-desktop"。
要汇总的,是记录 Claude 回复的那些行("type":"assistant")上附带的 usage。下面是真实的一行,只保留了汇总要用到的字段(ID 已隐去)。
{"type":"assistant","requestId":"req_…","timestamp":"2026-07-25T00:16:37.822Z",
"message":{"id":"msg_…","model":"claude-opus-5",
"content":[{"type":"text","text":"…"}],
"usage":{"input_tokens":2,"output_tokens":255,
"cache_read_input_tokens":33775,"cache_creation_input_tokens":17265,
"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":17265}}}}
usage 里的 4 个数字(输入、输出、缓存读取、缓存写入)是 Claude API 响应中的官方字段。但日志文件本身的格式——每一行写些什么——并没有官方文档说明。本文的计数方法是用我手头 v2.1.197 至 v2.1.260 的日志验证过的,今后的版本中可能会失效。
官方文档还明确写了一条注意事项:“对话记录与历史在存储时不加密,唯一的保护是操作系统的文件权限。”如果某个工具读取了 .env 文件,其内容也会留在日志里。把汇总结果给别人看没有问题,但把日志本身交给别人,或者让不太了解的工具去读取时,请务必小心。
3. 直接相加会多出约一倍——4 个陷阱
找到带 usage 的行,全部加起来——这是最直观的做法,但在我的日志里,总量大约是正确值的两倍。原因有 4 个。
陷阱 1:一次回复会写成好几行
Claude 的一次回复(一次 API 请求)不一定对应日志里的一行。在我的机器上,思考、正文、工具调用这样的每个内容块都各自写成一行(超过 99.9% 的行恰好只含一个块),而且每一行都带有 usage。用来识别一次回复的,是 message.id 与 requestId 的组合。
71,865 次回复。直接相加没有问题
69,810 次回复。相加就算成了 2 倍
53,060 次回复。相加就算成了 3 倍
19,475 次回复。相加就算成了 4 倍以上
来源:我的实测(2026年3月30日至9月15日的日志;带 usage 的 476,404 行,对应 214,210 次回复)
在写成两行及以上的 142,345 次回复中,76% 的每一行 usage 都完全相同。其余 24% 中,输出 token 的数值逐行不同。因此,对每次回复只保留输出 token 最大的那一行。另外,有 1,903 次回复还出现在另一个文件里(占全部 token 的 0.95%)。我没有查明原因,但只要按同一个键合并,这部分也不会被重复计算。
陷阱 2:子智能体的记录在单独的文件里
只读取主 .jsonl 文件的话,子智能体的部分会整个漏掉。在我的日志中,正确总量里来自子智能体的比例如下。
- 输入(未缓存):42.9%
- 输出:23.2%
- 缓存写入:10.8%
- 缓存读取:6.9%
按会话看,差距更大:最近 7 天按价格加权,从 0% 的会话到 54% 的会话都有。越是把工作分派给子智能体的会话,只数主文件时看起来就越小。
陷阱 3:两种误差会部分抵消,但每个会话抵消的程度不同
把主文件里的行直接相加,陷阱 1 会让数字变大,陷阱 2 又会让它变小。最近 7 天的总量是正确值的 2.06 倍。如果每个会话都偏离相同的倍数,占比依然是对的。但实际上并非如此。
| 会话 | 正确占比(排名) | 直接相加的占比(排名) | 直接相加 ÷ 正确 | 子智能体占比 |
|---|---|---|---|---|
| A | 31.7%(第1名) | 27.4%(第1名) | 1.79 倍 | 21% |
| C | 12.7%(第2名) | 12.0%(第3名) | 1.96 倍 | 2% |
| B | 11.4%(第3名) | 15.0%(第2名) | 2.71 倍 | 9% |
| D | 8.6%(第4名) | 5.4%(第5名) | 1.30 倍 | 39% |
| E | 5.4%(第5名) | 6.8%(第4名) | 2.60 倍 | 39% |
| F | 4.6%(第6名) | 4.1%(第8名) | 1.85 倍 | 0% |
| G | 3.2%(第9名) | 4.7%(第6名) | 3.02 倍 | 5% |
来源:我的实测(截至2026年9月15日的最近 7 天。为便于比较,仅此表连同子智能体占比在内都使用未加权的 token 数。会话字母与开头的图一致)
第 2 名与第 3 名互换,第 4 名与第 5 名也互换,实际排第 9 的 G 升到了第 6。依赖子智能体的 D 显得偏小,正是陷阱 2 的表现;但子智能体占比同样是 39% 的 E,却反过来达到了 2.60 倍。每次回复拆成多少行(包含多少思考和工具调用)也有影响,所以这个倍数无法事先预测。“直接除以二就行”是行不通的。
陷阱 4:97% 的 token 是缓存读取
即便计数正确,直接比较原始 token 数也会看错每个会话的轻重。最近 7 天的构成如下。
token 构成(最近 7 天,全部会话合计)
来源:我的实测(截至2026年9月15日的最近 7 天)
然而各项的单价相差极大。按 Anthropic 官方价格页,缓存读取是基础输入价格的 0.1 倍(Claude Fable 5.1 与 Claude Mythos 5.1 为 0.025 倍),5 分钟缓存写入是 1.25 倍,1 小时缓存写入是 2 倍,而输出在所有现行模型上都是输入价格的 5 倍。按 token 数占 12.7% 的会话 C,用这些价格加权后变成了 10.4%。
数字的大小本身也说明问题。在前 12 个会话中,除 D 和 E 之外的 10 个,每次回复平均读取约 41 万至 48 万 token 的上下文(依赖子智能体的 D 和 E 平均约为 24 万和 31 万)。“Claude Code 每次请求都会发送整段对话”,所以会话开得越久,每次请求就越重。其中的机制在Claude Code 的上下文到底被什么吃掉了里有详细说明。
4. 汇总脚本
这个汇总脚本把 4 个陷阱全部考虑在内。只用 Python 3 标准库就能运行(我在 3.11 上测试过)。它只读取日志,既不做任何修改,也不发送任何数据。如果你用环境变量 CLAUDE_CONFIG_DIR 改过配置目录的位置,它会改从那里读取。
import json, os, sys
from collections import defaultdict
from datetime import datetime, timedelta, timezone
from pathlib import Path
DAYS = float(sys.argv[1]) if len(sys.argv) > 1 else 7
ROOT = Path(os.environ.get("CLAUDE_CONFIG_DIR") or Path.home() / ".claude") / "projects"
SINCE = datetime.now(timezone.utc) - timedelta(days=DAYS)
# USD per 1M input tokens (output = 5x). First match wins.
PRICES = [("sonnet-5", 2), ("sonnet", 3), ("haiku", 1), ("opus-4-1", 15),
("opus-4-2025", 15), ("opus", 5), ("fable", 10), ("mythos", 10)]
best = {} # one API response = one (message.id, requestId)
for path in ROOT.rglob("*.jsonl"): # also reads <session>/subagents/*.jsonl
project = path.relative_to(ROOT).parts[0]
with path.open(encoding="utf-8", errors="replace") as f:
for line in f:
if '"usage"' not in line:
continue
try:
row = json.loads(line)
except ValueError:
continue
msg = row.get("message") or {}
usage = msg.get("usage")
ts = row.get("timestamp")
if row.get("type") != "assistant" or not usage or not ts:
continue
if datetime.fromisoformat(ts.replace("Z", "+00:00")) < SINCE:
continue
key = (msg.get("id"), row.get("requestId"))
old = best.get(key)
if old is None or usage.get("output_tokens", 0) >= old[2].get("output_tokens", 0):
best[key] = (project, msg.get("model") or "", usage)
totals = defaultdict(lambda: [0, 0.0]) # [tokens, weight]
for project, model, u in best.values():
p = next((v for name, v in PRICES if name in model), 5)
read_rate = 0.025 if "5-1" in model and ("fable" in model or "mythos" in model) else 0.1
inp, out = u.get("input_tokens", 0), u.get("output_tokens", 0)
read, write = u.get("cache_read_input_tokens", 0), u.get("cache_creation_input_tokens", 0)
write_1h = (u.get("cache_creation") or {}).get("ephemeral_1h_input_tokens", 0)
totals[project][0] += inp + out + read + write
totals[project][1] += p * (inp + out * 5 + read * read_rate
+ (write - write_1h) * 1.25 + write_1h * 2)
all_tokens = sum(t for t, _ in totals.values()) or 1
all_weight = sum(w for _, w in totals.values()) or 1
print(f"last {DAYS:g} days: {len(best):,} responses")
print(f"{'weight':>7} {'tokens':>7} project")
for project, (t, w) in sorted(totals.items(), key=lambda kv: -kv[1][1]):
print(f"{w / all_weight:7.1%} {t / all_tokens:7.1%} {project}")
把它保存为 usage_by_session.py 之类的名字,并把天数作为参数传入。省略参数时统计最近 7 天。
python usage_by_session.py # 最近 7 天
python usage_by_session.py 1 # 最近 24 小时
python usage_by_session.py 30 # 最近 30 天
输出如下(文件夹名已隐去)。weight 是按价格加权的占比,tokens 是按原始 token 数的占比。
last 7 days: 19,991 responses
weight tokens project
32.3% 31.7% D--work-project-a
11.1% 11.4% D--work-project-b
10.4% 12.7% D--work-project-c
7.7% 8.6% D--work-project-d
6.4% 5.4% D--work-project-e
脚本做了什么
- 用
rglob一直读到子文件夹:subagents/下的文件也会被读取,并计入其父会话所在的同一个项目(陷阱 2) - 按
message.id与requestId的组合把多行合并为一次回复,保留输出 token 最多的那一行(陷阱 1) - 按单价加权:以模型的输入价格为基准,输出乘 5 倍,缓存读取乘 0.1 倍,缓存写入乘 1.25 倍或 2 倍(陷阱 4)。价格与2026年9月的官方价格页一致,价格变动时请更新
PRICES - 按项目文件夹分组:如果你在同一个文件夹里开了多个会话,把
project换成按文件名汇总(子智能体则按subagents文件夹上一层的会话文件夹名),结果就会按会话 ID 分开
5. 实测:29 个会话中有 1 个用掉了近三分之一
最近 7 天,我的机器上有 29 个会话处于活动状态。如开头的图所示,用量集中在其中极少数几个会话上。
1 个会话,约占总量的三分之一
3 个会话,超过一半
其余 24 个合计约三分之一
29 个中超过一半
来源:我的实测(截至2026年9月15日的最近 7 天,按 API 价格加权)
把数字并排来看,可以看出三点。
第一,排在前面的会话,每一次请求都很重。前 3 个会话每次回复平均读取约 41 万至 48 万 token。并不只是请求次数多:它们一整天都开着,上下文不断变长。官方文档也指出,在长时间开着的会话里,哪怕只问一行问题,也会产生整段对话那么多的用量。
第二,依赖子智能体的会话,从主对话看起来很小。在 D 和 E 中,子智能体分别占了按价格加权用量的 44% 和 54%。只看侧边栏里的主对话,这部分是完全看不到的。
第三,超过一半的会话几乎没怎么用。额度掉得快,不是因为开着的会话多,而是少数几个重会话在消耗它。要采取措施,从这几个入手就够了。先削什么,请参阅Claude Code 省 Token 技巧与达到上限后的额外费用。
6. 数字怎么读,以及它的边界
这份汇总能告诉你什么、不能告诉你什么
- 🟡 权重是基于 API 价格的估算。Anthropic 并未公布 Pro 和 Max 的额度会按这个比例消耗。它可以作为会话之间相互比较的尺子,但不能用来计算你还剩百分之多少
- 只涵盖这台机器。其他机器、claude.ai 上的聊天以及在云端运行的会话都不包括在内。官方
/usage的明细也有同样的限制 - 在终端里使用的会话,无法追溯到 30 天以前。因为日志会在超过
cleanupPeriodDays(默认 30 天)后被删除。在桌面应用(或 Cowork)中开始或最近一次继续的会话,从 v2.1.248 起无论多久都会保留 - 🟡 日志格式不是官方规范。一次回复拆成多少行之类的细节,可能随版本变化。如果数字看起来不对,先比较合并重复行前后的条数
- 价格会变。Claude Sonnet 5 的首发价 $2/$10(每百万 token 的输入/输出)已转为正式价格(原定9月1日的涨价已取消),Fable 5.1 的缓存读取是输入价格的 0.025 倍。请让
PRICES与官方价格页保持一致
7. 想从现在起持续观察,就用 OpenTelemetry
汇总日志的长处是马上就能看到过去 30 天。如果你想从现在起持续观察,官方的监控功能 OpenTelemetry 更合适。
启用后,Claude Code 会导出 token 指标 claude_code.token.usage(类型有 input、output、cacheRead、cacheCreation)和费用指标 claude_code.cost.usage。两者默认都带有 session.id(OTEL_METRICS_INCLUDE_SESSION_ID,默认为 true)。由于它不读取日志文件,陷阱 1 的重复行问题根本不会出现,子智能体的用量也会按 query_source(main、subagent、auxiliary)分开记录。
想先在本地试试,可以按文档所示,把导出器设为输出到终端,然后启动 Claude Code。
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=1000
claude
要持续汇总,就设置 OTEL_METRICS_EXPORTER=otlp,把数据发送到你自己运行的接收端(能接收 OTLP 的监控后端)。需要自己搭建这个接收端,而且启用之前的用量不会被记录:这就是它与汇总日志的区别。
来源:Claude Code 官方文档《Monitoring》(指标名、属性、环境变量)
FAQ
Q1. /usage 的套餐明细还不够吗?
维度不同。套餐明细以百分比显示用量用在了哪些技能、子智能体、插件和 MCP 服务器上,但不显示是哪个会话用的。从功能一侧追查额度消耗的原因,就用 /usage;从会话一侧追查,就用本文的汇总方法。
Q2. 能用现成的汇总工具吗?
可以。例如非官方工具 ccusage 就能从同样的日志生成按会话的报告。使用前请确认两点。第一,所有处理是否都在本机完成:日志里包含未加密的工具结果。第二,它是怎么计数的:为确认它对重复行和子智能体的处理方式与本文一致,请拿它的结果与本文脚本的结果对照一次。
Q3. 我想把其他机器和 claude.ai 上的用量也算进来。
日志只按机器分别保存,所以要在每台机器上分别汇总,再把结果加起来。claude.ai 上的聊天不会记录在 Claude Code 的日志里。至于整个套餐还剩多少,看 claude.ai 上 Settings > Usage 里的进度条最可靠。
Q4. 我想保留日志,以便汇总更早的用量。
在终端里使用的会话,只要调大 settings.json 中的 cleanupPeriodDays,就能保留得更久。在桌面应用(或 Cowork)中开始或最近一次继续的会话,从 v2.1.248 起本来就无论多久都会保留(想设定期限时用 desktopSessionCleanupPeriodDays)。不过要注意,官方文档把调小这些值列为减少日志暴露的手段之一。保留得越久,未加密的记录留在本机上的时间就越长,请把这一点记在心上。
出处
- Claude Code Docs — Manage costs effectively(
/usage的 Session 栏与套餐用量明细、“根据本机历史计算”的说明、/insights、面向组织的面板、长会话中用量增长的原因) - Claude Code Docs — Explore the .claude directory(日志的存放位置、
subagents/、cleanupPeriodDays默认 30 天及桌面应用会话的处理方式、未加密) - Claude Code Docs — Desktop(用量环)
- Claude Help Center — Usage limit best practices(Settings > Usage 显示的内容)
- Claude Code Docs — Monitoring(OpenTelemetry 指标名、
session.id、环境变量) - Claude Platform Docs — Pricing(各模型单价、缓存倍率)
相关文章
- Claude Code 的上下文到底被什么吃掉了——为什么每次回复会变重
- Claude Code usage limit reached 成因与对策——撞上上限的时候
- Claude Code 省 Token 技巧与达到上限后的额外费用——先削什么
- Claude Code 每周限额:提前恢复的真相——每周额度的机制