超越全双工:把语音智能体理解为事件循环

几个月的语音智能体实践,如何改变了我对持续交互、任务委派、harness 与产品数据的理解。

On this page

几个月前,我觉得全双工语音建模最核心的问题是时机:语音持续流入模型,模型学习在合适的时间调用一个函数——回复用户。

This post is also available in English.

现在回头看,这个理解并不完整。

一个真正有用的语音智能体,不只是决定什么时候开口。它需要在任务运行时继续倾听,接收之前发起的任务结果,处理用户的打断和修正,并且不断决定应该说话、行动、委派、等待,还是进一步澄清。它接收的不只是音频 token,还有来自外部世界的异步事件。

做了几个月这样的系统之后,我越来越觉得,第一优先级的问题往往不是模型架构或者优化算法,而是我们究竟要在哪个环境里优化它。没有具体的产品,就很难定义正确的行为、搭建真实的 harness,也很难生产模型真正需要学习的数据。

共享 Workspace 里的 Co-worker

想象一下,我正在和一个语音智能体共同撰写一份设计文档。我们共享同一个 workspace:它能看到我正在读的段落、刚刚选中的内容、我手动做出的修改,以及后台仍在运行的任务。

我说:

这段开头还是有点抽象。我想表达的不只是模型能同时听和说,而是它在做事情的时候,我仍然可以改变它的方向。

这不是一条干净、明确的命令。我可能只是在思考,也可能希望它重写这一段,或者邀请它和我继续讨论。智能体需要推断我的隐含意图,但不能把每一个想法都当作行动授权。

它可以先简短回应:

对,真正重要的是执行过程中的可引导性。我可以围绕这个区别重写这一段。

如果我同意,它就可以修改文档。同时,它可能把查找案例或设计配图这样的长任务委派到后台。如果我随后打断它,说“不要只围绕打断来写,delegation 同样重要”,它就应该更新文档、调整正在运行的任务,并确保旧结果不会在稍后回来时覆盖新的方向。

这就是我设想的产品形态:不是给 chatbot 加一个语音入口,而是一个工作在共享 workspace 里的 voice-native co-worker。这个 workspace 可以是文档、代码库、画布,也可以是任何让想法持续存在并能够转化为行动的环境。

Audio 是一条无限延伸的流

全双工首先建立在 always-on 的假设上。在一次主动开启的工作会话中,音频会持续进入。输入可能是语音、沉默、犹豫、背景噪声、另一个说话人,也可能是用户的突然打断。它不会等待一个干净的轮次边界。

因此,模型实际上是在一条近似无限延伸的时间线上持续感知和行动。即使没有工具,这也并不简单。模型需要判断用户是否说完,区分打断和简单的附和,忽略无关噪声,识别说话人,并在合适的时间给出长度恰当的回应。

持续输入的音频时间线,以及语音智能体在时间线上发出和接收的离散事件
音频流不会停下来等待某个动作完成。语音、短程 function call、委派任务、steering 和异步返回,都被编排在同一条持续推进的时间线上。

现在的实时语音系统已经能展示不少这样的能力,但要让它们稳定可靠,仍然有很长的距离。最后一公里包括对话节奏、个性化以及与个人偏好的对齐:什么时候应该简短,什么时候应该展开,什么时候可以主动,什么时候最好保持安静。

这些问题很重要,但不是本文的重点。这里更有用的抽象是:模型持续接收 observation,并持续选择 action。语音是其中一种观察通道,说话是其中一种行动。当智能体接入 workspace 后,它所感知和影响的对象都不再只有对话。

从一个回复函数到完整的 Action Space

在真正开始做语音智能体之前,我无形中把 assistant 理解成只有一个函数:

respond_to_user()

全双工建模让这个函数的触发方式变得更灵活。它可以在用户完整提出问题后调用,也可以在用户犹豫时提供简短反馈,或者在模型判断主动回应有帮助时介入。但从根本上说,它仍然是一个对话系统。

Workspace 会改变它的 action space:

speak()
inspect_workspace()
edit_document()
call_tool()
delegate_task()
steer_task()
cancel_task()
wait()

用户仍然是环境中最重要的部分,却不再是唯一的部分。智能体还会和文档、代码、工具、API 以及被委派的 worker 发生交互。每次交互都会产生新的事件,而这些事件可能在用户继续说话或者智能体执行其他任务时返回。

甚至 speak() 也更适合被理解成一个持续运行的 activity,而不是一次已经完成的 response。语音可以在完整答案生成前开始,也可以被打断、缩短或者改变方向。它会改变用户对系统状态的认识,也会创造让用户修正系统的机会。

语音和 agency 正是在这里开始汇合。智能体不是轮流进行“对话”和“工作”,而是在工作进行时继续沟通,并且在整个过程中保持可引导。

三个并行的循环

对于 workspace co-worker,我倾向于把系统理解成三个运行在不同时间尺度上的循环。

Conversation loop 负责倾听、简短确认、澄清、轮次控制和打断。它需要给人即时的感觉。

Workspace loop 读取当前 artifact 并进行局部操作,例如打开文件、查看选中内容、修改段落或者展示 diff。这些操作通常需要足够快,才能继续属于实时交互的一部分。

Delegation loop 处理可能需要几秒到几分钟的工作,例如调研问题、运行代码、完成较大的实现或者和另一个系统协作。这些 activity 需要明确的身份和状态:运行中、被阻塞、已完成、失败、被调整或者被取消。

它们之间的区别不只是延迟。一个很快的操作也可能产生不可逆的外部影响,而一个缓慢的任务反而可能容易预览和撤销。真正重要的是 action contract:需要多长时间、能否被打断、执行中能否被修改、是否能展示中间进度,以及用户意图改变后应该发生什么。

一个可靠的 harness 必须协调这三个循环。当委派任务仍在运行时,智能体应该继续倾听;当智能体正在说话时,工具结果可能返回;当文档修改正在生成时,用户可能手动改动同一个段落。系统需要协调这些事件,同时不丢失对话脉络,也不破坏 workspace 的一致性。

持续音频、智能体语音、workspace 事件和可中断委派任务并行运行的语音智能体时间线
将全双工 agency 理解成并行事件流:workspace 操作和委派任务在后台发起、返回、改变方向或取消时,对话始终保持在线。

语音智能体是一套事件循环

这带来了我现在更认同的 mental model:语音智能体是一套 always-on event loop。

Audio 提供了主要时间轴,但其他事件可以在任何时间进入:

audio chunk
user interruption
workspace update
tool result
delegated-task progress
task completion
task failure

智能体也可能在先前任务尚未完成时,继续发起新的 activity。它们的返回顺序可能与发出顺序不同。一个结果可能对应很久以前的请求,也可能因为用户已经改变方向而变得过时。

因此,真正的挑战不只是 function calling,而是在多个异步事件流之间维持因果关系和对话的一致性。

模型需要理解自己请求了什么、当前事件属于哪个任务、任务是否仍然有效,以及新信息应该怎样改变 workspace 和当前对话。有时应该立即展示结果,有时一句进度更新就足够了,有时则应该安静地更新状态,等待更合适的时机。

这也是 implied intent 如此重要的原因。推断用户可能需要什么,并不等于获得了行动许可。是否行动应该取决于置信度、成本、可逆性和用户偏好。一个低风险的草稿可以主动准备;发送消息或者进行不可逆修改,则需要更明确的确认。

合理的主动程度无法在抽象环境里定义,它取决于具体产品,也取决于使用产品的人。

Harness 产生数据

这是过去几个月里,我思考方式上最大的变化。

实时交互、工具使用和 delegation 都有多种可行的技术方案。如果有足够多且足够真实的数据,其中不少方案都可能达到不错的基础效果。更困难的问题是如何创造这些数据。

有价值的训练样本不只是用户语音和智能体回复的配对。它还包括 workspace 状态、正在运行的任务、中间结果、打断、修正、延迟、失败,以及会对真实世界产生影响的操作。模型需要经历这样的情况:用户在一句话中途改变方向,被取消的任务仍然返回,两个 delegate 给出相互冲突的结果,或者一个看似有帮助的主动行为实际上并不受欢迎。

合成数据可以覆盖其中一部分,但事件分布最终来自产品。文档 co-worker、coding agent 和通用桌面助手会暴露不同的状态、允许不同的操作,也需要不同程度的主动性。它们需要不同的 harness,因此也会产生不同的学习问题。

这个关系是一套闭环。产品场景塑造 production harness;harness 产生真实交互和失败案例;这些经历转化成训练数据和模型行为。用户反馈随后会同时关闭两个循环:一方面,它会告诉我们产品和 harness 应该怎样改变;另一方面,它也会指出模型的哪些行为需要加强、纠正或重新评估。

连接产品场景、production harness、交互与失败、训练数据、模型行为和用户反馈的产品开发闭环
产品开发不是一条单向的数据流水线。用户反馈既会更新产品环境,也会修正模型行为,从而产生下一轮交互和数据。

Harness 不只是模型被部署的地方,也是数据生成器。

搭建真实 harness 的过程,常常是一些不够光鲜的工程工作:追踪任务状态、处理竞争条件、定义取消语义、保护用户编辑,以及从局部失败中恢复。但如果缺少这些工作,模型面对的就是一个虚假的世界,而我们评估的行为也未必在真实使用中重要。

