ENZH
和 AI 讨论这篇文章
ChatGPTClaude

给 Mio 选语音方案,最后定了 Hume EVI

📊 幻灯片

声音承载情感色彩的概念插画声音承载情感色彩的概念插画

第一篇里讲了 Mio v2 的那个转向:把物理形象剥掉,只留人格,一个伴侣而不是一群,一团光球而不是假人脸,人格从对话里长出来,不靠预写的角色卡。方向定了之后,下一件要解决的事就是声音——这个东西得开口说话,而且说出来得带感情。这篇具体讲讲我们是怎么选方案的。

先说之前的状态。v0.1.0 的时候 Mio 就会说话了:用 Fish Audio 的 S1 模型给每个角色克隆声音,听感温暖又自然,成本也极低。什么时候发语音是 LLM 自己决定的,一般是情感浓度高的时刻,安慰、撒娇、说晚安这种,模型在回复里打一个 [VOICE] 标记,后台去触发 TTS。

这套体验本身是成立的,用户能听到一个好像很在乎他们的声音。但用久了问题很明显:这个声音本身没有任何感情。Fish Audio 干的事就是读字、出音频,它不知道这段文字是开心的、难过的、讽刺的还是心碎的,所以每条消息的情绪基调都差不多,好听、中性、清晰。Mio 说「太替你高兴了!」和「真的很心疼你」,听起来是一样的。文字聊天你可以容忍情绪平淡,一个会开口说话的东西不行。

TTS 为什么念不出感情

传统 TTS 是条流水线,文字进去、音频出来。你想要感情,就得自己标:SSML 标签、style 参数,或者显式写一句「这句用悲伤的语气念」。做有声书、导航播报,这够用了。但一个每天生成上千条消息的伴侣呢?每条消息都有自己的情感语境,你不可能一条一条去标,TTS 系统自己又对语境一无所知。

2025 到 2026 年这块有个挺重要的变化:几家开始把情绪推断直接做进模型里。TTS 不只是念字了,它先理解这段文字在讲什么,再决定怎么念。做得最突出的两家正好互补,一家中文一家英文。

中文:豆包 TTS 2.0

字节(火山引擎)的豆包 TTS 2.0,升级点就是从「读字」变成「理解之后再表达」:拿大模型去分析对话的 context,自动推断该用什么情感、语调、节奏,不用你手动标。技术上他们管这个叫「3D 情绪空间」,强度、语义适配、生理特征三个维度,用 2000 小时专业配音数据训出来的。实际效果就是,你把「别担心,有我在呢」送进去,出来的语音是真的在安慰人:更柔、更暖、节奏微微放慢,你什么都不用指定。想精细控制也可以,比如「这句要压着哭腔说」,但那是可选项,自动推断在中文场景下 90% 以上的情况都能处理好。

英文:Hume AI Octave

Hume 的 Octave 从另一个角度解决同一个问题。它没走「标注情感语音数据拿去训练」那条路,直接建在一个真正会「读」文本的 LLM 上面,反讽、双关、情绪转折、言外之意它都懂。所以它更像一个有功力的配音演员,先理解再去念,而不是先跑个情感分析、再映射到几个预设情绪上。差别体现在微妙的地方:「Sure, I'd love to」这句话可以是热情也可以是讽刺,全看 context,Octave 能判断对,因为它理解的是整段对话,不是孤立的一句。

这两家都是非实时 TTS:文字进、音频出,延迟大概 200ms,正好接在 v0.1-0.2 的语音消息模式上,伴侣先生成文字,再把它说出来。STT 那边没什么可换的,gpt-4o-mini-transcribe 从 v1 一直用到现在,准、快、便宜,早就集成好了。

从语音消息到实时对话

语音消息只是个过渡形态。情感 AI 伴侣的最终形态肯定是实时语音对话:你说,它听,它回应,可以打断,可以接话,整个流畅度接近跟真人打电话。这是 v1.0 的目标,也是架构决策真正开始变难的地方。

最朴素的做法是把现有的东西串起来:STT 把你的语音转成文字,服务器查记忆、构建 context,LLM 生成回复,TTS 再转回音频。四步串行,延迟叠上去就是 1-3 秒,文字聊天里 1-3 秒没什么感觉,口语对话里 3 秒的沉默是很难受的。而且这条流水线还有几个问题压根没碰:轮次检测,怎么知道你说完了没;打断处理,它回复到一半你插话进去怎么办;情绪感知,你语气里带的信息,转成纯文字之后全丢了。所以实时语音平台我们认真评估了三个,对比下来结论挺清楚的。

