Skip to content

OpenAI legacy transform 链路删除 previous_response_id,导致 Codex 长会话 prompt cache 频繁失效、费用暴增 #1558

@NiuHaoRan233

Description

@NiuHaoRan233

现象

使用 Codex(codex-tui / codex_exec)+ 单个 OpenAI 上游账号,长会话下 prompt cache 频繁断裂,费用暴增。

异常请求特征:

  • Input Tokens 高达 17万~62万
  • Cache Read Tokens 却只有 2,432 / 9,344 / 9,600 这类极小固定值
  • 单条请求费用 $1.5~$3.1
  • 正常请求缓存命中率 95%+,异常请求仅 0.5%~5%

此问题与 #1099(多账号路由)无关,单账号场景同样复现,且已更新到最新版本。


数据证据

从导出的使用记录来看(411 条请求,总费用 $113.82):

  • 高缓存(>=80%):311 条,费用 $29.82,占 26%
  • 低缓存(<20%):75 条,费用 $82.29,占 72%

18% 的请求消耗了 72% 的费用。最典型的一条:Input 624,432,Cache Read 9,344,命中率 1.5%,单条 $3.14。

低缓存请求的 Cache Read 始终锁定在几个固定小值,说明上游只命中了极短的公共前缀(约系统提示词),真正的对话历史完全没有续上。


猜想

怀疑根因是:OpenAI 账号未启用 openai_passthrough 时,/responses 请求走的是 legacy transform 链路,该链路会主动改写 Codex 请求:

  1. 删除 previous_response_id:HTTP / WSv1 路径下无条件删除,导致上游无法识别这是同一会话的续链,长会话无法依赖 stored response,只能每轮把完整历史重新发给上游
  2. 强制 store=false:进一步确保上游不存储响应,续链能力完全失效
  3. 重写 instructions / 过滤 input:内容被改写,上游看到的请求和客户端发出的不一致
  4. 重建 session_id / conversation_id:先删掉客户端原始值,再重新生成注入

结果:Codex 长会话退化成每轮全量重发历史,只能靠 prompt cache 省钱。一旦 cache 过期或前缀变化,整段历史按全价 Input 收费。

对比老项目 claude-relay-service,同等场景下只替换鉴权、原样转发 body,不删 previous_response_id,无此问题。


建议

短期:在账号配置里启用 openai_passthrough: true 走纯透传链路。

根本建议:HTTP 路径不应无条件删除 previous_response_id,或对 Codex 客户端(可通过 User-Agent 识别)默认走 passthrough 链路。


验证方法

抓一条 Codex 的上游请求,确认:

  • previous_response_id 是否被删
  • store 是否被改成 false
  • session_id / conversation_id 是否保留客户端原始值

如果被改写,即可确认命中了 legacy transform 路径。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions