Coze Studio 开源版的 Token 消耗,可以从对话 API 完成事件的 usage 读取。需要找的是 conversation.chat.completed 中的用量对象,不能把“访问令牌 Token”、实时输出的字符数或一条消息完成事件当成模型用量。
本文适用于已经会调用 Coze Studio 流式对话 API 的开发者,依据 2026 年 10 月 1 日读取的官方 API 参考与开源对话用量实现。解析逻辑做过本地示例检查,未采集真实账户用量;下列数字为合成演示数据,不是实测账单。

在哪个事件里找 usage?
一次流式响应可能包含创建、处理中、工具消息、答案增量、答案完成及整轮完成等事件。等到conversation.chat.completed,读取该事件 data 中的 usage;最后的 done 表示流结束,本身不承载这份用量。
event: conversation.chat.completed
data: {"id":"demo-chat-1","conversation_id":"demo-conv-1","usage":{"token_count":160,"input_tokens":120,"output_tokens":40}}
event: done
data: [DONE]
这段演示的 input_tokens 为 120、output_tokens 为 40、token_count 为 160。查看时同时记录 chat ID 与 conversation_id,区分一次执行和整段多轮会话。当前源码在有运行用量时,将运行记录里的输入、输出、总量映射到这些字段;没有统计数据时 usage 可能缺失,不能自动填成 0。
三个字段怎样解读
| 字段 | 代表什么 | 常见误读 |
|---|---|---|
| input_tokens | 本次运行记录报告的模型输入用量 | 只按用户刚输入的一句话估计,忽略系统提示词、历史与检索内容 |
| output_tokens | 本次运行记录报告的模型输出用量 | 用最终页面上的汉字数代替模型统计 |
| token_count | 运行记录报告的总量 | 把它当成费用,或当成该会话所有历史执行的累计值 |
记录这些字段时,保留服务返回值。某些供应商或调用路径的统计口径有差异;总量与分项出现不一致时记录异常并核对模型服务,不要为了表格好看重算后覆盖原始值。缺失字段表示统计不可得,零表示服务明确报告零,这两种情况要分开。
保存事件后,用 Python 提取一次用量
在开发客户端中保存一份脱敏的 SSE 响应为 events.txt;第一次可以直接把上面的演示事件复制进去。下面程序只读本地文件,不发起 API 请求,也不输出问题、答案或令牌。保存为 usage_extract.py,运行 python usage_extract.py events.txt。
import json
import sys
def events(lines):
event, data = "message", []
for line in lines:
line = line.rstrip("\r\n")
if not line:
if data:
yield event, "\n".join(data)
event, data = "message", []
elif line.startswith("event:"):
event = line[6:].lstrip(" ")
elif line.startswith("data:"):
data.append(line[5:].lstrip(" "))
if data:
yield event, "\n".join(data)
seen = set()
found = False
with open(sys.argv[1], encoding="utf-8-sig") as file:
for event, data in events(file):
if event in ("error", "conversation.chat.failed"):
raise RuntimeError("响应包含失败事件,不能按成功用量验收")
if event != "conversation.chat.completed":
continue
item = json.loads(data)
chat_id = item.get("id") or item.get("chat_id")
if not chat_id:
raise ValueError("完成事件没有 chat ID")
key = (str(item.get("conversation_id")), str(chat_id))
if key in seen:
continue
seen.add(key)
found = True
usage = item.get("usage")
if not isinstance(usage, dict):
print("chat:", chat_id, "usage 未提供")
continue
result = {name: usage.get(name) for name in
("input_tokens", "output_tokens", "token_count")}
print(json.dumps({"chat_id": chat_id, "usage": result},
ensure_ascii=False))
if not found:
raise RuntimeError("没有整轮完成事件,当前文件无法给出成功运行用量")
对演示输入,应输出 chat_id=demo-chat-1 和 120、40、160 三项用量。重复保存了同一个完成事件时,程序按会话与 chat ID 组合去重;它不把每个 delta 或 message.completed 累加成另一份用量。示例程序用于查看记录,不负责判断网络流是否完整;请求成功还要检查完成、结束与错误事件。
怎样比较两种提示词的消耗
先固定智能体发布版本、模型和测试任务,分别新建会话,避免一种提示词带着大量历史、另一种从空会话开始。每次记录问题、是否新会话、回答是否正确、chat ID 与 usage,再比较完成同一任务的用量。
例如比较“只给结论”和“给结论及长解释”,不应只看哪个 output_tokens 少;如果短答案遗漏必要步骤,也没有完成原任务。更改输出长度、检索材料或历史轮数后,重复同一组测试并记录实际结果,不承诺固定节省比例。
用量和账单分别核对
Token 数不是金额。开源版调用外部模型,实际费用取决于模型供应商的价格、缓存、推理或其他收费项;服务器与插件成本也不在这三个字段里。对账时使用供应商账单及自己的请求记录,不能套用商业版扣子积分单价。
usage 也不是本地硬件的精确算力指标,不能据此计算固定 GPU 时长。若用量缺失,先检查模型是否返回用量以及 Studio 适配路径是否记录了它,再决定怎样补充统计。
常见疑问
短问题为什么 input_tokens 很多?
检查系统提示词、会话历史、知识库召回材料和工具返回是否进入模型上下文。用新会话做同任务对照,再查看实际输入记录;仅凭一个数不能断言哪段内容最占用。
重新连接收到同一完成事件,要再算一次吗?
同一 chat ID 的同一执行结果不重复计入;真正重新发起了对话、产生新 chat ID,则是另一项执行。连接断开时先核对已有执行记录,不能把重发请求当成无成本读取。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31554.html