Codex 的本地 Token 估算是字节启发式,不是模型 tokenizer 的精确复刻。它把 Base Instructions 与每个 ResponseItem 的“模型可见估算字节”相加,再按约四字节一 Token 换算;真实服务端 usage 到达后,则以 usage 为基准补上本地新增项。
不直接按序列化长度计费
Reasoning 加密内容、加密函数输出、base64 图片和音频若按原始字符串长度估算,会把编码膨胀误当成模型 Token。估算器对这些载荷做替换:减掉 raw payload 字节,加上固定或模态专用 token 估计。
def estimate_item_tokens(item):
raw_bytes = len(json_encode(item))
visible = raw_bytes
visible -= encoded_media_bytes(item)
visible += estimated_media_bytes(item)
visible -= encrypted_payload_bytes(item)
visible += estimated_plaintext_bytes(item)
return ceil(max(0, visible) / 4)
源码注释明确称其为 coarse lower bound。所有加法使用饱和运算,极端长度不会整数溢出。
单项输出上限在记录时执行
Function 与 Custom Tool output 进入 History 前按模型的 TruncationPolicy 截断。策略可按 Token 控制,并乘 1.2 给 JSON 序列化留余量。图片/音频 content items 也受输出预算影响,超限载荷可能被省略。
def active_context_tokens(history, server_usage, reasoning_included):
total = server_usage.total_tokens if server_usage else 0
if not reasoning_included:
total += estimate_old_encrypted_reasoning(history)
total += estimate_items_after_last_model_output(history)
return saturating(total)
服务端 usage 只覆盖截至最近模型响应的内容;之后本地追加的工具结果和用户 steer 需额外估算。若响应头说明 server 已计入历史 reasoning,则不重复加入。
源码与测试锚点
codex-rs/core/src/context_manager/history.rs:单项处理与估算器。codex-rs/utils/output-truncation:字节/Token 启发式与截断。codex-rs/core/src/context_manager/history_tests.rs:图片、音频、加密 payload 估算。
评论
登录后即可评论