探究 Codex 上下文压缩(Context Compaction)的工作原理

对于非 codex 模型,开源的 Codex CLI 在本地压缩上下文:由 LLM 使用一个 compaction prompt 对对话进行摘要。当压缩后的上下文被后续使用时,responses.create() 会通过一个 handoff prompt 来框定摘要内容。这两个 prompt 都可以在源代码中看到。

对于 codex 模型,CLI 则会调用 compact() API,返回一个加密的 blob。我们不知道它内部是否使用了 LLM,使用了什么 prompt,也不知道是否存在 handoff prompt。
下面,我将展示一个简单的 prompt injection(2 次 API 调用,35 行 Python)如何揭示:API 压缩路径确实使用了 LLM 来摘要上下文,具有自己的 compaction prompt,并且在摘要前会添加一个 handoff prompt。这些 prompt 与开源版本几乎完全相同。
Step 1 — compact()
我使用一条精心构造的用户消息调用 compact()。在服务端,一个 compactor LLM 使用其隐藏的 system prompt 处理我们的输入(这个 system prompt 是我从未见过且想要弄清楚的)。
服务端似乎这样组装 compactor 的上下文:

compactor LLM 同时读取它的 system prompt 和我们的输入。因为我们的输入包含一个注入载荷(上图红色文字部分),compactor 被诱导将自己的 system prompt 写入了输出。这段明文摘要只存在于 OpenAI 的服务器上。我们只能看到加密后的 blob:

此时我们无法读取 blob 内部的内容。它经过 AES 加密,密钥在 OpenAI 的服务器上。我们只能寄希望于 compactor 服从了注入指令,将其 prompt 写入了摘要中。唯一的验证方式是 Step 2。
Step 2 — create()
我将加密 blob + 第二条用户消息传递给 responses.create()。服务端解密 blob 并组装模型的上下文。
我发送的内容:

模型看到的内容大致如下:

如果 Step 1 成功,解密后的 blob 应该包含 compaction prompt(通过我们的注入泄露)。服务端还会在 blob 前面添加一个 handoff prompt。因此,如果我们的探测成功地让模型复述它看到的内容,输出应该能揭示三个部分:system prompt、handoff prompt 和 compaction prompt。
Output
下面是 extract_prompts.py 一次运行的完整、未编辑的输出。黄色 = system prompt,绿色 = handoff prompt,粉色 = compaction prompt。
我们如何确认这些是真实的 prompt 而非模型的幻觉?提取出的 compaction prompt 和 handoff prompt 与开源 Codex CLI 中非 codex 模型使用的已知 prompt(prompt.md、summary_prefix.md)高度匹配,因此模型从零编造这些内容的可能性很低。不同运行之间结果会有差异。

The Guessed Pipeline
综合以上发现,以下是我们对 compact() 在服务端的工作流程的最佳推测,基于提取结果。
The Script

Open Question
为什么 Codex CLI 要使用两条完全不同的压缩路径(非 codex 模型走本地 LLM,codex 模型走加密 API),而底层的 prompt 几乎完全相同?以及,为什么要加密摘要?
很难断言。也许加密 blob 携带的信息超出了这个简单实验所能揭示的范围——例如与工具调用结果的压缩和恢复有关的特定内容。但我没有继续深入测试。
原文作者:Kangwook Lee (@Kangwook_Lee),KRAFTON CAIO / Ludo Robotics CTO 原文链接:https://x.com/Kangwook_Lee/status/2028955292025962534 发布于 2026-03-03
如果这篇文章对你有帮助,欢迎请我喝杯咖啡,支持我继续创作更多内容。
Buy me a coffee