这就是为什么找到一个具体场景,可能比选择训练算法更重要。产品定义了什么才是好的行为。

从执行者到 Co-worker

可靠的编排仍然只是基础。

我最终想要的 co-worker,不应该只是一个接受命令并返回 artifact 的执行者。它应该能帮助我思考。这个区别在长时间协作中尤其明显。

假设我们已经花了一个小时讨论某个设计。我曾经考虑过一种方案,但因为延迟限制而放弃。后来,一个委派任务返回了新的证据,改变了那个限制条件。执行者只会报告结果;co-worker 则应该知道这个结果为什么重要:它让之前被放弃的方案重新与现在的决策产生了联系。它可能会说:“这个结果改变了我们之前放弃 streaming design 时的延迟假设,要不要重新考虑一下?”

再比如,当多个任务正在后台运行,而我正专注写作时,我不希望每一个中间结果都变成通知。我希望智能体保护我的注意力,把相关更新合并起来,只在某个结果阻塞当前计划或者产生重要选择时打断我。正确行为取决于我正在做什么、结果有多紧急,以及我习惯怎样工作。

这些例子需要的不只是更长的 context window。智能体需要对 workspace 有结构化理解:当前有哪些决策、为什么做出这些决策、哪些任务依赖它们,以及用户现在正关注什么。它还需要判断主动性的边界。记住所有事情没有意义,如果它总是在错误的时间想起错误的内容。

这会带来第二层困难的问题:context management、memory、personalization,以及和人类偏好的对齐。一个有用的 co-worker 不仅要理解当前请求,还要理解用户的目标、工作方式和期待的主动程度。在 coding session 中正确的行为,放到 planning discussion 里可能就是错误的;一个人觉得贴心的主动行为,另一个人可能觉得冒犯。

我不认为这些问题能在产品出现前被完整回答。“更加主动”本身并不是一个有效目标。在共享文档里,主动可能意味着安静地准备一份可撤销的草稿;在 coding workspace 里,可能意味着编辑后运行一个相关测试。但发送消息、改变部署状态或者调整一个长期任务,都应该有不同的授权边界。

我们需要观察用户在什么地方欢迎帮助、在什么地方希望保持控制,以及主动行为在什么时候开始打扰工作。Personalization 不是一个可以独立附加在交互设计上的功能;它来自用户、智能体和共享环境之间具体而长期的关系。

模型不是第一个问题

刚开始这项工作时,我问的是怎样做出一个更好的全双工模型。现在我觉得,这个问题问得太早了。

一开始,人很自然地会关注那些最容易描述的技术选择:audio 和 text 应该怎样排布,模型应该在什么时机输出,应该使用哪种优化方法,以及怎样进一步降低延迟。这些方向上的进展都是真实的,却不会自动产生一个令人信服的 co-worker。

一些最明显的失败其实发生在模型上面一层。任务本身正确完成了,但它返回时用户早已改变方向;智能体给出了很好的回答,却在用户试图打断时说得太长;delegate 已经取得进展,但主智能体不知道这个更新是否值得打扰用户;一次局部文档修改看起来合理,却违背了二十分钟前做出的决定。

我们很容易把这些全部归类为模型问题。有时它们确实是。但更多时候,系统从未获得清晰的 task contract、可靠的 workspace 状态,或者能够展示理想行为的训练样本。在环境仍然没有定义清楚时继续优化模型,只是在围绕一个模糊目标做局部提升。

因此,第一个问题应该是我们希望实现怎样的协作。对于 workspace co-worker,成功不只是回答质量,而是用户能否保持专注、低成本地改变任务方向、理解系统正在发生什么,并且相信共享 artifact 仍然体现自己的意图。这些产品层面的结果会告诉我们应该暴露哪些 action、保留哪些事件、harness 需要提供什么保证,以及模型究竟应该学习什么。

这是一套循环,而不是固定的流水线。用户反馈可能说明某种行为需要更好的训练,也可能说明产品场景本身设计错了:智能体获得了过多权限,workspace 暴露的上下文不够,或者交互在错误的时机要求确认。下一代模型和下一版产品应该一起被设计。

模型当然仍然重要。对话质量、低延迟、长上下文理解,以及稳定处理异步事件,都是困难的技术问题。但当它们与真实环境和真实用户需求连接起来后,我们才能更清楚地理解和解决这些问题。

对我来说,这就是过去几个月最重要的体会:通往更好语音智能体的路径,可能不是从一个新模型开始,而是从一个值得与它共享的 workspace 开始。