将 AI 头像引入语音代理

介绍与 Tavus 的集成

视频头像不再仅仅是噱头——它们已经成为开发人员和企业真正需要的有用工具。我们从客户那里听到了很多这样的反馈,尤其是在教育、医疗保健、心理健康和营销领域。每个人似乎都热衷于将他们的语音交互转化为更具视觉性和吸引力的东西。

为什么选择头像?

虽然语音是人类交流的主要媒介,但视觉线索也起着重要作用。面部表情、手势和眼神接触增加了上下文,有助于传达意图、情感和参与度。将 AI 语音代理集成到应用程序中时,添加视觉头像可以通过使交互感觉更自然和引人入胜来改善用户体验。

将头像集成到代理框架中

我们正在推出一种简单的方法,将 AI 头像添加到您的 LiveKit 代理中,首先支持 Tavus,Tavus 是实时 AI 头像模型的领先提供商。

该集成被设计为一个插件,它捕获代理的音频输出并将其转发给头像模型进行视频合成。这种方法最大限度地减少了样板代码,同时保留了对代理逻辑的完全控制。

您只需几行代码即可将 Tavus 头像附加到任何 LiveKit 代理。

  avatar = tavus.AvatarSession(
      replica_id="r4c41453d2", 
      persona_id="p2fbd605"
  )
  await avatar.start(session, room=ctx.room)

在前端,头像被发布到房间,就像 LiveKit 上的任何其他视频轨道一样。这意味着可以使用 LiveKit 的任何客户端 SDK 进行渲染。我们还在我们的语音 AI 入门应用中添加了对头像渲染的支持。下面是在同一 UI 中渲染代理头像或音频可视化器的完整代码示例

function AgentVisualizer() {
  const { state: agentState, videoTrack, audioTrack } = useVoiceAssistant();

  if (videoTrack) {
    return (
      <div className="h-[512px] w-[512px] rounded-lg overflow-hidden">
        <VideoTrack trackRef={videoTrack} />
      </div>
    );
  }
  return (
    <div className="h-[300px] w-full">
      <BarVisualizer
        state={agentState}
        barCount={5}
        trackRef={audioTrack}
        className="agent-visualizer"
        options={{ minHeight: 24 }}
      />
    </div>
  );
}

幕后原理

头像生成引入了额外的处理,因此我们在设计系统时非常注重最小化延迟。即使是很小的延迟也会扰乱对话的自然流程。为了减少开销,我们应用了多项优化——其中一些利用了 LiveKit 的独特功能。

远程生成

大多数头像模型需要专用的 GPU,并且通常在与代理代码分离的机器上运行。为了支持这一点,头像系统旨在将视频合成卸载到远程服务器。

一个简单的实现可能会遵循以下工作流程

  1. 捕获代理的音频输出并通过 websocket 发送到远程服务器
  2. 从远程服务器接收生成的视频
  3. 通过 WebRTC 发布音频和视频

在此设置中,步骤 2 成为瓶颈,原因有二

  • 延迟增加:等待接收视频帧后再重新发布会引入延迟。
  • 额外的编码开销:通过网络传输视频需要编码和解码,这会进一步增加延迟并可能降低质量。

为了避免产生额外的延迟,我们采用了更有效的方法

  1. 头像生成服务器作为参与者加入同一个房间
  2. 代理通过 ByteStream 将音频输出发送到生成服务器
  3. 生成服务器将同步的音频和视频直接发布到房间中

此设置避免了冗余编码和传输延迟,同时保持了实时性能和质量。

处理中断

中断处理在会话式 AI 中至关重要。用户可以随时打断代理——提出问题、改变话题或澄清某事。LiveKit 代理原生支持中断,但引入远程头像服务器会增加复杂性:服务器如何检测中断,以及当需要丢弃预合成的帧时,它如何保持流畅的播放?

为了解决这个问题,我们使用 LiveKit 的 RPC 系统,该系统允许参与者在房间中调用其他参与者的远程函数。这使得代理能够实时通知头像服务器中断事件,以便它可以根据需要取消或调整正在进行的视频合成。

当头像服务器接收到中断事件时,它会丢弃任何预合成的帧,并开始生成反映头像正在聆听状态的新帧。这种转换必须精确计时,以避免明显的故障或卡顿的视频播放。

协调播放状态

在基于语音的交互中,代理知道响应是否已完全被听到非常重要。与文本不同,文本内容会立即交付且不会被中断,音频播放是实时发生的——使得计时成为对话流程的关键部分。播放完成还标志着内容何时应该提交给聊天上下文。

为了保持与我们的 SpeechHandle API 的兼容性——该 API 允许代理等待音频播放——我们需要跟踪远程合成服务器何时完成播放。

为此,我们再次使用 LiveKit 的 RPC 系统——这次是反向的。当播放完成时,头像服务器会向代理发送一个 RPC。代理接收此信号并使用它相应地解析内部状态和 API。

总结

向 LiveKit 代理添加头像支持带来了独特的挑战,尤其是在延迟、中断和同步方面。我们非常愉快地构建了这种集成来为您处理这些复杂性,从而使创建响应迅速的实时头像体验变得更加容易。

使用 Tavus 试一试,让我们知道它在您的用例中效果如何!