字节跳动 Seed 宣布推出原生音视频全双工大模型 SeedRealtime,并已在豆包 App 全量上线。它关注的并不是单纯把语音识别、视觉理解和语音合成串联起来,而是让模型直接面对连续的音频、视频与文本信息流,在交互过程中同时做到“边看、边听、边说”。
这意味着实时多模态交互开始从“轮流发送消息”走向“持续感知和持续响应”。用户不必等模型完成一轮识别后再发起下一轮输入,模型也可以结合声音、画面和时间变化理解当前场景。
从多模块流水线到统一理解
传统的语音助手通常采用类似这样的链路:
麦克风 -> 语音识别 -> 文本大模型 -> 文本生成 -> 语音合成
摄像头 -> 图像抽帧 -> 视觉模型 -> 文本大模型
这种架构容易落地,但实时体验会受到多个环节影响:语音识别需要等待一句话结束,视频通常以离散图片或低频抽帧方式输入,不同模态之间还需要通过文本或中间结果传递信息。
SeedRealtime 的核心方向,是采用统一架构原生融合音频、视频与文本,并在连续的多模态信息流上进行交互。按照这一思路,模型处理的对象不再只是“这一句语音”或“这一张图片”,还包括声音和画面在时间轴上的变化。
这类时序信息很重要。例如,用户说“刚才那个地方再解释一下”,模型需要结合此前看到的画面、听到的内容和当前指代关系,而不是只分析最新的一句话。
三项能力意味着什么
来源摘要提到,SeedRealtime 已实现三项核心突破,其中已明确披露的方向包括音视频联合理解。它原生支持声音、画面与时序信息,这为连续场景下的交互提供了基础。
1. 音视频联合理解
声音和画面经常需要放在一起分析。一个人指向屏幕时,视频提供手势和目标位置,语音提供意图;会议中有人发言时,音频包含内容和语气,视频则可能提供说话人、演示文稿或现场状态。
联合理解的价值不只是“同时支持两种输入”,而是让模型能够判断它们之间的关系:哪个声音对应哪个画面、某个动作发生在什么时间、用户的口头描述是否与当前视觉内容一致。
2. 连续多模态信息流
实时场景里的输入没有明确的消息边界。用户可能停顿、改口、插话,也可能在说话过程中转动摄像头。模型如果只能等待完整输入,就难以形成自然的对话节奏。
连续信息流要求系统持续接收并更新上下文,同时判断何时响应、是否需要打断当前输出,以及哪些历史内容仍然与当前场景相关。
3. 全双工实时交互
“全双工”可以理解为用户和模型能够同时进行输入与输出。模型说话时,用户仍然可以继续讲话;用户改变关注点时,系统也需要及时调整,而不是把所有内容排队处理。
这种交互方式更接近人与人交流,但工程复杂度也更高。系统需要处理语音活动检测、打断策略、音频缓冲、视频帧采样、响应延迟和上下文同步等问题。模型能力之外,端到端系统设计同样决定体验。
可以怎样构建一个实时多模态客户端
SeedRealtime 的具体开放接口、协议和参数应以官方发布信息为准。下面给出一个与主题匹配的最小客户端框架,假设服务端提供 WebSocket 接口,并接受音频块、视频帧和文本事件。示例重点展示数据组织方式,不能直接替代真实 SDK。
运行前需要把 WS_URL 改成实际服务地址,并根据服务端要求补充鉴权方式、音频编码和视频格式。
import asyncio
import base64
import json
import os
import websockets
WS_URL = os.environ.get("REALTIME_WS_URL", "ws://localhost:8000/realtime")
TOKEN = os.environ.get("REALTIME_TOKEN", "demo-token")
def event(kind: str, data: bytes | str) -> str:
if isinstance(data, bytes):
data = base64.b64encode(data).decode("ascii")
return json.dumps({"type": kind, "data": data})
async def run_demo() -> None:
headers = {"Authorization": f"Bearer {TOKEN}"}
async with websockets.connect(WS_URL, additional_headers=headers) as ws:
await ws.send(event("text", "请关注画面中的演示文稿,并用中文简短回答。"))
# 实际项目中,这些数据来自麦克风和摄像头。
audio_chunk = b"fake-pcm16-audio"
video_frame = b"fake-jpeg-frame"
await ws.send(event("audio.chunk", audio_chunk))
await ws.send(event("video.frame", video_frame))
await ws.send(event("input.end", ""))
async for raw in ws:
message = json.loads(raw)
message_type = message.get("type")
if message_type == "audio.delta":
pcm = base64.b64decode(message["data"])
print(f"收到语音片段: {len(pcm)} bytes")
elif message_type == "text.delta":
print(message.get("data", ""), end="", flush=True)
elif message_type == "response.done":
print("\n本轮响应结束")
break
if __name__ == "__main__":
asyncio.run(run_demo())
真正的全双工客户端还需要把发送和接收拆成并发任务,并实现用户打断。例如,播放模型语音期间检测到用户重新开口,就可以发送 response.cancel,停止旧响应,再继续上传新的音频和视频数据。这个策略能减少“模型还在回答上一句话”的滞后感。
对应用开发者的影响
实时音视频模型适合那些上下文变化快、单一文本交互不够自然的场景:视频通话助手、在线教育、会议记录与问答、屏幕操作指导,以及需要同时观察环境和听取指令的智能终端。
但并不是所有应用都应该直接采用全双工模式。纯文本问答、低频客服和强调审计的业务,仍然可能更适合可回放、可检索、边界清晰的请求响应架构。全双工会带来更高的带宽、算力和状态管理成本,也需要更严格的隐私处理。
落地时可以重点检查以下问题:
- 是否需要持续上传摄像头画面,还是只在用户授权后按需采样?
- 音频和视频数据是否加密传输,是否设置明确的保存期限?
- 用户插话后,旧响应如何取消,新的上下文从哪里开始?
- 延迟、丢帧和弱网场景下,客户端是否有降级方案?
- 模型的视觉判断、语音转写和自动操作是否需要人工确认?
结语
SeedRealtime 的发布,显示实时多模态交互正在从“多个模型拼接”走向统一模型处理连续信息流。它带来的关键变化不是多了一个输入框,而是交互单位从一轮消息扩展到了持续发生的声音、画面和对话状态。
对于开发团队,合理的采用路径是先选一个对实时性确有需求的场景,测量端到端延迟、打断成功率、音视频同步和资源成本,再决定是否扩大使用范围。模型越像一个持续在线的交互对象,产品就越需要认真设计权限、隐私、可控性和失败时的退路。