三方对比

维度Hume EVI 3OpenAI Realtime API豆包 Realtime
自定义 LLM支持——gemini、claude、任意不支持——只能用 gpt不支持——只能用豆包大模型
语音情感表达业界最强,一等公民弱——官方称"future improvement"好——3D 情绪空间
用户情绪识别支持——从语调分析有限支持
System prompt / context 注入完全支持支持不支持——黑盒
工具调用支持——可调你的 API支持不支持
打断处理支持——基于语调轮次检测支持支持
延迟约 500ms 首字节约 300ms约 700ms
价格按分钟计费 (Pro)按分钟计费 (audio)待定

表格说了大半,但有一个点得单独拎出来:OpenAI Realtime 和豆包 Realtime 是同一个致命问题,不能用你自己的 LLM。 OpenAI 锁死 gpt,豆包锁死自家大模型。做通用语音助手这无所谓,对 Mio 来说这就是死局。

原因具体是这样的:Mio 的核心差异化全在记忆、人格和情绪 context 上,这些东西活在我们服务器上,每次回复前要注入 LLM 的 context window。伴侣得知道你上周提过面试、最近一直挺焦虑、喜欢直说不喜欢绕弯子,这些 context 才是让它成为「你的伴侣」而不是「一个通用 AI」的东西。所以我们的要求很硬:对 system prompt 和 LLM 本身要有完全控制权。

豆包这边我们专门验证了三件事:支不支持自定义 system prompt,能不能动态注入 context,能不能换外部 LLM。答案分别是不支持、有限支持(只能塞 RAG 风格的知识片段,做不了行为指令)、不支持。等于一个说话很好听的黑盒,它只能是豆包,成不了你的伴侣。OpenAI Realtime 至少支持 system prompt,但锁死 gpt 意味着用不了 gemini(Mio 靠它的性价比)也用不了 claude,而且语音情感表达在官方口径里还是「future improvement」,对一个拿情感当卖点的产品来说,这不可接受。

最后选了 Hume EVI 3

整个架构一句话能讲清楚:LLM 决定说什么,Hume EVI 负责怎么说,有点像编剧和演员的分工。

LLM 当编剧决定说什么、Hume EVI 当演员决定怎么说的分工架构LLM 当编剧决定说什么、Hume EVI 当演员决定怎么说的分工架构

LLM 根据人格、记忆、情绪状态和对话历史生成回复文本,它对这个角色是谁、这个时刻需要什么理解最深,反正它不用管语音层的事,把内容写出来就行。Hume 管表达层的全部:听对方讲话(STT 加情绪分析),判断对方什么时候说完(轮次检测),用对的情感语调把回复念出来(Octave TTS),再处理各种意外,比如被打断、被抢话、回复还没回来先垫一句。具体一轮对话是这样跑的:

  1. 用户说话。 Hume 同时干三件事:把语音转成文字;分析用户语调里的情绪(「听起来用户很焦虑」);判断用户说完了没——不是傻等静音超时,是从语调本身理解对话的节拍。

  2. Hume 把结果送到我们服务器。 我们拿到用户文本加情绪分析,查记忆、构建 context、调 LLM(gemini 或 claude,随便换),返回回复文本。

  3. Hume 把回复说出来。 Octave 自动匹配情绪合成语音,音频流式返回。

这里面最妙的设计是填充词。Hume 内置了一个叫 eLLM 的快速轻量模型,200ms 内先给一个即时反应,「嗯…」「哦!」这种,把完整回复生成的那段空隙填掉,再无缝过渡到正式回复。用户感知到的延迟几乎是零,对话里不会出现几秒钟的干等。你想想真人是怎么接话的:没有人沉默三秒然后突然讲出一段完整的话,都是先「嗯…」一下,边想边说。Hume 复刻的就是这个模式:正式回复还没生成完,先用一个即时反应把话接上。

用户:"我没拿到那个 offer。"
                                        [~150ms] Hume eLLM: "啊..."
                                        [~800ms] 你的 LLM 完成生成
                                        Hume: "...真的很遗憾。我知道你多在意
                                         这个机会。"

