7月8日消息,多名开发者近期发现,Anthropic 的 Claude Code 和 OpenAI 的 Codex Desktop 存在相同的会话管理缺陷:用户在会话中粘贴或附加的图片以 base64 编码形式被写入会话历史文件,并在此后每一轮 API 请求中被完整重发。模型在第一轮已完成图像理解,但此后数十轮对话仍在为同一张图片反复计费。该问题最早可追溯至 2026 年初,目前 GitHub 上相关 issue 均为 open 状态,两家公司均未发布正式修复。 技术根因:图片被当作文本历史保留,而非一次性输入
正常的会话管理逻辑中,文本消息需要保留在历史中以维持上下文连贯性,且文本可享受 prompt cache 机制,重发成本较低。图片则不同——模型在首次接收时完成视觉理解,此后有价值的只是理解结论,原始图片数据不再有信息增量。但 Claude Code 和 Codex 的 session JSONL 文件将图片的完整 base64 数据直接内联存储在会话记录中,既作为 message.content 的一部分,也作为 toolUseResult 的一部分。每张截图通常占 500KB 至数 MB,一旦进入历史,后续所有请求都会携带全部历史图片的完整数据。 更严重的是,两款产品的自动压缩机制基于 Token 数量触发,而非基于请求体积。一张图片在 API 层面约占 1000 Token,但 base64 编码后占 500KB 以上字节。这意味着 117 张截图在 Token 计数上仅占约 10 万,远低于上下文窗口上限,永远不会触发压缩——但请求体积已膨胀到 64MB,远超 API 的 20MB 上限。Token 计数与字节限制完全脱钩,图片数据得以在两道防线之间无限堆积。
实际损害:数百万 Token 消耗、会话永久报废
在 OpenAI Codex 的一个已报告案例中,一次后续请求携带了多张历史图片的 base64 数据,实际上行请求达到 8.34MB,折合约 570 万 prompt Token。用户的 ~/.codex/sessions 目录膨胀至 2.8GB,其中三个会话文件分别达到 1.4GB、1.3GB 和 60MB。在 Claude Code 方面,有用户在仅 41% Token 利用率(约 40.9 万 Token)时就触发了 20MB 请求体积上限,之后所有消息——包括纯文本——全部失败。
另一个被详细记录的 Claude Code 案例中,一次图片尺寸超限触发了 400 错误,Claude Code 静默移除图片后自动重试了 41 次。每次重试都改变了消息前缀,导致 prompt cache 失效,整个上下文在每轮都以 cache-write 费率重新写入。该循环使这一个 session 的总成本膨胀了约 35 倍,而用户在当时完全无法感知。
当积累的图片数据超过一定阈值,/compact 命令本身也会失败,报错 Error compacting conversation。会话进入不可恢复状态,用户被迫手动删除 session 文件,此前所有对话上下文随之丧失。
GitHub issue 状态:均为 Open,官方未给出修复时间表
在 OpenAI 的 Codex 仓库中,相关 issue 包括 #18629(2026 年 5 月)、#23257、#28150、#28316(2026 年 6 月)和 #28531,全部为 open 状态。在 Anthropic 的 Claude Code 仓库中,#19701(2026 年 1 月)、#37418、#43056 和 #65636 描述了相同问题的不同表现形式。#37418 虽已关闭,但其修复仅合并了两个 commit,并未从根本上解决 base64 持久化问题——后续更大规模的 #43056 和 #65636 继续被报告。部分 issue 被 GitHub Actions 机器人标记为 stale 后自动关闭,引发社区不满。
两个仓库中的多位贡献者已给出了明确的修复方向:将图片数据存储为外部引用,在历史中仅保留轻量占位符或哈希摘要,当前轮图片正常发送但不进入持久化历史。Codex 仓库的代码审计显示,其 context_manager/history.rs 中的 for_prompt() 函数仅在目标模型不支持图像输入时才剥离历史图片——对于支持图像的模型,历史图片数据会被完整保留在模型可见范围内。修复方案已经清晰,但截至 7 月 8 日,两家公司均未在正式版本中合入相关修改。
社区自救:Hook 拦截与 Session 文件手术
由于官方修复缺位,社区产出了多种自行缓解方案。image-context-cascade 是一个基于 Hook 的方案,在请求发出前将历史图片替换为可恢复的轻量占位符,保持当前轮图片完整。fix-claude-session 和 claude-code-session-repair 是针对已损坏 session 的 JSONL 文件修复工具,通过定位并删除内联 base64 数据来恢复会话可用性。还有开发者编写了 PostToolUse Hook,监控 session 文件体积,在接近 20MB 上限时强制触发压缩或发出警告。 这些方案的共同前提是:用户需要知道这个问题存在、知道去哪里找 session 文件、知道如何修改 JSONL 结构。对大多数普通付费用户而言,Token 的异常消耗是静默发生的,直到账单或额度耗尽才能察觉。
两家头部产品共享同一架构缺陷,不是巧合
Claude Code 和 Codex 独立开发,但在 session 管理上犯了完全相同的错误:将大体积二进制数据作为文本历史的一部分进行序列化和重放。这反映的是 AI Agent 产品在从单轮问答走向长会话工作流时,session 持久化层的设计没有跟上。文本历史的重放是有价值的——它让模型记住上下文;但图片历史的重放是纯粹的浪费——模型不需要重新看一张已经理解过的图。两者的处理逻辑应该从一开始就不同,但目前两款产品都用同一套全量保留、全量重发的逻辑处理所有类型的内容。
对于高频使用图片输入的开发者(截图调试、UI 审查、设计稿对照),这个缺陷的影响是系统性的。一次包含 8 张截图的调试会话,在后续 30 轮纯文本交互中可能额外消耗超过 100 万 Token,且用户完全无感知。在按量计费模式下,这直接转化为不必要的支出;在订阅模式下,这加速额度耗尽。
等待的是修复意愿,不是修复能力
从已有的代码审计和社区 PR 来看,修复这个问题在技术上并不复杂:将 base64 数据外置为文件引用,在历史重放时用占位符替代,当前轮正常传输。多位贡献者已指出了代码中的具体修改点。问题不在于能不能修,而在于这类不直接影响功能可用性(session 在崩溃前是正常工作的)、不产生用户可见错误信息(Token 消耗是静默的)的缺陷,在产品迭代优先级中被持续排后。社区将此与此前 Codex 的磁盘写入和降智问题类比——都是在舆论压力达到临界点之前,不会获得工程资源投入的类型。