Heartbeat Thinking: Speculative Reasoning and Tool Execution While Listening in Realtime Voice Agents
Zhenyu Zhang, Kewei Fu, Yongqi Tong, Chenzhi Zheng, Wei Wu, Jiang-Ming Yang, Jianshe Li
cs.CL
2026-10-19
蚂蚁国际的 Heartbeat 在用户说话时让进行中的推理和工具调用跑完。FDBench v3 投机覆盖从 34.67% 升到 50.67%,最终回复延迟从 6.90 秒降到 4.39 秒。
带工具的语音 agent 常常等用户说完才开工。订单号、预算这些能动手的信息,前半句往往就有了。等说完再推理和调工具的级联管线,仍要等 VAD(语音活动检测,判断这句有没有说完)触发,再串行推理、调工具、合成语音。用户感到的空白,落在话说完之后。
SHANKS 把推理前移,生成却被语音块截断,工具参数可能写不完。SIA 遇到新事件就打断正在生成的内容,调用没发出去就白做。更新越勤,能一口气写完一次调用的时间越短。提前做完也不自动能用:后补的预算会让早先的搜索作废。
Heartbeat Thinking 来自蚂蚁国际。新语音不打断已在跑的计算,只交给下一次 Thinker。说完后,Responder 用交接时已完成的准备回答整句。两个角色可以是不同模型。主实验 Thinker 为 Qwen3.6-35B-A3B,Responder 为 DeepSeek-V4-Flash。
节拍固定:每 500 毫秒尝试启动一次,最多 2 路同时跑,槽满则跳过、不排队。每次只读启动瞬间的部分转写、本轮已完成的推理,和当时已返回的工具结果。一个 Thinker 把参数写完,另一个消化刚到的半句。
Thinker 可以 noop(眼下无新动作),可以只记推理,也可以发出结构化工具请求。推理写入共享记录后再异步调工具,模型和工具在时间上重叠。提示词不许用相同工具名和完整参数重复已有调用。返回的结果用来补缺参、发下一步。转写没变,准备也能再走一层。
VAD 判定说完,新 Thinker 停止,未完成的投机任务连同排队一起取消。Responder 只收时刻 c 前的快照,更晚的结果丢弃。它按 ReAct(边推理边行动)核对整句:后文推翻的解释丢掉,名称和参数完全一致的结果复用,没结果的调用自己重发。因此不用等被取消的任务。
Window Thinking 沿用同一节拍,窗口结束后才到的输出直接丢弃,用来对照 SHANKS 式截断。Speech-to-Speech、Pipecat、LiveKit 等说完再做,投机覆盖按定义是 0。
SpeechFCEval 有 1914 条,评函数名和参数。FDBench v3 有 100 条录音、79 个场景、12 位说话人,评磕绊和改口。AudioCRAG 有 1312 条知识问答。STC(投机工具覆盖率)在前两个基准上,是参考调用里已做完、进入 Responder、且没被相同工具名和完整参数重做的比例。AudioCRAG 上则是复用投机检索、不再另检的样本比例。
| 方法 | SpeechFCEval 准确率 / STC | FDBench 质量 / Pass@1 / STC | AudioCRAG 正确率 / STC |
| Speech-to-Speech | 58.66 / 0 | 84.0 / 75.0 / 0 | 56.48 / 0 |
| Pipecat | 56.83 / 0 | 78.0 / 63.0 / 0 | 56.94 / 0 |
| LiveKit | 52.85 / 0 | 77.6 / 67.0 / 0 | 59.45 / 0 |
| Window Thinking | 67.95 / 33.13 | 72.0 / 57.0 / 34.67 | 57.24 / 20.05 |
| Heartbeat | 66.85 / 43.69 | 77.0 / 65.0 / 50.67 | 55.49 / 62.42 |
相对 Window Thinking,STC 高 10.56、16.00、42.37 个百分点。FDBench 质量从 72.0% 到 77.0%,Pass@1 从 57.0% 到 65.0%。这个 Pass@1 仍低于 Speech-to-Speech 的 75.0% 和 LiveKit 的 67.0%,高于 Pipecat 的 63.0%。质量 77.0% 低于三条级联基线(84.0%、78.0%、77.6%)。SpeechFCEval 准确率从 67.95% 降到 66.85%,仍高于三条级联。AudioCRAG 正确率从 57.24% 降到 55.49%,缺答率从 14.33% 升到 16.84%。覆盖上去了,任务分没有跟着涨。
FDBench 延迟相对语音结束,负值表示说完之前。这项测量关闭了两个模型的思考模式。
| 方法 | 正确工具调用发起 | 最终回复起点 |
| Heartbeat | -4.37 秒 | 4.39 秒 |
| Window Thinking | -2.74 秒 | 6.90 秒 |
| Pipecat | 2.45 秒 | 8.08 秒 |
| Speech-to-Speech | 2.72 秒 | 8.39 秒 |
| LiveKit | 3.52 秒 | 8.52 秒 |
终响从 6.90 秒降到 4.39 秒,少 36.4%,比最快的级联基线 Pipecat(8.08 秒)低 45.7%。匹配请求的第一次工具调用,Heartbeat 在说完前 4.37 秒发出,Window Thinking 在说完前 2.74 秒,级联基线在说完后 2.45 到 3.52 秒。
换 Responder,STC 优势还在,质量会反转。SpeechFCEval 上,Qwen3.8-Flash-Next 准确率 64.30%、STC 55.27%,高于 Window 的 57.14% 和 44.05%;Qwen3.5-397B-A17B 准确率 69.70% 对 67.27%,STC 只有 41.20% 对 32.49%。覆盖更高的那个,准确率更低。FDBench 上,后者的 Heartbeat Pass@1 为 61.0%,低于 Window 的 62.0%(STC 45.33% 对 34.67%)。
Thinker 换成 Qwen3.5-9B、GLM-4.7-Flash、Gemma-4-26B-A4B-it,覆盖都不是 0。Responder 仍为 DeepSeek-V4-Flash 时,Gemma 的 SpeechFCEval 准确率 68.58%,高于默认 Thinker 的 66.85%,STC 为 42.71% 对 43.69%。AudioCRAG 上 Gemma 复用率 74.70%,正确率 55.87%,仍低于 Window 的 57.24%。
FDBench 去掉首尾静音后,目标落在前 70% 的录音,说完前发出一致调用的占 73.3%;落在后 30% 的占 49.2%;明确改口后能修正的占 70.6%。另有 4.0% 参数正确,回答用了过时结果:50 美元预算没说完,已加购 99.99 美元咖啡机,后又搜到 40 美元商品,回答称加的是便宜的,总额仍报 99.99。后一次搜索撤不回已经执行的加购。
SpeechFCEval 五组里四组覆盖上升。Speech-BFCL 并行调用从 36.34% 到 58.03%,SmartInteract 从 40.57% 降到 38.32%。
说话的几秒可以变成已返回的工具结果。和语音块截断比,Heartbeat 多给的是写完参数的时间,以及不会被新语音取消的工具。Thinker 和 Responder 用外部记录交接,可以是不同模型。实验里边听是 Qwen3.6-35B-A3B,收口是 DeepSeek-V4-Flash。
这是调度上的改进。FDBench 终响 4.39 秒对 Window Thinking 的 6.90 秒,Pass@1 也更高。不投机的 Speech-to-Speech 仍是 75.0%,LiveKit 是 67.0%,Heartbeat 是 65.0%。调用发得早,终响就能压下来。答得对不对,看 Responder 怎么读那份快照。
500 毫秒、最多 2 路,长句会多次调用 Thinker,token 和 GPU 时间论文没给。加购、下单这种改外部状态的工具,投机阶段一旦成功,说完时取消未完成任务也撤不回。
论文承认三点。调度间隔和并发写死,不会看转写有没有新信息、工具有没有返回,安静片段会多跑推理。Responder 只拿交接瞬间的快照,更晚的工具结果进不了这一轮。延迟只测了 FDBench v3,没把覆盖、推理成本和终响在不同工具负载下的交换算清。
覆盖高,任务不一定更好。SpeechFCEval 和 AudioCRAG 相对 Window Thinking 都是降的。4.0% 的录音参数正确,回答却用了过时结果,加购也不能回滚。论文没有给出改提示或改交接之后的对照。
Window Thinking 是同一节拍下丢掉迟到输出,用来逼近 SHANKS 的截断,不是那篇系统的完整复现,也没有和 SIA、Stream RAG 的直接数字。FDBench 只有 100 条录音,Pass@1 从 57% 到 65% 的差距很薄。评委是开到最大推理力度的 DeepSeek-V4-Flash,与主 Responder 同族,对这种交接有没有偏向,文中没写。STC 把「做完」和「Responder 没有重调」绑在一起,多调一次,覆盖率就掉。