For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主要導覽
2026年3月25日 音訊

Perplexity 如何運用 Realtime API,讓數百萬人使用語音搜尋

運用 Realtime API 打造 Perplexity Computer 語音智慧體的經驗分享。

作者: Paul Fryzel (Perplexity), Charu Jaiswal (OpenAI)

Perplexity 如何運用 Realtime API,讓數百萬人使用語音搜尋

在 Perplexity,我們非常重視打造令人愛不釋手的產品。對我們的智慧體式瀏覽器 Perplexity Comet,以及功能強大的通用數位工作者 Perplexity Computer 而言,實現這個目標的一大關鍵,就是讓使用者能完全透過語音操作。只要說出需求、交付任務,就能看著它開始執行,這種體驗帶來了獨特的滿足感。我們看好語音介面的潛力,因為它讓實際互動多了一點魔法般的感受。

我們在正式環境中採用 Realtime-1.5,將這種魔法帶入 Perplexity 每月處理的數百萬次語音工作階段。看著 Computer 介面上的語音使用量成長,令我們非常興奮,也學到了很多。接下來,我們會分享至今幾個意想不到的收穫。也歡迎你試用 Realtime-1.5,並與我們分享你的心得。

1. 確立上下文管理策略

長篇內容,尤其是資訊密集、長達數小時的 Podcast,是最能明確考驗上下文管理的情境之一。我們希望使用者能透過語音查詢 Podcast 逐字稿,隨時提問,例如詢問節目進行到兩個半小時時某個時間點的內容,並獲得條理清楚的回答。

上下文無法容納整份逐字稿。我們最初嘗試將它切成大區塊傳送,但很快就發現,大區塊更新一旦失敗,就會一次丟失所有先前內容。假設上下文視窗只剩下 5,000 個 Token 的空間,卻試圖送入 10,000 個 Token 的更新,模型就會失去所有先前的歷史內容。因此,大區塊的風險高得多:單次過大的更新就可能清掉整塊上下文,無法讓系統逐步捨棄舊內容。

於是我們改變了做法,不再一次送入大量更新,而是將所有內容切成小得多、每塊 2,000 個 Token 的區塊,再逐步送入。這增加了處理開銷,卻讓系統的行為穩定得多。即使發生截斷,也只會刪去少量歷史內容,不會一次清空全部。

我們還學到一個微妙的細節:並非所有上下文都應以相同方式送入模型。使用 conversation.item.create 更新上下文時,item.type: "message" 有三種角色:systemuserassistant。這些角色會告訴模型它看到的是哪一類訊息。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 模型,以及它們將帶來的全新語音體驗做好準備。