Claude Code 到底有多快?每秒令牌数,基于 20,000 轮实测
Claude Code 从不显示输出速度,但每个会话转录里都有计算它所需的全部数据。我们用一个 40 行的脚本跑了自己的 319 个会话、20,408 轮、1,200 万输出令牌:按中位数,Opus 5 每秒输出 63 个令牌,Opus 5.5 为 95,Sonnet 5 为 77,而且短回答总是比长回答慢。本文给出方法、脚本、数据,以及快速模式会带来什么变化。
Claude Code 在令牌方面告诉你很多:/usage 显示会话和本周已用多少,AgentsRoom 的会话监视器逐轮统计输入、输出、缓存读取和缓存写入,状态栏能显示上下文窗口的已用比例。但大家一直在找的数字它们都不显示:你等待时模型每秒实际生成多少令牌。
这个数字没有被隐藏,只是从没被算过。每个会话的每条消息都写入 ~/.claude/projects/ 下的 JSONL 转录,每条助手消息都带时间戳和令牌用量。于是我们在自己的机器上算了最近四周。下面是方法、脚本和结果。
数据从哪里来
Claude Code 为每个会话在 ~/.claude/projects/<project slug>/<session id>.jsonl 写一个文件,每个事件一行。这里要看的是助手消息,只留有用字段后是这样的:
{
"type": "assistant",
"uuid": "24d13076-…",
"parentUuid": "d4447285-…",
"requestId": "req_011CepWq…",
"timestamp": "2026-09-07T18:00:08.412Z",
"message": {
"model": "claude-opus-5",
"usage": {
"input_tokens": 2,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 51591,
"output_tokens": 200,
"output_tokens_details": { "thinking_tokens": 0 },
"speed": "standard"
}
}
}
四点让测量成为可能:
timestamp在内容块追加时写入,所以一轮最后一个块记录的是流结束时刻。parentUuid指向上一行,即模型正在回应的用户消息或工具结果。它的时间戳即请求发出时刻。requestId把一次 API 调用的各个块归到一起。一轮先写文字再调用工具,会产生两行requestId和usage都相同的助手记录,所以令牌按请求计一次,不按行计。usage.output_tokens是请求的总输出,包括思考;output_tokens_details.thinking_tokens说明其中多少是思考。
文件里没有首个令牌的时间。能测的是整轮:从请求离开你的机器到最后一个令牌到达。这也是你等待时唯一感受得到的数字,我们就用它。
方法
对每个 requestId:取带有它的第一行和最后一行助手记录,从第一行读 usage,找到第一行的父记录,再用输出令牌数除以父记录与最后一行时间戳之间的秒数。然后按模型看分布,不看单一平均值,因为 40 秒和 2 秒的轮次不是一回事。
我们剔除了无输出令牌、时长不为正(恢复的会话里,父记录可能晚于子记录)和超过十五分钟的轮次,后者是中断的会话,不是长回答。此外没有任何过滤。
脚本是 40 行无依赖的 Python,在哪都能运行,会读取机器上的所有项目。
import json, glob, os, statistics as st
from datetime import datetime
from collections import defaultdict
def ts(s): return datetime.fromisoformat(s.replace("Z", "+00:00")).timestamp()
turns = []
for path in glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")):
by_uuid, groups, order = {}, {}, []
with open(path) as fh:
for line in fh:
try: o = json.loads(line)
except ValueError: continue
if "uuid" in o: by_uuid[o["uuid"]] = o
msg = o.get("message") or {}
if o.get("type") == "assistant" and msg.get("usage") and o.get("timestamp"):
rid = o.get("requestId") or o["uuid"]
if rid not in groups: groups[rid] = []; order.append(rid)
groups[rid].append(o)
for rid in order:
first, last = groups[rid][0], groups[rid][-1]
out = first["message"]["usage"].get("output_tokens", 0)
parent = by_uuid.get(first.get("parentUuid"))
if not parent or not parent.get("timestamp") or out <= 0: continue
dur = ts(last["timestamp"]) - ts(parent["timestamp"])
if 0 < dur <= 900:
turns.append((first["message"].get("model"), out, dur))
by_model = defaultdict(list)
for model, out, dur in turns: by_model[model].append((out, dur))
for model, rows in sorted(by_model.items(), key=lambda kv: -len(kv[1])):
rates = [o / d for o, d in rows]
print(f"{model:18s} turns={len(rows):6d} median={st.median(rates):5.1f} tok/s "
f"weighted={sum(o for o, _ in rows) / sum(d for _, d in rows):5.1f} tok/s")
weighted 列是令牌总数除以总秒数,对应长时间的自主运行;中位数对应单个交互轮次。
实测数字
法国的一台 Mac,319 个转录,2026 年 8 月 27 日至 9 月 25 日的 20,408 轮,45 小时生成共产出 1,200 万输出令牌。每轮都是标准速度(快速模式见下文)。转录里以 Claude Code 写入的名称出现五个模型。
| 模型 | 轮数 | 中位数 tok/s | 第 25 至 75 百分位 | 加权 tok/s |
|---|---|---|---|---|
| Opus 5 | 16,708 | 62.7 | 51.5 至 71.8 | 69.8 |
| Opus 5.5 | 1,102 | 94.9 | 80.9 至 109.0 | 109.3 |
| Sonnet 5 | 426 | 77.0 | 62.6 至 91.5 | 87.0 |
| Fable 5.1 | 2,070 | 75.1 | 66.1 至 82.9 | 80.0 |
| Opus 4.8 | 102 | 60.9 | 49.1 至 66.5 | 64.2 |
先看两点。第一,Opus 5.5 不是比 Opus 5 快一点:中位数快一半,加权数字快 57%,长轮次占比也高得多。第二,同一模型内部的差异比模型之间更大:Opus 5 第 25 百分位的一轮每秒输出 51 个令牌,第 75 百分位是 72。原因是轮次大小,值得单独一节。
短回答总是更慢
还是 Opus 5,按一轮中的输出令牌数切分:
| 一轮中的输出令牌数 | 轮数 | 中位数 tok/s | 耗时中位数 |
|---|---|---|---|
| 1 至 99 | 1,854 | 42.1 | 1.9 秒 |
| 100 至 499 | 10,743 | 60.6 | 3.4 秒 |
| 500 至 1,999 | 3,512 | 72.8 | 11.1 秒 |
| 2,000 及以上 | 599 | 78.4 | 38.8 秒 |
同一模型、同一个月、同一台机器,一行的回答和长回答速率相差一倍。模型在长轮次里并没有输出得更快。每一轮在首个令牌出现前都要付一笔固定成本:请求发出,提示词被处理,流开始。80 令牌的一轮里,这笔成本占耗时的三分之一;3,000 令牌的一轮里,它淹没在噪声中。
对耗时与输出令牌数做最小二乘拟合,就能分开两者。斜率是流式传输速度,截距是固定成本:
| 模型 | 每轮固定成本 | 流式传输速度 |
|---|---|---|
| Opus 5 | 1.03 秒 | 81.6 tok/s |
| Opus 5.5 | 1.10 秒 | 148.9 tok/s |
| Sonnet 5 | 0.45 秒 | 94.9 tok/s |
| Fable 5.1 | 0.99 秒 | 84.8 tok/s |
| Opus 4.8 | 1.40 秒 | 69.9 tok/s |
所以工具调用密集的会话感觉慢时,问题很少在模型吞吐量,而在轮次数量。逐个读取十二个文件的代理要付十二次固定成本;同一代理用一次批量调用读取,只付一次。这和降低令牌成本是同一个道理:更少更大的轮次,而非更快的模型。
语料中最长的一轮是 Opus 5 在 236 秒内输出 21,332 个令牌,端到端每秒 90 个:固定成本摊薄后,这是我们在该模型标准速度下观察到的上限。
思考令牌也是输出令牌
output_tokens 包含模型在回答前的思考,output_tokens_details.thinking_tokens 告诉你其中有多少。我们的语料中,思考占 Opus 5 全部输出的 30%,Opus 5.5 为 18%,Fable 5.1 为 36%,Sonnet 5 为 54%,Sonnet 5 大多在审查任务中以较高推理强度运行。
这对解读慢的轮次很重要。一轮思考八秒、只打印两行,不是模型慢,而是产出了 600 个你没看到的令牌。按每个令牌算,带思考的轮次比不带的略快:Opus 5 上每秒 67 对 57 个令牌,因为它们更长,更能摊薄固定成本。会话拖沓而你不需要推理过程时,该调的是推理强度,不是模型。
缓存读取改变的是账单,不是速率
Claude Code 几乎每轮都命中提示词缓存:Opus 5 的 16,680 轮中只有 130 轮 cache_read_input_tokens 为零,都是会话的第一轮。输出 100 到 500 令牌的轮次中,命中缓存的中位速度为每秒 60.6 个令牌,耗时 3.4 秒;未命中的为 58.0,耗时 3.7 秒。差别真实但很小,且在固定成本上,不在流式传输速度上。缓存关乎你携带的上下文的价格,所以 AgentsRoom 终端里的令牌计数器把缓存读取和缓存写入分成两个数字显示。
整个月都很稳定
累计数字可能掩盖漂移,所以我们也看了 Opus 5 在最常见的 100 到 500 令牌轮次上的每周中位数:逐周为每秒 63.6、64.1、60.9、61.7、56.9 个令牌,最后一周尚未结束,为 68.7。57 到 69 之间,没有趋势。如果某个下午会话变慢,怪罪模型前,不妨只对那天跑一下脚本。
快速模式改变什么,以及我们没测到的
每个 usage 块都有 speed 字段,我们的 20,408 个全是 standard。Anthropic 为 Claude Opus 提供快速模式,在 CLI 中用 /fast 或在用户设置中用 "fastMode": true 开启,模型最多快 2.5 倍,但每令牌更贵:Opus 5.5 上每百万输入令牌 8 美元、每百万输出令牌 40 美元,Opus 5 和 Opus 4.8 上为 10 美元和 50 美元。Pro 和 Max 套餐中它计入用量额度,不占订阅窗口;Sonnet 和 Haiku 不支持,开启会切换到 Opus。提示词旁的闪电图标表示已开启。
我们没付费用它,没有实测数字可与官方的 2.5 倍对照。如果你在用,同一个脚本就能告诉你效果:按 usage["speed"] == "fast" 过滤轮次,比较中位数。把数字发给我们吧。
这对我们运行代理意味着什么
三点,都与选更快的模型无关。
第一点关于预期。如果七个代理的夜间运行产出两百万个输出令牌,就是每秒 70 个令牌下八小时的生成量,分摊在并行的代理之间。知道速率,才能判断计划任务能否在下一个开始前完成。
第二点关于轮次。每轮固定的那一秒,在 30 令牌的确认和 3,000 令牌的 diff 上都一样。每走一小步都先问、或逐个读文件的代理,时间都花在这一秒上。所以我们在无人值守的代理的提示词里写上“互不依赖的读取要合并成一批”。
第三点关于计数器该显示什么。AgentsRoom 的会话监视器显示令牌和缓存,会话变重时变红;它不显示速率,测完之后,我们也不确定它该不该显示。速率是模型和轮次大小的属性,不是会话的属性,开发者需要的数字就在上面的表格里。所以这是一篇文章,而非一个小组件。
常见问题
Claude Code 每秒生成多少个令牌?
在我们 2026 年 8 月 27 日至 9 月 25 日记录的 20,408 轮中:Opus 5 的输出令牌中位数为每秒 63 个(用全部令牌除以全部秒数则为 69),Opus 5.5 为 95(109),Sonnet 5 为 77(87),Fable 5.1 为 75(80),Opus 4.8 为 61(64)。这些数字算的是整轮,从请求离开你的机器到最后一个令牌流式传输完毕,正是你实际等待的时间。
/usage 或 /cost 会显示每秒令牌数吗?
不会。/usage 显示套餐配额、5 小时窗口和每周窗口,以及上下文窗口的已用比例;/cost 是 /usage 的别名。两者都不显示速率。速度只存在于 ~/.claude/projects/ 下的会话转录中,每条助手消息都带时间戳和输出令牌数,本文脚本读的正是它们。
为什么短回答感觉比长回答更慢?
因为每一轮在首个令牌到达前都要付一笔固定成本:上传请求、处理提示词、启动流。我们的数据中,这笔开销在 Opus 5 和 Opus 5.5 上约一秒,Sonnet 5 上约半秒。80 令牌的回答中,一秒占整轮的三分之一,测得速率降到每秒 40 个令牌;3,000 令牌的回答中,同样的一秒几乎消失,速率升到 80 以上。流式传输速度本身是恒定的。
思考令牌算在速度里吗?
算。每条消息的 usage 块报告 output_tokens及其 output_tokens_details.thinking_tokens 明细,思考令牌是 output_tokens 的一部分。在我们的语料中,思考令牌占 Opus 5 全部输出的 30%,Opus 5.5 为 18%,Sonnet 5 为 54%,后者多以较高推理强度运行。思考很久的一轮并不慢,它在生成你看不到的令牌。
提示词缓存会让 Claude Code 更快吗?
输出速率不会提高。100 到 500 令牌的轮次中,命中提示词缓存时 Opus 5 中位速度为每秒 60.6 个令牌,未命中时为 58.0,整轮耗时 3.4 秒对 3.7 秒。缓存影响的是你为上下文付的钱,不是回答的速度。
Claude Code 的快速模式是什么,能快多少?
Claude Opus 的一种配置,Anthropic 称最多快 2.5 倍,但每令牌更贵:Opus 5.5 上每百万输入令牌 8 美元、每百万输出令牌 40 美元,Opus 5 和 Opus 4.8 上为 10 美元和 50 美元,计入用量额度而非订阅窗口。用 /fast 切换,开启后提示词旁出现小闪电图标。我们测的 20,408 轮没有一轮用快速模式(所有转录都写着 speed: standard),所以没有实测数字;本文数字均为标准速度。
下载 AgentsRoom
在一个窗口中运行你所有项目的所有 AI 代理。
配套应用:随时随地监控你的 Agent
使用 Claude、Codex、Antigravity CLI 或其他 AI 提供商。
把 Bug 和需求直接发送到您的公开待办清单。
继续阅读
把 PDF 转成 Markdown 以节省 LLM token:MarkItDown 实战指南
直接把 PDF 喂给 Claude 或任何 LLM 都会悄悄烧掉大量 token:每一页都会被额外转成图片。先用微软免费开源工具 MarkItDown 把文件转成 Markdown,token 账单最多可降低 80%。完整指南涵盖 CLI、Python 与 MCP 配置。
阅读全文如何与 AI 编程代理沟通:Claude、Codex、Antigravity、Grok Build
代码不再是瓶颈,沟通才是。本文介绍如何与 AI 代理 Claude、Codex、Antigravity 和 Grok Build 协作,让你更快、更精准地交付,同时减少 token 消耗。
阅读全文Antigravity Remote Control:在手机上能做什么,不能做什么
Google在2026年8月21日为Antigravity 2.0和Antigravity CLI推出了Remote Control,这个名字的搜索量说明大家想知道它到底是什么。下面是它能做的事,已于9月22日对照文档核实:设置里的开关和agy remote-control命令,用Google账号登录的网页仪表板,添加到主屏幕后能收到推送通知,多台机器集中在一个切换器里,以及三个要紧的限制(只支持Antigravity,每台机器一个守护进程,设置留在CLI上)。然后讲AgentsRoom手机遥控器怎样覆盖另外13个CLI,以及两者怎样配合。
阅读全文