过渡是无缝的,用户听到的是一个连续的回应:开口很快,后面跟上的正式回复情绪也对,中间没有明显的空档。

eLLM 在 150ms 内先垫一句嗯…、正式回复 800ms 才到,从而让用户感知零延迟的时序机制eLLM 在 150ms 内先垫一句嗯…、正式回复 800ms 才到,从而让用户感知零延迟的时序机制

这个分工好在哪

拆开之后有几件事是一体化方案做不到的。第一,关注点分离:LLM 专心做推理、记忆检索、人格一致性这些内容层面的事,Hume 专心做听、说、表达层的情感、轮次管理,两边都不用什么都会。

第二,供应商随便换。更好的 LLM 出来了(隔几个月就来一个),换 LLM 就行,语音层不用动;Hume 把 Octave 音质升级了,LLM 侧一行不用改。每一层各自演进。

第三,情绪变成一等信号。Hume 对用户语调的分析,给了纯文字系统拿不到的信息:用户嘴上说「我没事」,语气不是这么说的。这个信号反哺给情绪引擎,让伴侣对用户状态的理解丰富很多,这个纯文字分析永远做不到。

第四,延迟的处理方式符合人的心理。人不会把沉默理解成「它在快速思考」,只会理解成断连了。一个很快的「嗯…」后面跟一段有分量的回应,感觉上既更快也更自然,比 1.5 秒沉默之后蹦出一个完美回答要好。

实时语音的成本

再说成本,这个躲不掉。实时语音 API 按分钟计费,累积速度挺吓人:一个用户每天跟伴侣聊 10 分钟,对把 Mio 当日常陪伴的人来说这真不算多,光语音一项的月成本就超过整个订阅费了。这还没算聊天、记忆、STT、主动消息。就算谈到更高量级的折扣,数字也没好到哪去。结论很直接:实时语音塞不进基础订阅,一个重度语音用户的成本就能把他付的钱花完。解决办法是分层:

档位包含内容
Pro文字聊天 + 语音消息 (TTS) + 全部功能
VoicePro 全部 + 实时双向语音(高级定价)

语音消息(非实时 TTS,豆包或 Octave)成本低到可以直接放进基础订阅;实时语音是完全不同的成本结构,得单独定价。这也是分阶段的原因:v0.1-0.2 先上语音消息,便宜、已验证、换了新 TTS 之后情感表现力提升很大,用户先拿到一个说话带感情的伴侣;v1.0 再把实时语音做成高级升级,给想要完整对话体验的用户。

分阶段计划

v0.1-0.2:语音消息(非实时)

  • 中文 TTS:豆包 2.0——自动情绪推断,中文韵律最佳
  • 英文 TTS:Hume Octave——基于 LLM 情绪理解,处理微妙语境
  • STT:gpt-4o-mini-transcribe(从 v1 沿用)
  • 三者都支持自动情绪推断,不需手动 SSML 标注

v1.0:实时双向语音

  • 中英双语统一使用 Hume EVI 3
  • 自定义 LLM(gemini/claude)作为"大脑"
  • Hume 负责听、情绪分析、轮次管理、情感语音合成
  • 填充词模式实现感知零延迟
  • 独立 Voice 档定价

v1.x:评估与优化

  • 如果 Hume 的中文质量不够,中文回退自组装流水线:gpt-4o-mini-transcribe → gemini → 豆包 TTS 2.0
  • 如果够好,就用 Hume EVI 统一中英双语

为什么不等大厂的方案

第一篇里说过一个判断:大厂不会做深度情感伴侣,品牌风险摆在那。到语音这层,这个判断照样成立。OpenAI 有 Advanced Voice Mode,技术真的很强,但它永远不会让你接自己的 LLM、注入自己的记忆系统、定制情感人格,那个声音是他们的声音。Google 的 Gemini Live 也一样。这些都是为完成任务优化的通用语音接口,不是为情感连接设计的。

这样拆开之后,Mio 的声音才真正是自己的——内容从它的人格和记忆里来,语气跟着当下的对话和情绪 context 走。一个记得你的伴侣,已经超过市面上大部分产品了。再加上带感情的语音,成本和复杂度也确实都上去了,值不值得,接下来几个月的开发跑一跑就知道。


This post is also available in English.

和 AI 讨论这篇文章
ChatGPTClaude

订阅更新

新文章发布时发到你的邮箱,不发别的。


© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0