
对于非 Codex 模型,开源的 Codex CLI 在本地压缩上下文:一个大语言模型(LLM)使用压缩提示词(compaction prompt)来总结对话。当压缩后的上下文随后被使用时,responses.create() 会接收它以及一个框架化该摘要的衔接提示词(handoff prompt)。这两个提示词在源代码中都是可见的。
对于 Codex 模型,CLI 转而调用 compact() API,该 API 返回一个加密二进制大对象(encrypted blob)。我们不知道它内部是否使用了大语言模型(LLM),使用了什么提示词,或者是否根本没有衔接提示词(handoff prompt)。
在下文中,我将展示一个简单的提示词注入(prompt injection)(2 次 API 调用,35 行 Python 代码)如何揭示 API 压缩路径确实使用了一个大语言模型(LLM)来总结上下文,并带有它自己的压缩提示词(compaction prompt)和在摘要前添加的衔接提示词(handoff prompt)。这些提示词与开源版本几乎完全相同。
第 1 步 — compact()
我使用精心设计的用户消息调用 compact()。在服务端,一个压缩器大语言模型(compactor LLM)使用它自己隐藏的系统提示词(我从未见过并想弄清楚)来处理我们的输入。
服务端似乎是这样组装压缩器的上下文的:
压缩器大语言模型(LLM)同时读取其系统提示词和我们的输入。由于我们的输入包含一个注入有效载荷(injection payload)(上方的红色文字),压缩器被诱导在其输出中包含了它自己的系统提示词。这个明文摘要(plaintext summary)仅存在于 OpenAI 的服务器上。我们只能看到加密二进制大对象(encrypted blob):
此时,我们无法读取该对象内部的内容。 它是经过 AES 加密的(AES-encrypted),且密钥保存在 OpenAI 的服务器上。我们只能希望压缩器服从了注入,并将它的提示词写入了摘要中。找出答案的唯一方法是第 2 步。
第 2 步 — create()
我将加密二进制大对象(encrypted blob)连同第二条用户消息传递给 responses.create()。服务器解密该对象并组装模型的上下文。
我发送:
模型看到的似乎是这样的内容:
如果第 1 步奏效,解密后的对象应该包含被我们的注入泄露的压缩提示词(compaction prompt)。服务器还会在该对象前添加一个衔接提示词(handoff prompt)。因此,如果我们的探测成功让模型重复它所看到的内容,输出应该能揭示全部三个部分:系统提示词(system prompt)、衔接提示词(handoff prompt)和压缩提示词(compaction prompt)。
输出
以下是 extract_prompts.py 一次运行的完整、未经编辑的输出。黄色 = 系统提示词(system prompt),绿色 = 衔接提示词(handoff prompt),粉色 = 压缩提示词(compaction prompt)。
https://github.com/openai/codex/blob/main/codex-rs/core/templates/compact/summary_prefix.md
我们如何知道这些是真实的提示词而不是虚假的幻觉文本(hallucinated text)?提取出的压缩提示词(compaction prompt)和衔接提示词(handoff prompt)与开源 Codex CLI 中用于非 Codex 模型的已知提示词(prompt.md,summary_prefix.md)密切匹配,这使得模型凭空捏造它们的可能性很低。不同运行的结果会有所不同。
推测的流水线(Guessed Pipeline)
综上所述,这是我们根据提取出的内容对 compact() 在服务端所做工作的最佳推测。
https://github.com/openai/codex/blob/main/codex-rs/core/templates/compact/prompt.md
脚本
开放性问题(Open Question)
当底层提示词几乎相同时,为什么 Codex CLI 要使用两种完全不同的压缩路径(非 Codex 模型使用本地大语言模型,Codex 模型使用加密 API)?又为什么要对摘要进行加密?
很难说。也许加密二进制大对象(encrypted blob)携带的内容比这个简单实验所揭示的更多,例如,关于如何压缩和恢复工具结果(tool results)的特定信息。但我没有费心进一步测试。






