![]()
一套讓服務(wù)器端程序偽裝成會(huì)議參與者的技術(shù)方案,正在讓實(shí)時(shí)語(yǔ)音轉(zhuǎn)寫(xiě)的接入成本從"造火箭"降級(jí)到"拼樂(lè)高"。Agora(聲網(wǎng))的Python Server SDK配合AssemblyAI Universal-3 Pro,用不到200行代碼就能實(shí)現(xiàn)多說(shuō)話人實(shí)時(shí)轉(zhuǎn)寫(xiě)——這個(gè)數(shù)字在三年前需要一支5人團(tuán)隊(duì)折騰一個(gè)季度。
核心突破在于PCM音頻流的"零摩擦"對(duì)接:Agora直接輸出16kHz單聲道原始音頻幀,恰好是AssemblyAI流式接口的輸入規(guī)格,中間不需要任何格式轉(zhuǎn)換或重采樣。
GitHub上的開(kāi)源實(shí)現(xiàn)(github.com/kelseyefoster/voice-agent-agora-universal-3-pro)把這個(gè)過(guò)程拆成了三步:克隆倉(cāng)庫(kù)、填環(huán)境變量、運(yùn)行bot.py。整個(gè)流程的復(fù)雜度,大概相當(dāng)于配置一個(gè)Slack機(jī)器人。
但別被簡(jiǎn)潔的表象騙了。這套方案背后藏著兩個(gè)關(guān)鍵設(shè)計(jì)決策,直接決定了它能不能在生產(chǎn)環(huán)境扛住壓力。
服務(wù)器端"幽靈":為什么不用客戶端SDK
Agora的Python Server SDK讓程序以CLIENT_ROLE_AUDIENCE身份加入頻道——這個(gè)角色的微妙之處在于,它既能訂閱所有參與者的音頻流,又不會(huì)出現(xiàn)在用戶的參會(huì)者列表里。
「沒(méi)有瀏覽器,沒(méi)有移動(dòng)端,沒(méi)有UI包袱。」一位用過(guò)類(lèi)似方案做會(huì)議助手的開(kāi)發(fā)者告訴我,「你的bot就是一個(gè)純后端服務(wù),崩潰重啟對(duì)用戶完全無(wú)感知。」
這個(gè)設(shè)計(jì)規(guī)避了傳統(tǒng)方案的兩個(gè)坑:一是客戶端SDK的兼容性問(wèn)題(不同瀏覽器對(duì)WebRTC的實(shí)現(xiàn)差異能折磨人一周),二是音頻采集的權(quán)限彈窗——在Chrome收緊自動(dòng)播放策略后,這幾乎是必踩的雷。
更隱蔽的好處是算力成本的重新分配。客戶端轉(zhuǎn)寫(xiě)需要把音頻數(shù)據(jù)先傳到服務(wù)器,服務(wù)器處理完再傳回結(jié)果,來(lái)回兩趟流量。而Agora的服務(wù)器端bot直接在云端訂閱音頻,轉(zhuǎn)寫(xiě)服務(wù)也在云端,數(shù)據(jù)鏈路縮短了一半。
代碼里的關(guān)鍵一行是set_playback_audio_frame_before_mixing_parameters,必須在subscribe_all_audio之前調(diào)用。這個(gè)順序要求曾讓早期測(cè)試者踩坑——調(diào)反了會(huì)導(dǎo)致Agora內(nèi)部重采樣,輸出變成48kHz,AssemblyAI直接報(bào)錯(cuò)。
Universal-3 Pro的"說(shuō)話人指紋":從轉(zhuǎn)文字到分角色
AssemblyAI這次開(kāi)放的u3-rt-pro模型,核心賣(mài)點(diǎn)不是準(zhǔn)確率(雖然官方稱(chēng)英語(yǔ)WER降到5%以下),而是format_turns參數(shù)開(kāi)啟后的說(shuō)話人切換檢測(cè)。
傳統(tǒng)流式轉(zhuǎn)寫(xiě)的輸出是一串連續(xù)文本,多人對(duì)話時(shí)你得自己猜"這句話是誰(shuí)說(shuō)的"。Universal-3 Pro會(huì)在WebSocket消息里帶上turn標(biāo)簽,標(biāo)記每段話的發(fā)言人邊界——相當(dāng)于給純文本打上了時(shí)間軸和角色I(xiàn)D。
這個(gè)能力對(duì)會(huì)議場(chǎng)景是剛需。想象一個(gè)銷(xiāo)售復(fù)盤(pán)會(huì):AI助手需要區(qū)分"客戶說(shuō)了什么"和"銷(xiāo)售怎么回應(yīng)",才能生成有用的跟進(jìn)建議。沒(méi)有說(shuō)話人分離的轉(zhuǎn)寫(xiě),后續(xù)的分析準(zhǔn)確率會(huì)直接腰斬。
技術(shù)實(shí)現(xiàn)上,Universal-3 Pro用了聲紋聚類(lèi)+上下文建模的混合方案。流式場(chǎng)景下不能等會(huì)議結(jié)束再全局優(yōu)化,所以模型必須在聽(tīng)到新音頻的同時(shí),實(shí)時(shí)判斷這是新說(shuō)話人還是之前出現(xiàn)過(guò)的某位。
Agora的bot架構(gòu)恰好配合了這個(gè)需求:每個(gè)參與者有獨(dú)立的uid,bot為每個(gè)uid開(kāi)一條獨(dú)立的WebSocket連接。這意味著AssemblyAI收到的音頻流天然是"單說(shuō)話人純凈版",不需要做復(fù)雜的聲源分離——又是一個(gè)零摩擦的對(duì)接點(diǎn)。
代碼里的stream_participant函數(shù)是并發(fā)設(shè)計(jì)的:每個(gè)參會(huì)者一個(gè)異步任務(wù),互不影響。10人會(huì)議就是10條WebSocket并行,CPU瓶頸在AssemblyAI的API端,不在你的bot這邊。
生產(chǎn)環(huán)境的三個(gè)隱藏開(kāi)關(guān)
開(kāi)源代碼為了演示清晰,省略了不少運(yùn)維細(xì)節(jié)。如果你打算把這個(gè)bot丟進(jìn)生產(chǎn)環(huán)境,有三個(gè)參數(shù)需要重新考慮。
第一個(gè)是AGORA_BOT_UID的取值。示例用了9999,但Agora的uid是32位無(wú)符號(hào)整數(shù),理論上1到2^32-1都合法。建議用隨機(jī)數(shù)或者哈希生成,避免和真實(shí)用戶的uid沖突——曾有團(tuán)隊(duì)因?yàn)楣潭ㄓ?0000,結(jié)果和某個(gè)客戶的測(cè)試賬號(hào)撞車(chē),音頻流串了。
第二個(gè)是token的刷新策略。Agora的RTC token默認(rèn)24小時(shí)過(guò)期,但長(zhǎng)時(shí)間運(yùn)行的會(huì)議助手可能需要更長(zhǎng)的生命周期。代碼里用的是一次性token,生產(chǎn)環(huán)境應(yīng)該接入Agora的Token Builder服務(wù),實(shí)現(xiàn)自動(dòng)續(xù)期。
第三個(gè)是音頻幀的緩沖控制。Agora的SDK默認(rèn)會(huì)緩沖幾百毫秒的音頻以保證流暢性,但實(shí)時(shí)轉(zhuǎn)寫(xiě)對(duì)延遲敏感。可以通過(guò)set_audio_frame_parameters調(diào)整緩沖深度,代價(jià)是弱網(wǎng)環(huán)境下的音頻質(zhì)量波動(dòng)。
「我們測(cè)試過(guò),緩沖從默認(rèn)的200ms降到50ms,端到端延遲從800ms降到400ms,但丟包率超過(guò)3%時(shí)會(huì)出現(xiàn)斷續(xù)。」一位做遠(yuǎn)程面試系統(tǒng)的技術(shù)負(fù)責(zé)人分享了他的調(diào)參經(jīng)驗(yàn)。
成本賬:比自研便宜多少
算筆粗暴的賬。如果自研這套系統(tǒng),需要搞定:WebRTC服務(wù)器部署(至少2人月)、音頻編解碼優(yōu)化(1人月)、轉(zhuǎn)寫(xiě)模型微調(diào)或?qū)樱?人月)、說(shuō)話人分離算法(3人月)、高并發(fā)架構(gòu)(2人月)。按硅谷工程師成本,輕松燒掉30萬(wàn)美元。
Agora+AssemblyAI的方案,開(kāi)發(fā)成本壓縮到1人周以內(nèi)。運(yùn)行成本是Agora的音頻訂閱流量費(fèi)(約$0.99/千分鐘)加上AssemblyAI的流式轉(zhuǎn)寫(xiě)費(fèi)($0.37/小時(shí))。一場(chǎng)60分鐘的4人會(huì)議,總成本大概$0.15。
這個(gè)定價(jià)對(duì)SaaS廠商特別有殺傷力。假設(shè)你的會(huì)議助手產(chǎn)品月活用戶開(kāi)10萬(wàn)場(chǎng)會(huì),每場(chǎng)平均30分鐘3人,自研方案的攤銷(xiāo)成本可能還沒(méi)收回,Agora+AssemblyAI的賬單已經(jīng)能覆蓋運(yùn)營(yíng)費(fèi)用。
但便宜也有邊界。如果你的場(chǎng)景需要離線轉(zhuǎn)寫(xiě)(會(huì)議結(jié)束后再處理)、需要支持小語(yǔ)種(Universal-3 Pro目前強(qiáng)在英語(yǔ))、或者需要自定義詞匯(比如醫(yī)療術(shù)語(yǔ)),這套方案的靈活性就不夠用了。
AssemblyAI的文檔里埋了一個(gè)細(xì)節(jié):u3-rt-pro的format_turns在多人同時(shí)說(shuō)話時(shí)會(huì)有"粘連"現(xiàn)象——兩個(gè)聲音重疊的片段可能被歸為同一個(gè)turn。這對(duì)辯論場(chǎng)景是硬傷,但對(duì)一對(duì)一面試或銷(xiāo)售通話影響不大。
開(kāi)源倉(cāng)庫(kù)的issue區(qū)已經(jīng)有人提了PR,想加入VAD(語(yǔ)音活動(dòng)檢測(cè))前置過(guò)濾,避免靜音片段浪費(fèi)API調(diào)用。這個(gè)優(yōu)化能把成本再砍15%左右,但會(huì)引入額外的延遲——又是一個(gè)典型的工程權(quán)衡。
這套方案最有趣的地方,是它把"實(shí)時(shí)語(yǔ)音AI"這個(gè)曾經(jīng)的高門(mén)檻領(lǐng)域,變成了開(kāi)發(fā)者可以隨手試玩的積木。當(dāng)基礎(chǔ)設(shè)施足夠成熟時(shí),創(chuàng)新的瓶頸就從"能不能做"轉(zhuǎn)移到了"做什么有價(jià)值"。
下一個(gè)會(huì)冒出來(lái)的,是用這套架構(gòu)做的什么產(chǎn)品?自動(dòng)會(huì)議紀(jì)要已經(jīng)卷成紅海,實(shí)時(shí)銷(xiāo)售教練、無(wú)障礙通話助手、甚至游戲里的NPC語(yǔ)音交互——哪個(gè)場(chǎng)景會(huì)先跑出來(lái)?
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.