做同传时,我最怕对方说完了,屏幕还没给我任何东西。可如果为了快,把模型每个没说完的碎片都直接当定稿,我看到的又可能是半句日语配上一句并不属于它的中文。我的处理方法是把出字和校正分开:先显示临时译文,句子结束后再校正;原文与译文则各自监控,不因为一路停了就隐藏另一路。

最初我也很想把问题简单地归给模型:换一个更强的 GPT,是不是又快又准?实际代码和测试不支持这个结论。此时默认的实时译文是 gpt-realtime-translate,原文转写是 gpt-realtime-whisper,整句精修则交给 gpt-5。它们回答的不是同一个问题;把精档文本模型塞进最前面,可能只会让第一行字幕更晚。

降低等待:临时译文先显示,整句随后校正#

日语还在说时,实时链路先返回译文 delta。它的好处是快,代价是句子没有结束,后半句可能改变前半句的意思。等一句话有了边界,我再拿完整原文、前文和术语表做整句精修,按同一段的身份回填。这里不是让“最终答案”覆盖陌生的一行,而是让读者看得出眼前这句从临时到稳定的过程。

这个分工经历过反复。早期一段 31 秒的音频只有两处自然停顿,切分器却切出了 80 个片段。字幕看起来很“实时”,实际阅读却要不停拼接碎句。我改过分句、整句合并和段落配对;又发现原文、译文两条流节奏不同,不能按第 N 个片段硬凑一对。一次尝试用两条实时会话同时做双向翻译,10 秒中文测试里的 21 个片段出现错位和中日混杂,最后废掉这条方案,反向翻译改为句子结束后按段落回填。它比双流“同时动”慢一拍,却不把两个人的句子拼错。

同一句话,两种时钟 还在说:流式译文先给可读的临时字幕 句子结束确认这一段的边界 整句精修前文、术语、段落身份 速度指标:第一句何时出现  质量指标:完整句是否对齐、是否保留原意 二者分开测,不能用“模型更强”同时替代。
按实际字幕管线重绘。临时译文和整句精修是不同阶段,不是同一份结果等一会儿自动变准。

排查断流:48 秒重放里原文只走了 7.3 秒#

8 月 31 日那次重放直接暴露了显示问题。我拿本机一段 48 秒的难音频按真实节奏重放。译文持续回到第 43.9 秒,原文却在第 7.3 秒后停更。连接始终在,屏幕后面的字幕却空了:显示逻辑把“有原文”设成“可以显示译文”的前提。模型其实已经交出中文,我的 UI 把它藏掉了。

同一段录音观测到的事实该怎么呈现
原文流第 7.3 秒后不再更新明确标记原文缺失,检查这一路的健康
译文流一直返回到第 43.9 秒继续显示现有译文,不跟着原文一起消失
连接始终未断不能用“socket 在线”代替两条流都正常

我发现还不止一处问题。为了帮助识别,我曾向实时接口加过识别语言和术语提示;探针才证明这个 endpoint 不接受那两个设置,遇到未知字段会拒绝整条配置。原来所谓“识别模型突然不说话”,一部分是我把它配坏了。修掉设置后,默认的快速转写模型在这段高重复音频上仍可能无声停住:它在干净合成语音上首字约 1.9 秒,另一个文件转写模型约 5.8 秒;但在这段难音频里,前者很快停了,后者能覆盖全段。快模型适合开场,不能保证每一场都能跑完。

于是我让原文和译文各记自己的最后更新时间:译文仍在、原文长时间没来,才有理由判原文流坏了;两边都没有,可能只是现场安静。确认原文断流时,先显示已有译文,并尝试切换原文转写模型。这个决定也有代价:恢复后的原文可能晚到、与译文并非字字对齐,所以界面不能把两路写成“已经精确配对”。

连接没断,两条字幕流却不是一起活着 原文7.3 秒后停更 译文43.9 秒 0 秒48 秒
依据去掉谈话内容的事件时间线重绘;不是录音或产品界面的原始截图。

这次重放证明了配置错误、两路健康判断和显示规则之间的关系,也让后面约 25 秒本来被压住的译文能出现。它不证明以后每场真人面试都不会断流。对我来说,下一步该量的是首行出现时间、整句稳定时间、原文覆盖率和错译率,而不是挑一个“最强模型”名字贴到设置页上。官方的 Realtime translation 指南也把字幕时机、延迟与术语准确度分开作为测试维度;在我的软件里,这些还得用自己的音频和界面反复核对。

证据出处:8 月 2 日整句精修、双会话失败与段落回填的提交;8 月 31 日 PR #5、docs/REALTIME_ENDPOINT.md 的 48 秒真实音频探针和 Tests/SourceStreamOutageTests.swift。这篇的第 7.3 / 43.9 秒来自重放记录,不能读成普遍延迟指标。