跳到正文

Perplexity 如何借助 Realtime API 将语音搜索带给数百万用户

本文目录文章开头

在 Perplexity,我们非常注重打造使用体验出色的产品。对于我们的智能体浏览器 Perplexity Comet,以及强大的通用数字工作者 Perplexity Computer,其中很重要的一点就是让它们完全支持语音操作。只需说出你的需求,交出任务,然后看着它完成——这种体验有一种独特的满足感。我们非常看好语音作为交互界面,因为它让实际的交互感觉更接近魔法。

我们在生产环境中使用 Realtime-1.5,将这种魔法带给 Perplexity 每月管理的数百万次语音会话。看着 Computer 界面中语音功能的增长,既令人兴奋又富有启发性。我们将分享目前学到的一些令人惊讶的事情。我们鼓励你试用 Realtime-1.5,并把你的发现也分享给我们。

1. 制定你的上下文管理策略

长篇内容,尤其是信息密集的数小时播客,是我们最清晰的上下文管理测试之一。我们希望让播客的文字记录可以通过语音使用,这样用户就可以随时切入,询问两个半小时处的特定时刻发生了什么,并得到连贯的回答。

你无法把整个文字记录都塞进上下文。我们的第一种做法是分大块发送。我们很快发现,大块更新会以全有或全无的方式失败。如果你试图将一个 10,000 token 的更新发送到一个只剩 5,000 token 空间的窗口中,模型会丢失之前的所有历史。这使得大块更新风险高得多,因为一次过大的更新可能会抹掉整个上下文块,而不是让系统更优雅地遗忘。

所以我们改变了方法。我们不再进行大块更新,而是开始把所有内容拆分成更小的 2,000 token 块,并增量地喂给模型。这会带来更多的开销,但行为要稳定得多。当截断发生时,它只会修剪一点历史,而不是把所有内容都抹掉。

我们学到的另一个微妙之处是,并非所有上下文都应该以相同的方式进入模型。当使用 conversation.item.create 更新上下文时,item.type: "message" 有三个角色:system、user 和 assistant。这些角色告诉模型它看到的是哪种消息。system 用于指令和行为塑造,user 用于最终用户输入,assistant 用于模型生成的输出。

当我们弄错这一点时,交互开始感觉不对劲。如果太多上下文以 user 的形式进入,模型的行为就好像用户在朗读每一段文本,包括网页片段和评论,而不是简单地基于这些材料提出问题。如果太多以 system 的形式进入,情况则相反。模型会失去对它自身“知道”的内容、作为上下文提供的内容,以及用户当下实际询问内容之间的区分。

一个很好的例子是浏览流程。当用户滚动页面时,我们会持续用屏幕上的内容更新模型。如果所有这些都被框定为用户输入,模型就会开始表现得好像用户把每一段都大声说了出来。这不是正确的心智模型。我们希望系统感觉它在后台感知着页面,然后在用户提问时自然地回答。这最终与其说是关于原始上下文的量,不如说是关于让对话语义保持正确。

2. 在产品各处标准化音频体验

Perplexity 拥有多个产品界面,例如 Ask、Comet 和 Computer。每个界面都建立在不同的客户端技术栈之上。Swift、TypeScript、Rust 和 C++ 都可能产生不同的原生音频缓冲区。当我们让每个客户端向 Realtime API 发送其自身的原始或原生音频格式时,导致了性能上的不一致。

我们最终用 Rust 构建了一个 SDK,以抽象掉这些平台特定的差异,并确保每个客户端向 API 发送相同的音频契约。在实践中,这意味着在音频到达服务器之前就对其进行处理:重采样为 48 kHz 单声道,匹配 Opus 编解码器偏好和 WebRTC 的内部速率,通过 WebRTC APM 进行回声消除、自动增益控制、降噪和高通滤波,然后进行编码以便传输。该 SDK 让我们有一个统一的地方来标准化音频常量、重采样并设置完整的处理管道,而不是逐个客户端地进行这些操作。

3. 为复杂的环境进行调优

在用户所处的真实环境中调优 VAD 至关重要。这意味着要针对真实的麦克风、扬声器音量和背景噪音进行校准。我们内部的一个测试用例是旧金山一家嘈杂的酒吧,因为那感觉像是一个真实的产品场景。有人会说:“你试过新的 Perplexity 应用了吗?”他们的朋友拿出手机,如果语音功能失败,我们就失去了两个用户。当它奏效时,反应更接近于“我**”。这对我们来说是一个有用的推动因素。在干净条件下有效的东西,在现实世界中往往会失效。最好先为复杂的环境进行调优。

语音用户体验中最难的部分之一是把握好停顿。人们会自然地停下来思考、在屏幕上查找内容,或者准备朗读某些内容。模型很容易将这种停顿视为一轮对话的结束,并过早地插话。我们在一些案例中看到了这种情况,比如有人请求帮助进行数学推导。他们会停下来查找公式,结果模型在他们完成提问前就插话了。这促使我们推出了语音锁定功能。我们没有采用传统的按住说话方式(默认关闭语音,用户必须按下才能说话),而是将其反转。交互默认保持环境感知状态,但当用户想要暂时保持发言权时,他们可以锁定语音并接管这一轮对话。我们还认为这不仅仅是一个一次性功能。随着语音界面进入更复杂的工作流,我们相信这种交互模式的某种版本将成为标准。

4. 仅使用核心工具并保持其在分布内

将工具集缩小到最重要的少数工具,在我们的案例中意味着少于十个。我们专注于一个涵盖最高价值操作的小型核心工具集。这种权衡是合理的,并且随着新快照的改进,情况可能会变得更好。

我们在系统提示中添加了明确的指令,说明何时以及如何调用每个工具。我们小心地确保工具模式和输出都保持在模型的分布内。在实践中,这意味着将工具输出格式化为普通的结构化工具数据,而不是助手对话。我们返回字段清晰分隔的结构化 JSON,例如 response_text 用于面向用户的发言,以及像 require_repeat_verbatim 这样的行为标志,而不是将语音内容与内联指令混在一起。这使得工具使用更加稳定,并使交互模式更接近模型在训练期间可能见过的形式。

// Good:
{
  "response_text": "I kicked-off the task to create a market research dashboard",
  "require_repeat_verbatim": true
}
// Avoid:

I kicked-off the task to create a market research dashboard

# Response Instructions

Read the above instructions EXACTLY as they are

Realtime 已准备就绪

Realtime-1.5 是该行业的一个转折点。在处理长上下文、更多工具以及高智能任务方面,当然还有改进空间。但我们预计模型会变得更好。在 Perplexity,我们着眼于为那个未来在今天就做好构建。我们希望在为下一波 Realtime 模型及其将带来的全新语音体验做准备的同时,让今天的系统变得可用。

阅读显示设置

调整正文排版

当前浏览器记住选择,应用于文章正文。手机上正文宽度以屏幕可用空间为限。

图表完整性提示

普通文章遇到图表保存问题时显示提示。