GPT Realtime 上生产环境:到底该选哪种上下文策略?
如果你已经把 gpt-realtime 跑上了生产环境,大概率撞到过同一个问题:多轮对话之间,上下文到底该怎么管?
听上去像个实现细节,其实不是。这个决定直接关系到:你每通电话的成本是三毛还是九毛,你呼叫中心的延迟能不能压在两秒以内,以及你的客户会不会在同一通电话里被迫把账号报上五遍。
企业客户把语音和对话式 AI 从 demo 推向规模化时,追问的其实是同一件事:怎么优化 prompt 缓存策略,让调用量从每天一百通涨到十万通时,token 账单和延迟预算不会跟着爆炸。缓存是 realtime API 上撬动成本最狠的那根杠杆:缓存过的音频输入比未缓存便宜 99%,而解锁它靠的是一个稳定的前缀(prefix)。但到底哪种缓存策略真的赢,取决于你的应用是一次性查询、一段简短对话,还是呼叫中心那种动辄三十轮的升级工单。
我拿 Microsoft Foundry 部署的 gpt-realtime 做了一组对照:七种上下文管理策略,同一套负载——一段十轮的病患入院登记对话,医疗支持场景。同一个模型,同一个区域,同一段系统提示词。变的只有策略本身。
为什么上下文策略是那根杠杆
实时语音通话的每一轮,都会把音频 token 发给模型、再收回音频 token。第 N 轮发什么,取决于你决定从第 1 到 N-1 轮里记住什么。这个决定定了你的 token 量,token 量定了你的账单。
Azure gpt-realtime 在 realtime API 上的定价是这样的:音频输入 32 美元/百万 token,缓存音频输入 0.40 美元/百万 token(差不多九九折),音频输出 64 美元/百万 token。缓存折扣大得离谱,所以前缀稳不稳定,几乎就决定了成败。下面这七种策略,说白了就是对同一个问题给出的七个不同答案:第 N 轮,什么东西该待在 prompt 前缀里?
七种策略
A)全量历史。 单条常驻 WebSocket,服务端保留每一条对话记录。第 10 轮能看到第 1 到 9 轮的完整内容。总计 18,123 token,缓存命中率 50.5%,一个稳定增长的前缀,缓存起来特别漂亮。记忆完美,代码最简单。但尾部延迟最糟:第 6 轮花了 6.3 秒,因为前缀越涨越长。而且 WebSocket 一断,整通电话的上下文就全没了。
B)无状态。 每轮开一条新 WebSocket,模型只看得到系统提示词和当前问题。总计 6,557 token,这是地板价。缓存命中率很低,也没有任何对话记忆——只有当每一轮都能独立成立时才用得上。
C)滑动窗口。 每轮新连接,但注入最近两组问答。第 5 轮能看到第 3、4 轮。总计 8,655 token。短期连贯性有了(“对,就那个”),可到第 5 轮,第 1 轮的细节已经丢了。缓存率掉到 20.4%,因为移动的窗口不停地打断前缀。
D)每 5 轮压缩一次。 用 gpt-realtime-mini 每 5 轮生成一段约 70 词的摘要,塞进系统提示词,之前的单轮记录丢弃。总计 8,660 token,缓存率 7.1%,每次刷新摘要都会让前缀失效。语义层面的长期记忆保住了(账号、最初的诉求)。不过我这个十轮测试只触发一次压缩,这套架构本来是奔着三十轮通话去的,在这儿没机会证明自己。
E)滑动 + 压缩。 混合派。系统提示词里放老对话的压缩摘要,外加最近两轮的原文。总计 7,975 token,是所有保留记忆的策略里最紧凑的一个。两个时间尺度都覆盖到了:“你之前提到……"(摘要)和"等一下,你刚说什么?"(窗口)。缓存率 10.4%。能容忍重连的呼叫中心,我会首选它上生产。
F)服务端截断。 “让 API 自己搞定"派。像 A 一样单条常驻 WebSocket,但你传一个截断配置,让服务端在指令后上下文超过 8,000 token 时丢掉最老的条目,保留窗口的 80%。客户端一行历史管理代码都不用写。结果它垫底。总计 18,247 token。八千的阈值在十轮负载里根本没触发——上下文一直没超——所以 F 表现得跟全量历史一模一样,只是多背了点开销。等它在更长的通话里真触发了,缓存会在触发那一轮断掉,省下的也只是一部分。而且你没法调它丢什么,服务端只会不加区分地挑最老的丢。它适合当安全网叠在别的策略上,而不是当主力打法。
G)会话内删除。 这才是给生产语音用的策略。单条常驻 WebSocket 整通电话都活着,这是最关键的一点。每轮之后,客户端检查 response.done → usage.total_tokens。一超过触发阈值(我们用的 600),客户端就做三件事:把最老的几轮总结成一个要点列表,对每一条被取代的条目在服务端调 conversation.item.delete,再把摘要作为系统消息插进去——整个过程不断开 WebSocket。最近两轮永远原样保留。这和 OpenAI cookbook 里的模式一致。总计 14,721 token,缓存率 23.9%。
撬动成本的是 token 量,但决定生产选型的不是
按总 token 排个序:B (6,557) → E (7,975) → C (8,655) → D (8,660) → G (14,721) → A (18,123) → F (18,247)。
看看 A 和 F,缓存命中率最高的两个(50.5%、46.3%),它们偏偏也是最贵的两个。缓存率是个虚荣指标。一万八千 token 打五折,还是比七千 token 打个低折扣要贵。真正付账单的那个数字,是总 token 量。
无状态之所以在 token 量上赢,是因为它压根没在干那件难事,它没有记忆。当每一轮都能独立成立时它才对:药剂师语音查药、用药依从性打卡、药房 IVR 替代,任何"状态由业务流程持有、LLM 只是个语音接口"的场景。
我从这组基准里拿到三个结论。为总 token 量优化,别盯着缓存命中率。缓存率是虚荣指标,大上下文上的高命中率,比小上下文上的低命中率还糟。选能满足你约束的最便宜策略,而不是绝对最便宜的那个。实时语音要用 G,查询类要用 B,呼叫中心要用 E。排行榜告诉你什么最便宜,你的用例告诉你什么能接受。
几条原则,在大多数企业级语音和对话式 AI 部署里都成立:
- 从你的通话形态出发,别从排行榜出发。三轮查询、十轮支持、三十轮升级,各有各的正确答案,挑那个贴合你典型会话的策略。
- 为总 token 量优化。缓存命中率看着诱人,但它只给输入里被缓存的那部分打折;总 token 量才是同时驱动账单和延迟的东西。
- 把系统提示词当成神圣的前缀空间。任何逐轮变化的东西都会把它后面的所有缓存打断,所以稳定内容(指令、人设、长期摘要)放前面,易变内容(当前轮、滑动窗口)放后面。
- 早点定下你的延迟姿态。如果你有严格的两秒 SLA,重连型策略就出局了,你需要一整通电话都保持单条 WebSocket 存活的模式。能接受重连的话,选择就多了,通常还能省 token。
- 把服务端截断当安全网,不是主力。它保证上下文不会无限膨胀,但用默认阈值,恰恰在你最需要的那些通话里很少触发。
- 先测量,再优化。上生产后,把每轮的 token 数、缓存命中率、端到端延迟都埋点跑上至少一周,再选策略。合成基准(包括这一个)也只能近似真实客户对话的样子。
完整代码在这里:https://github.com/ganachan/gpt-realtime-context-strategies/tree/main?WT.mc_id=AI-MVP-5003172
- 本文作者:BeanHsiang
- 本文链接:https://beanhsiang.github.io/post/2026-05-30-gpt-realtime-in-production-which-context-strategy-should-you-actually-use/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。