LiveKit 实时语音 Agent 端到端实现解剖

从客户端声学、WebRTC SFU、Agent 调度到模型管线与自然打断

这是一份基于公开文档与开源代码的 clean-room 式系统解剖。LiveKit 的 Server、Agents 和客户端 SDK 是开源的,因此本文可以比闭源 Realtime API 更进一步,追踪到具体类、队列、状态机和网络连接;但不会把 LiveKit Cloud 的私有调度、Inference、增强降噪或 Insights 实现猜成开源事实。
文中的结论分为三类:源码事实来自固定 commit;官方事实来自 LiveKit 当前公开文档;设计判断是如果我们自己实现同类系统时的架构取舍。
证据快照:2026-08-23。固定版本为 LiveKit Server v1.13.5、LiveKit Agents Python 1.7.0、LiveKit Client SDK JS 2.22.0,实施时仍应重新核对最新接口。

零、名词解释:阅读报告前先建立共同语言

LiveKit 对象与运行时

名词全称 / 中文通俗解释本报告中的位置
RTCReal-Time Communication,实时通信让音频、视频或数据低延迟双向流动的一类系统整条实时语音链的技术类别
Room房间 / 会话容器LiveKit 中把参与者、媒体轨道和数据消息组织在一起的逻辑空间,不是一个 UI 页面每次实时对话的媒体容器
Participant参与者加入 Room 的用户、设备网关、电话或 Agent 进程用户端与 Agent 都以 Participant 进入 Room
Track媒体轨道一条持续的音频、视频或数据流;发布者 publish,接收者 subscribe用户麦克风上行与 Agent 语音下行
SFUSelective Forwarding Unit,选择性转发单元不理解语义,只接收参与者的媒体包并转发给订阅者;比把所有音频混在一起更灵活LiveKit Server 内的媒体转发核心
AgentServerAgent 服务进程向 LiveKit 注册可接任务的 Agent 代码与容量管理 Worker 和 Job 的服务端入口
Worker工作进程 / 工作单元接受 LiveKit dispatch,启动具体会话 Job承载可用 Agent 容量
Job单次会话任务为一个 Room / 会话承载隔离的 Agent 运行实例每个活跃会话的执行实例
AgentSessionAgent 会话编排器收音频、判断轮次、调用模型/工具、产生回答并发出状态事件AI 行为与会话状态的核心
RoomIORoom Input / Output,房间输入输出适配器把 Room Track 和 AgentSession 的音频/转写输入输出连接起来Agent Participant 与 Room 的媒体接口
可听历史Audible history用户实际上已经听到的 Assistant 内容与播放位置,不等于模型已生成的全部内容打断后修正对话上下文的事实基线
Playout Ledger播放事实账本记录声音排队、开始、实际播出与清空的位置连接物理播放和 Conversation projection

WebRTC 与网络安全

名词全称 / 中文通俗解释本报告中的位置
WebRTCWeb Real-Time Communication一整套实时媒体协议栈,包含建连、加密、抖动处理、拥塞控制与音频传输;并不只属于浏览器Client / Agent 与 LiveKit Server 的媒体传输
Signaling信令在真正传媒体前交换“谁加入、有哪些 Track、怎样建连”等控制信息SDK 与 LiveKit Server 之间的控制连接
ICEInteractive Connectivity Establishment,交互式连接建立收集并选择双方可互通的网络候选地址WebRTC 建连机制
STUNSession Traversal Utilities for NAT帮客户端发现自己在公网看到的地址跨网络建连辅助服务
TURNTraversal Using Relays around NAT直连失败时中继全部媒体,代价是额外带宽和延迟复杂 NAT / 防火墙下的媒体兜底
DTLSDatagram Transport Layer Security在 UDP 上完成握手与密钥协商WebRTC 媒体加密的密钥协商层
SRTPSecure Real-time Transport Protocol,安全实时传输协议加密音频/视频媒体包WebRTC 的安全媒体传输层
RTP / RTCPReal-time Transport Protocol / Control ProtocolRTP 送实时媒体,RTCP 回报丢包、抖动、时序等质量信息SDK 与 SFU 内部的媒体数据面
Data Channel数据通道与媒体 Track 并行传递低延迟应用数据传状态、播放回执等事件
RPCRemote Procedure Call,远程过程调用一个 Participant 调用另一个 Participant 暴露的受控方法并等待结果Agent 调用客户端/设备能力
JWTJSON Web Token带签名的短期入房凭据,声明 identity、Room 和权限Client 与 Agent 加入 Room 的授权凭证

音频与 AI

名词全称 / 中文通俗解释本报告中的位置
PCMPulse-Code Modulation,脉冲编码调制未压缩音频样本,简单但占带宽采集、处理和送入 audio source 的基础格式
Opus实时音频编码器WebRTC 常用的低延迟语音/音乐压缩格式LiveKit 音频 Track 的常见编码
AECAcoustic Echo Cancellation,声学回声消除从麦克风中消除扬声器正在播放的回声全双工边播边听的关键声学处理
NSNoise Suppression,噪声抑制降低风扇、环境底噪等非语音噪声客户端声学前处理
AGCAutomatic Gain Control,自动增益控制自动把过小或过大的输入音量拉到合理范围客户端输入电平控制
VADVoice Activity Detection,语音活动检测判断当前有没有人在说话,不等于已经理解一句话是否结束AgentSession 的轮次与打断输入之一
STT / ASRSpeech-to-Text / Automatic Speech Recognition,语音识别把语音变成文本级联模型路径第一段
LLMLarge Language Model,大语言模型理解文本、推理、决定回答和工具调用Agent 的推理模块
TTSText-to-Speech,语音合成把回答文本合成音频级联模型路径最后一段
Realtime Model原生实时语音模型直接持续接收音频并流式产生音频/事件,内部不一定暴露独立 STT/TTS可替代 STT → LLM → TTS 整条级联路径

可选平台服务

名词全称 / 中文通俗解释本报告中的位置
Ingress外部媒体入流把 RTMP、WHIP 等外部流送进 LiveKit Room外部媒体接入的可选服务
Egress媒体输出 / 录制从 Room 录制或转推到外部直播平台录制与直播输出的可选服务
SIPSession Initiation Protocol,会话初始协议连接电话网络与 VoIP 系统电话渠道接入协议
Redis内存数据存储 / 消息总线LiveKit 多节点时共享 Room 路由和节点状态分布式部署依赖,单节点不需要
OTelOpenTelemetry统一采集 trace、metric 与日志的可观测标准自建观测链的推荐接口

如果只读一页

LiveKit 不是另一个 OpenAI Realtime,也不是一个自己生成语音的基础模型。它更准确的定位是:

以 Room / Participant / Track 为统一对象模型,以 WebRTC SFU 为实时媒体底座,以 AgentSession 为会话状态机,以 AgentServer 为弹性执行池,把任意 STT、LLM、TTS 或原生 Realtime Model 接入同一条实时交互链路。

官网的 LiveKit Ecosystem 表格很大,但它是能力目录,不是安装依赖图:Browser、Swift、Android、ESP32 和 C++ SDK 是不同终端的替代入口;Python 与 Node.js Agents SDK 是两种 Agent 实现选择;Starter Apps、UI Components、Ingress、Egress、SIP 与 Cloud 托管能力都可以按场景独立采用。还要进一步区分两种集成深度:需要 Room、多端互通和标准 WebRTC 媒体时采用完整 LiveKit 平台;Cardputer 或桌面 App 只在本机连接一个 Agent 时,可以只复用 LiveKit Agents runtime,通过自定义 AudioInput / AudioOutput 直接进入 AgentSession,不部署 LiveKit Server、Client SDK、Room 或 SFU。

用户、浏览器、手机、SIP 来电和 AI Agent 在 LiveKit 中都被归一为 Room 内的 Participant。用户发布麦克风 Track;Agent 作为服务端 Participant 订阅它,经模型管线产生音频,再发布自己的 Track。LiveKit Server 负责信令、ICE/TURN、SRTP、SFU 转发、房间状态和 Agent dispatch;Agent 进程负责轮次、模型、工具、打断、可听历史和业务逻辑;模型本身仍可来自 OpenAI、Google、Deepgram、ElevenLabs、自托管推理或 LiveKit Cloud Inference。LiveKit overview Agents overview

与“浏览器直接连 OpenAI Realtime”的方案相比,典型 LiveKit 拓扑是:

浏览器 / App / SIP 电话
        ↕ WebRTC / RTP
LiveKit Room / SFU
        ↕ WebRTC Track
自有 Agent Job 进程
        ↕ Provider API / WebSocket
STT → LLM → TTS,或原生 Realtime Model
01-livekit-end-to-end-room-sfu.png

这张图刻意把模型画成 Agent Job 后方的三条可替换路径:Room/SFU 统一媒体对象,AgentSession 统一会话状态,业务后端继续掌握身份、权限与真实动作。

这多了一次 LiveKit ↔ Agent 的媒体路径,却换来六项平台能力:

  1. 模型可替换:级联管线、speech-to-speech、half-cascade 可以共用 Room 与 Agent 生命周期。
  2. 媒体可编排:多参与者、选择性订阅、数据通道、SIP、录制和前端状态都落在统一房间模型。
  3. 逻辑归自己:工具、身份、权限、业务状态和 Prompt 留在自有 Agent 进程,不需要塞进客户端。
  4. Agent 可调度:Agent Server 长连注册容量;LiveKit 按负载选择 Worker,再为 Job 启动隔离进程。
  5. 打断可闭环:生成取消、音频队列清空、实际播放位置、文本截断和远端模型上下文同步在同一框架中协调。
  6. 可以自托管:媒体 Server、Agents、SDK、SIP Server 均有开源路径;但 Cloud Inference、Insights 和部分增强音频能力不是开源 Server 的同义词。

LiveKit 最值得学习的不是某个 STT 或 TTS 封装,而是它把实时语音拆成了三个深模块:

  • Media Fabric:Room、Participant、Track、WebRTC transport、SFU、重连和分布式房间路由。
  • Agent Runtime:Worker 注册、容量选择、Job 隔离、RoomIO、AgentSession、AgentActivity、SpeechHandle。
  • Conversation Consistency:轮次判断、暂停/恢复、播放游标、迟到音频 fencing、已听历史和模型上下文截断。

如果我们自己实现一套基本相似的系统,应复用成熟 WebRTC/SFU 和模型 Provider,重点自研的不是编解码器,而是 Session Actor、Turn Manager、Playout Ledger、Capability Gateway 与跨层可观测性。


一、证据边界与版本快照

1.1 这次能看到什么

OpenAI Realtime 的分析只能依据公开契约反推可能实现;LiveKit 则可以直接检查三条开源主链:

层固定快照本报告检查的核心实现
LiveKit Serverv1.13.5 / 788d4c354474383956067e3a22ffba88dd4803e4信令、Room、Participant、WebRTC transport、SFU、Redis router、Agent dispatch
LiveKit Agents Python1.7.0 / da6af86ac640a3bc54585764e64321d7048c1c16AgentServer、Job 进程、AgentSession、AgentActivity、RoomIO、OpenAI Realtime 插件
LiveKit Client SDK JS2.22.0 / f3732d14bf3162981e4a57d1daa7305a1f3ab7b5getUserMedia、声学约束、PeerConnection 管理、重连、远端播放

三者均为 Apache-2.0。源码快照能证明公开仓库在该 commit 的实现,但不能证明 LiveKit Cloud 内部部署参数、私有服务、实时负载、SLA 或线上分支与仓库逐字相同。

1.2 开源与 Cloud 必须分开理解

能力开源可自托管LiveKit Cloud 托管能力
Room / Participant / Track / SFU是托管运行
WebRTC 信令、ICE/TURN 接入是,需自己部署公网和 TURN托管全球边缘与网络
Agents SDK 与 Agent Server是可托管部署,也可自托管 Agent 连 Cloud Room
STT / LLM / TTS 插件是,Provider 账密由自己管理也可使用 Cloud Inference 统一入口
SIP Server有独立开源部署路径Cloud 预置服务与电话能力
Agent Insights 统一音频/转写/Trace/日志时间线不是完全自托管产品Cloud 特性;完全自托管应接 OpenTelemetry、日志、对象存储
增强噪声消除基础客户端 AEC/NS/AGC 与自选 DSP部分高级模型由 Cloud 提供

官方 Observability 文档明确说明 Cloud Insights 不适用于完全自托管媒体部署;不过 Agents SDK 的 OpenTelemetry spans 可以导出到任意 OTLP 后端。Observability overview Export traces


二、总体架构:五层、四条连接、三个状态权威

Mermaid diagram

四条长期或半长期连接分别承担不同职责:

连接端点主要内容谁负责恢复
客户端信令Client SDK ↔ LiveKitJoin、SDP、ICE、Track/Participant 更新、resumeClient SDK + LiveKit signal bridge
客户端媒体Client PeerConnection ↔ LiveKit SFUSRTP 音频、RTCP、DataChannelWebRTC ICE/DTLS + SDK 重连策略
Worker 控制AgentServer ↔ LiveKit /agent注册、容量、availability、assignment、terminationAgentServer 重连循环
模型连接Agent Job ↔ STT/LLM/TTS/Realtime Provider音频帧、文本 token、工具事件、生成音频各 Provider plugin + AgentSession

系统中至少有三个不同的状态权威:

  • Room 是媒体成员关系的权威:谁在线、发布了什么 Track、谁订阅谁。
  • AgentSession 是当前对话执行的权威:轮次、生成、工具、正在播放的 SpeechHandle。
  • 业务后端是现实事实的权威:用户身份、订单、设备动作、支付、长期记忆和审计。

把三者混成一个“会话状态”会制造恢复错误:Room 重连不代表模型连接仍在;模型生成完成不代表声音已播放;工具函数返回不代表业务事务已提交。


三、客户端:声学现实仍然属于设备

3.1 采集链路

Web 客户端调用 getUserMedia 获取麦克风。JS SDK 的默认音频约束开启 autoGainControl、echoCancellation、noiseSuppression 和 voiceIsolation;代码再把约束传给浏览器的 navigator.mediaDevices.getUserMedia。audio defaults media capture

这说明 LiveKit 负责“请求浏览器启用声学处理”,不等于 LiveKit Server 自己替客户端完成 AEC:

扬声器参考信号 ─────┐
                    ↓
麦克风 → AEC → NS → AGC → 浏览器 AudioTrack → Opus / WebRTC
          ↑
      设备声学与 OS 音频栈

生产客户端仍需承担:

  • 权限与设备切换;
  • 采样率、声道和路由变化;
  • 蓝牙耳机切换及 SCO/A2DP 差异;
  • 外放双讲、远场混响、风噪和键盘声测试;
  • iOS 后台、Android audio focus、浏览器 autoplay 限制;
  • 本地 mute、push-to-talk、音量表和设备故障提示。

AEC 是自然打断的前提。若助手播放音频重新进入麦克风,远端 VAD 会把助手自己的声音误判成用户插话;更强的服务端降噪无法可靠替代设备侧回声参考。

3.2 WebRTC 连接并非一条简单 Socket

JS SDK 用 PCTransportManager 管理 publisher 与可选 subscriber PeerConnection,并支持 subscriber-primary、publisher-primary、publisher-only 三种模式。双 PC 模式把发布和订阅隔离,单 PC 模式可以双向承载;ICE candidates、track、data channel 和 offer 都通过信令层协调。PCTransportManager

客户端建连的逻辑步骤是:

  1. 向自有后端登录并获取短期 Room access token;token 绑定 room、participant identity 和发布/订阅权限。
  2. 与 LiveKit 建立 TLS WebSocket 信令连接,交换 Join、SDP 和 ICE。
  3. ICE 选择 host / srflx / relay candidate;必要时经 TURN。
  4. DTLS 建立密钥,媒体走 SRTP,音频 Track 发布到 SFU。
  5. Agent 加入后,客户端订阅其音频 Track,SDK attach 到 HTMLMediaElement 或 Web Audio graph 播放。Connecting to LiveKit RemoteAudioTrack

Room token 不是用户登录 token。推荐由业务后端在完成用户鉴权后签发短 TTL、最小权限的 LiveKit token;API secret 不应进入浏览器。

3.3 重连是“恢复”与“重建”两条路径

JS SDK 区分轻量 resumeConnection 和完整 restartConnection。前者恢复信令并保留/修复现有 PeerConnection;后者关闭旧连接、重新 Join、重建 PC,必要时尝试下一区域。失败的 resume 会升级为 full reconnect。reconnect decision restart and region fallback

产品不能只显示“网络已恢复”。完整恢复应分别确认:

  • Room participant identity 是否延续;
  • 本地麦克风 Track 是否重新发布;
  • Agent 是否仍在同一 Job / Session;
  • Provider 实时模型连接是否重放必要上下文;
  • 旧音频是否已 flush,当前播放 cursor 是否有效;
  • 未完成工具调用是继续、查询结果还是幂等重试。

四、LiveKit Server:信令、Room 与 SFU 如何接住音频

4.1 Room 是媒体 Actor,不是聊天记录

Room 持有 Participant、Track、订阅关系、AgentDispatch 和广播状态。新 Track 发布后,Room 登记 Track、广播 Participant 更新,并按 auto-subscribe 策略让已有 Participant 订阅;首次发布还可以触发 publisher 类型的 Agent job。onTrackPublished

因此 AI Agent 与普通参会者共享相同媒体原语:

  • 用户麦克风:一个由用户 Participant 发布的 audio Track;
  • Agent 耳朵:Agent Participant 对用户 Track 的 subscription;
  • Agent 嘴巴:Agent Participant 发布的另一个 audio Track;
  • 转写、状态、RPC:Room data / text / RPC 能力;
  • 电话:SIP Participant 进入同一个 Room。

这套对象模型让“网页用户 ↔ Agent”“两名用户 + Agent”“电话用户 ↔ Agent”“机器人摄像头 + Agent”不必各造一套会话协议。

4.2 信令和媒体可以落在不同入口节点

客户端的持久 WebSocket 可能连接节点 A,而 Room 实际托管在节点 B。分布式模式下,入口节点作为 signaling bridge 把信令代理到 Room 节点;当前一个 Room 必须完整落在单个节点上。Distributed multi-region

Server 的 RedisRouter 用 Redis 保存 node 列表与 room → node 映射,并把 participant signal 路由到 Room 所在节点;drain 时把当前节点标记为 SHUTTING_DOWN。RedisRouter

Mermaid diagram

这个约束直接影响容量设计:扩容可以增加并发 Room 数,但不能用加节点线性扩展单个超大 Room。语音 Agent 通常每 Room 参与者少,因此 room affinity 很自然;大型会议或广播场景则需要单房间容量测试。

4.3 SFU 不解码再混音,而是选择性转发 RTP

在媒体路径上,Pion WebRTC OnTrack 接到上行 TrackRemote,LiveKit 为发布 Track 建立 WebRTCReceiver;每个订阅者对应 DownTrack。Receiver 收到扩展 RTP packet 后分发给 DownTrack,DownTrack 做 sequence/timestamp、layer、重传和拥塞相关处理后写向订阅者。WebRTCReceiver DownTrack WriteRTP

对语音 Agent 来说,SFU 的价值不是视频多层,而是:

  • 浏览器和 Agent 都使用标准 WebRTC,而非每个模型 Provider 的私有媒体协议;
  • 一个用户 Track 可以同时给 Agent、录制器、监督员或第二参与者;
  • RTCP、NACK、抖动和拥塞控制留在成熟实时媒体栈;
  • Agent 换模型不要求客户端换连接协议。

代价也很明确:Agent 必须先从 SFU 收到媒体,再发给模型;模型音频又先回 Agent,再发布到 SFU。相较客户端直连模型,这增加网络 hop、缓冲点和故障域,因此 Agent 与 Room 节点、模型区域应尽量就近部署。

4.4 自托管部署的实际网络成本

真正的自托管不是只启动一个 Docker 容器。生产环境至少需要:

  • 公网可达的 TLS 信令入口;
  • UDP 媒体端口与 TCP/TLS fallback;
  • TURN 服务应对严格 NAT、防火墙和企业网络;
  • Redis 支撑多节点共享状态与消息总线;
  • room-aware drain,不能把有活跃 Room 的节点直接杀掉;
  • 区域 DNS/LB 与 node selector 协同;
  • SFU 的带宽、包率、UDP buffer 和单房间容量监控。

LiveKit 官方的 drain 语义是:活跃 Room 继续运行、允许新 Participant 加入这些活跃 Room,但拒绝在该节点创建新 Room;所有参与者离开后才退出。Distributed multi-region


五、Agent 调度:一个 AI Participant 如何被拉起

5.1 AgentServer 是 Worker,不是每会话业务对象

Agent 应用启动后,AgentServer 与 LiveKit 的 /agent endpoint 建立长期 WebSocket,注册 agent name、job type、permissions、deployment、版本和当前负载。它不是先加入某个 Room 等用户,而是成为一台可接受 Job 的 Worker。Agent server

当 Room 或 Participant 满足 dispatch 条件时,链路如下:

Mermaid diagram

02-agent-dispatch-job-isolation.png

调度链上同时存在两种权威:Room 的媒体节点亲和由 LiveKit Server / Redis 路由维护,Worker 的执行容量由 AgentServer 管理;独立 Job 进程则是一次会话的故障与资源隔离单元。

Server 端不是简单 round-robin。固定源码中,AgentHandler 按 (agentName, namespace, jobType, deployment) 找 Worker,用 max(0, 1-load) 作为剩余容量权重随机选择;若 Worker 不可用则尝试下一个。worker selection weighted load

Worker 收到 availability 后会立即计算有效负载并预留 slot,防止两个并发请求在 Job 尚未进入 active list 时同时超卖;收到 assignment 后才把带有 Room URL 与 token 的 RunningJobInfo 交给进程池。availability and reservation

5.2 为什么默认每 Job 一个进程

在非 Windows 平台,Python Agents 默认 JobExecutorType.PROCESS;生产默认负载阈值为 0.7,还提供 prewarm、idle process、memory warning/limit 和 drain 配置。worker defaults

每 Job 进程带来四个隔离收益:

  • 一次会话的死循环、内存泄漏和 Provider SDK 崩溃不直接污染其他 Job;
  • 可以在进程级执行资源计量、终止和重启;
  • Room token、每会话 userdata 与工具上下文不必共享全局可变状态;
  • AgentServer 可以先 prewarm 进程,减少 import、模型加载和连接初始化冷启动。

但它不是完整安全沙箱。恶意工具仍可能访问同一宿主凭据、文件系统和网络;高风险多租户应再叠加容器、VM、seccomp、网络策略和按租户的 capability credential。

5.3 调度层真正需要观测的不是 QPS

对语音 Agent,更关键的 Worker 指标是:

指标原因
dispatch wait / assignment latency用户进入 Room 后多久真正出现 Agent
cold vs warm Job start首轮延迟是否被 import、模型连接、VAD 加载拖慢
active jobs / reserved slots / effective load发现并发超卖或过度保守
room node ↔ agent node RTT直接进入双向媒体延迟预算
agent node ↔ model region RTT级联每阶段、Realtime WebSocket 都受影响
abnormal job exit / redispatch count会话是否被进程崩溃打断
drain duration发布与缩容是否会破坏长通话

调度恢复也不能只“重新拉一个进程”。新 Job 必须知道它是新会话、接管还是恢复;业务层需为 tool call、用户身份、会话摘要和未完成事务提供可重放的 checkpoint。


六、Agent Runtime:AgentSession 是怎样的深模块

6.1 核心对象与职责

AgentSession 的构造函数直接接受 STT、VAD、LLM 或 RealtimeModel、TTS、turn handling、tools、MCP servers 和运行选项;源码对它的定义就是把媒体、模型、工具、端点判断和打断粘合成一个实时 Agent runtime。AgentSession

对象深职责不应承担
AgentServer注册、容量、dispatch、Job 生命周期单轮对话状态
JobContextRoom URL/token、Job 元数据、进程上下文长期业务记忆
AgentSession会话入口、I/O、事件、模型、工具、观测SFU 转发与业务权限真相
AgentActivity当前 Agent 的轮次、生成、打断和 speech 调度跨会话 worker 调度
SpeechHandle一段可排队、可打断、可等待的发言生命周期整个 Conversation
RoomIORoom Track ↔ Agent 音频/转写/状态适配模型 Provider 协议
Provider pluginSTT/LLM/TTS/Realtime 协议适配与重连Room membership 和业务授权

这是一组“深模块”:上层业务只需定义 Agent 指令、tools 和可选 node override,不必自己操作每个 WebRTC frame、STT partial、TTS chunk 和打断 race。

6.2 RoomIO 把 Agent 变成真正的 Participant

AgentSession.start() 若未提供自定义 I/O,会创建默认 RoomIO,并同时初始化 session trace、usage、recording 和 primary session 状态。session start

输出侧 _ParticipantAudioOutput 创建一个 rtc.AudioSource,默认队列上限 200 ms,把流重组为 20 ms frame,再发布 LocalAudioTrack 并等待订阅者。RoomIO output

这里有两个非常重要的工程信号:

  1. 音频生成与实际播放之间一定有队列。模型已经产生的音频不等于用户已经听到。
  2. frame 粒度决定打断下限。20 ms frame 与 200 ms queue 是该固定版本的实现参数,不是所有部署的永恒契约,但说明框架显式管理 playout backlog。

6.3 一次正常语音轮次

Mermaid diagram

这条时序中存在五个独立的“完成”:用户停说、turn commit、模型 response complete、Agent output queue drained、客户端真实扬声器播放完成。只有最后两个接近“用户听完”,服务端不能用 response complete 替代。

6.4 可覆写的节点接口

级联管线向业务暴露 stt_node、llm_node、transcription_node 和 tts_node;它们都接受/返回 async iterable,因此可以在不改 Session 状态机的前提下插入预处理、路由、缓存、guardrail、文本规范化或自有模型。pipeline nodes

推荐把定制放在语义正确的 seam:

  • 音频增益、带通或自有降噪:STT 前的 audio node;
  • 多 STT fallback:STT adapter,而非业务 Agent;
  • RAG、Prompt、LLM router:llm_node;
  • Markdown/emoji/数字读法:TTS 前文本变换;
  • 品牌音色与合规播报:独立 TTS 或 tts_node;
  • 权限、幂等、审计:工具外的 Capability Gateway,不能只写在 Prompt。

七、三种模型管线不是三套产品

LiveKit 把 Room、调度、工具和 turn runtime 与模型管线解耦,因此同一前端和后端可以选择三类语音路径。Pipeline models

Mermaid diagram

路径优势代价更适合
STT → LLM → TTS每段可替换、转写及时、审计清楚、工具生态成熟、可精确播报多阶段增加延迟;文本接口损失韵律与情绪客服、交易、受监管流程、多语言和强可观测产品
原生 Realtime Model最低潜在延迟、自然 prosody、双讲与情绪表现更好Provider 锁定、远端上下文同步更复杂、转写可能滞后、难保证逐字播报陪伴、教育、自然开放对话、低延迟体验
Half-cascade保留原生音频理解,输出音色/合规文本更可控仍要协调实时理解与独立 TTS,接口成熟度依 Provider品牌音色、强 TTS 能力、希望折中可控性与自然度

LiveKit 文档当前推荐多数生产项目先从级联管线开始,这不是因为 speech-to-speech 不好,而是级联更容易检查每一阶段、替换 Provider、断言工具与转写。Realtime 路径适合体验优先,但仍需补齐 conversation projection 和 interruption consistency。

7.1 级联管线的真正延迟结构

总首音延迟近似为:

T_first_audio ≈
  T_capture_and_uplink
  + T_endpointing
  + T_STT_final_or_stable_partial
  + T_LLM_first_usable_text
  + T_TTS_first_chunk
  + T_agent_to_SFU
  + T_client_jitter_and_playout

这些项不是全串行:streaming STT、preemptive generation、LLM sentence chunking 与 streaming TTS 可以重叠。但越早预测性生成,越容易在用户补充后作废,因此需要 generation id、cancel 和不提交未播放文本。

作为自建目标而非 LiveKit 官方性能承诺,可先设:

  • 客户端 20 ms 帧;
  • 用户停说后 200–500 ms 内 commit 普通短句;
  • 400–900 ms 首个可听音频为优秀目标区间;
  • 100–200 ms 内对明确 barge-in 停止远端播音;
  • 所有分位数按 P50/P95/P99、网络类型、设备和语言拆分。

7.2 Realtime 路径仍然经过 Agent

以 OpenAI plugin 为例,RealtimeModel 被传给 AgentSession(llm=model);Agent Job 内的 RealtimeSession 再用 Provider API key 建立到 OpenAI 的 WebSocket。它把 Room audio frame 重采样、按 100 ms chunk 组织成 input_audio_buffer.append,并接收 response.output_audio.delta 等事件。OpenAI Realtime model Provider WebSocket push audio

所以实际拓扑是:

Browser ─WebRTC─> LiveKit SFU ─WebRTC─> Agent Job
                                           │
                                           └─WebSocket─> OpenAI Realtime

而不是 Browser 直接把 PeerConnection 建到 OpenAI。这个桥接层的意义是:

  • API key 留在服务器;
  • Room/SIP/多参与者与模型 Provider 解耦;
  • Agent 可插入工具、guardrail、转写投影和 handoff;
  • 同一产品可以把 OpenAI 换成别的 realtime model。

代价是媒体不再是客户端到模型的最短路径。若只做单用户浏览器语音、业务控制很薄、且完全绑定一个 Provider,客户端直连模型通常更省 hop;若要多渠道、Provider 可替换、自托管媒体和复杂工具,LiveKit 的中间层更有价值。


八、轮次与自然打断:LiveKit 最值得逆向学习的部分

8.1 轮次结束不是一个 VAD 布尔值

LiveKit 当前支持多种 turn detection 策略:

模式结束信号优点风险
semantic turn detector + VAD声学停顿 + 语义完成度避免用户思考停顿被抢话需要模型推断,可能增加等待
realtime model turn detectionProvider server-side VAD / semantic VAD与原生模型生成紧密协调控制权和诊断依赖 Provider
VAD-only静音持续时间快、语言无关犹豫、长停顿时容易过早提交
STT endpointingSTT final / endpoint event与转写一致受 STT latency 和语言影响
manual / push-to-talk客户端显式 commit最确定交互不够自然,用户负担高

Turn detection and interruptions

高质量策略应把 speech_started、STT partial/final、语义 EOU、最大等待时间和场景策略组合成状态机。比如客服收集订单号时,可以延长端点;“确认/取消”短指令可更激进;电话噪声环境应提高 min speech duration。

8.2 打断是五阶段提交协议

Mermaid diagram

03-interruption-audible-history.png

图中的三个历史不是同一份状态:模型可能已经生成、Agent 可能已经推送,但用户未必真的听见。自然打断只有在生成、播放和 conversation projection 同时收敛后才算完成。

五个阶段分别解决不同 race:

  1. 检测:用户真的开始说,还是回声、咳嗽、短 backchannel?
  2. 决策:当前 speech 是否允许打断,是否只先暂停等待更多证据?
  3. 生成取消:取消当前 Realtime response、LLM/TTS task 和排队 SpeechHandle。
  4. 物理停播:清空 Agent 输出队列,让还未发往 SFU 的 frame 不再出去。
  5. 语义提交:只把用户实际听到的部分写回本地与远端 conversation。

AgentActivity.interrupt() 会取消 preemptive generation、后台/current/queued speeches,并通知 realtime session 取消模型生成。interrupt fan-out

8.3 停止生成不等于停止声音

RoomIO 在 interruption 时:

  • 增加 _interruption_generation;
  • 丢弃内部 audio buffer;
  • 从已推送时长中减去 AudioSource.queued_duration;
  • 调用 clear_queue();
  • 以修正后的时长上报 playback_position;
  • forwarding task 对 generation 不匹配或 interrupted 的 frame 直接丢弃。

RoomIO interruption

这里的 _interruption_generation 就是 generation fence:即使取消信号与 frame producer 交错,旧代 frame 也不能重新进入新一轮播放。

不过 Agent 侧的 AudioSource queue drained 仍不是客户端扬声器的绝对物理位置:SFU、网络和客户端 jitter buffer 还可能有少量在途音频。若产品要求逐字精确的“已听历史”,应让客户端回报 playout acknowledgement,或者把服务端 cursor 当可接受近似并测量其误差。

8.4 可听历史必须反写给模型

当 speech 只播放一部分,AgentActivity 以实际 playback_position 计算 audio_end_ms,调用 realtime provider 的 truncate,本地 chat context 也只 upsert forwarded_text;完全未播放的 message 会从远端 mutable chat context 移除。audible transcript commit

OpenAI plugin 的 truncate 会发送 conversation.item.truncate,没有可听音频时可删除 item;interrupt() 则发送 response.cancel。provider cancel and truncate

这建立了三个同步对象:

生成历史:模型曾产生什么
播放历史:Agent 已向 Room 推送到哪里
可听历史:用户实际听到了什么

正确 conversation projection 应以可听历史为目标,而不是保存完整生成历史。否则下一轮模型会说“如我刚才解释的后半部分”,但用户从未听到那部分。

8.5 false interruption 不是异常,而是双讲必然现象

固定源码支持先 pause 当前 audio output,在超时或 turn verdict 后判断是否是假打断;若允许恢复且 SpeechHandle 尚未结束,就继续播放原 speech。Adaptive detector 出现不可恢复错误时,会降级为 VAD interruption,并释放被暂存的转写。false interruption resume adaptive fallback

这是比“VAD 一响就 kill”更成熟的策略:

  • “嗯”“对”“我在听”可能只是 backchannel,不一定要夺取轮次;
  • 咳嗽和瞬时噪声可以先暂停,而不是永久丢掉 response;
  • 真正连续讲话或出现有效 final transcript 时再 commit interruption;
  • detector 故障不能让 Agent 彻底失去打断能力,应降级到简单策略。

九、业务行动面:工具在 Agent 里执行,但权限不属于 Agent

9.1 模型工具调用只是行动提案

AgentSession 可以直接接收 tools、toolsets 和 MCP servers,LLM 或 Realtime Model 产生 function call 后由 Agent runtime 执行并把结果写回生成链。框架还支持多步工具、handoff 和 node override。AgentSession options Agent nodes

但生产系统应再包一层 Capability Gateway:

模型 function call
  → schema validation
  → 从可信 Session 取 user / tenant / role
  → policy check
  → 高风险动作二次确认
  → idempotency key / expected version
  → 业务 API
  → receipt / error / actual state
  → 结构化 tool result 回模型

不要让模型参数中的 user_id、is_admin 或“用户已经同意”成为授权证据。可信身份来自业务登录、Room token binding 和服务端 Session;工具只允许引用当前上下文中可访问的资源。

9.2 工具与语音有不同的取消语义

用户打断 Agent 播报时,至少有三种可能:

  • 只停止语音,已经成功的业务动作不能回滚;
  • 取消尚未开始的只读查询;
  • 对可取消的长任务发送 cancellation,但等待业务系统确认终态。

因此一次 tool run 应拥有独立 operation_id 与状态机:

proposed → authorized → running → succeeded | failed | cancel_requested → cancelled

Agent SpeechHandle 的 cancel token 不能直接冒充业务事务回滚。若用户在“订单已经提交”播到一半时插话,conversation 需要保留真实订单 receipt,即使刚才的自然语言被截断。

9.3 长任务必须离开实时 Job 的内存

Realtime Job 适合低延迟会话,不适合作为数分钟到数小时任务的唯一容器。长任务应进入持久队列/工作流系统,保存:

  • task_id、用户/租户和权限快照;
  • 输入、审批、幂等键和业务版本;
  • 可恢复 checkpoint、进度和最终 artifact;
  • 与 room_name、participant_identity、agent_job_id 的弱关联;
  • 结果通知渠道,而不是假设原 Room 永远在线。

LiveKit Agent 负责把用户意图转成受控任务、播报进度和结果;长期状态仍应由业务系统拥有。


十、前端交互面:音频 Track 之外还要同步什么

LiveKit Room 同时提供 media tracks、text/data、RPC 和 Participant metadata/attributes,因此前端不必从音频或转写猜 Agent 状态。建议定义一个小而版本化的 UI 协议:

消息关键字段用途
agent.state.v1state, turn_id, speech_id, seqlistening / thinking / speaking / interrupted / error
transcript.delta.v1speaker, segment_id, text, final, seq实时字幕与修订
tool.status.v1operation_id, name, phase, display_text查询中、等待确认、已完成
session.error.v1code, recoverable, action明确提示重连、换设备、重试
playout.ack.v1speech_id, audio_ms, seq可选:精确回报客户端已播放位置

状态同步必须带 turn_id / speech_id / 单调 seq,避免重连或迟到消息让 UI 从 listening 倒退到 speaking。字幕也应区分:

  • speculative partial:可修改;
  • stable partial:短期 UI 可依赖;
  • final transcript:语言识别完成;
  • audible assistant transcript:用户实际听到部分;
  • generated transcript:仅用于调试,不能直接当用户记忆。

对用户而言,最重要的恢复提示不是“WebRTC connected”,而是“我仍在听”“刚才的操作已经完成”“这段回答被你打断了”。底层连接状态要投影成产品语义。


十一、电话、机器人和多参与者为什么自然进入同一架构

11.1 SIP 来电也是 Participant

LiveKit Telephony 用 trunk 和 dispatch rule 把传统电话接入 Room。每个来电者被表示为 SIP Participant,拥有普通 Participant 的 metadata/attributes 和额外 SIP 属性;Agent 无需改写核心会话逻辑,只是输入音频从浏览器 WebRTC 变成 SIP/RTP gateway。Telephony introduction

PSTN / SIP Provider
  → SIP trunk
  → LiveKit SIP service
  → SIP Participant 加入 Room
  → Agent dispatch
  → 同一 AgentSession / tools / model pipeline

电话场景还需额外处理:

  • 8 kHz 窄带与 HD voice codec 差异;
  • DTMF、呼叫转移、振铃、接听、挂断和 voicemail/IVR;
  • caller ID 不能单独作为强身份认证;
  • SIP trunk ACL、TLS/SRTP、区域和监管要求;
  • 来电噪声、串音与没有可靠设备侧 AEC 的场景。

自托管 LiveKit Server 不会自动包含 SIP 服务,官方文档要求单独部署 LiveKit SIP。Telephony architecture

11.2 多参与者不是免费获得的“群聊智能”

Room 原语支持多参与者,但多方 Agent 仍需显式设计:

  • diarization:哪位 Participant 在说,而不只是一个混合音频流;
  • subscription policy:Agent 听谁、何时听;
  • floor control:多个人同时说时谁拥有 turn;
  • privacy:私聊 Track / data 是否允许 Agent 订阅;
  • tool authority:不同 Participant 的权限和确认不能混在一个 user context;
  • response addressing:Agent 回答全体还是某一人。

LiveKit 解决了媒体成员关系,不会自动解决多人社会规则。


十二、安全与隐私:E2EE 在 AI Agent 场景中的真实边界

12.1 传输加密、Room E2EE 与模型可见性不同

普通 WebRTC 使用 DTLS-SRTP 保护链路传输;LiveKit 还支持 media/data 的端到端加密,使中间 SFU 无法读取内容。密钥生成、分发和轮换由应用负责,信令/API 仍只是 TLS 传输加密而非 E2EE。Encryption overview

但 AI Agent 必须读取用户音频才能推理。因此 E2EE 的实际 endpoint 会包含 Agent Participant:

用户设备 ⇄ E2EE media ⇄ Agent endpoint ⇄ Provider TLS ⇄ 模型服务

这能防止 SFU 明文读取媒体,却不能让音频对 Agent 进程、STT/LLM/TTS Provider 不可见。隐私评审应逐跳回答:

  • 谁拥有 E2EE key;
  • Agent 在哪里解密;
  • 原始音频是否录制、保留多久;
  • 转写、trace 和日志是否包含 PII;
  • Provider 是否用于训练、在哪个区域处理;
  • 工具输出是否回到第三方模型;
  • 用户如何撤回同意和删除数据。

12.2 最小权限边界

主体最小凭据
浏览器/App短 TTL Room token,仅目标 room/identity 和必要 publish/subscribe grants
Agent Worker 注册Agent grant;不复用业务管理员 token
Job Participant只允许当前 Room 与需要的 Track/Data 权限
Model plugin单 Provider、单环境 secret,最好短期/代理化
Tool按用户/租户和 operation scope 的 capability token
Observability exporter只写入目标 telemetry backend,不可读取业务数据库

Room metadata 与 Participant attributes 可被其他参与者或服务读取时,不应存放长期密钥、完整 OAuth token 或不必要的 PII。


十三、可观测与测试:要重建一条跨媒体的因果链

13.1 Trace 不能只停在 LLM

LiveKit Agents 为 Session、语音管线和工具提供 OpenTelemetry instrumentation;Cloud Insights 可把音频、转写、trace、日志和事件指标放入统一时间线,完全自托管则应把相同语义导出到自有系统。Export traces Agent insights

推荐统一以下关联键:

trace_id
room_name / room_sid
participant_identity / participant_sid
agent_job_id / worker_id
session_id / turn_id / speech_id
provider_request_id / response_id
tool_operation_id

端到端时间线至少记录:

时间点说明
mic_capture_at客户端采到首帧/末帧
room_track_rx_atAgent 收到媒体
speech_start/end_atVAD 边界
turn_committed_at轮次正式提交
stt_partial/final_at转写阶段
llm_first_token_at文本生成首 token
tool_start/end_at外部副作用
tts_first_frame_at / realtime_audio_at模型首音频
room_audio_published_atAgent 发布输出
client_playout_started/ended_at用户真实播放近似
interrupt_detected/flushed/truncated_at打断三阶段

只有这样才能区分“模型慢”“网络慢”“端点判断慢”“TTS 慢”“音频已到但 autoplay 被阻止”。

13.2 指标分成四组

  • 媒体 QoE:RTT、jitter、packet loss、NACK、TURN ratio、audio concealment、input/output level。
  • 会话体验:time-to-agent-ready、end-of-turn latency、time-to-first-audio、barge-in stop latency、false interruption rate、dead air。
  • 模型与业务:STT WER 抽样、tool success/duplicate/cancel、hallucination、handoff、token/audio seconds/cost。
  • 平台可靠性:worker load、dispatch wait、job crash、provider reconnect、Room node drain、Redis/TURN failure。

均值会掩盖坏体验,应按 P50/P95/P99、设备、网络、语言、Provider、区域、电话/网页入口拆分。

13.3 测试分层

LiveKit 自带的测试框架可在 pytest/Vitest 中断言 message、tool call、arguments 和 handoff;Agent simulations 可测试完整多轮对话,但默认文本模式不覆盖真实音频链路。Testing and evaluation

因此需要四层测试:

  1. 确定性逻辑测试:工具 schema、权限、幂等、状态机、conversation truncation。
  2. 文本行为测试:Prompt、tool selection、handoff、错误恢复、grounding。
  3. 合成音频回归:多语言、口音、噪声、长停顿、数字、人名、重叠说话。
  4. 真实设备 E2E:手机/浏览器/耳机/外放、Wi-Fi/4G/高丢包、后台切换、SIP 电话。

必须单独做打断故障注入:在不同生成位置插话、连续两次插话、咳嗽、短 backchannel、cancel 后注入迟到音频、Provider 断线、Room resume、Job crash 和工具成功后播报被打断。


十四、与直接 OpenAI Realtime 架构的本质比较

维度客户端直连 OpenAI RealtimeLiveKit + Agent + OpenAI Realtime
客户端媒体路径Client ↔ OpenAIClient ↔ LiveKit SFU ↔ Agent ↔ OpenAI
首要目标最短的单用户模型媒体路径Provider-neutral 的实时媒体与 Agent 平台
API key客户端短期凭据 + 可选后端 sidebandProvider key 只在 Agent 服务器
多参与者 / Track需自建产品编排Room 原生
SIP / 电话OpenAI SIP 接入或自有网关SIP Participant 进入同一 Room
模型切换客户端/后端需适配 ProviderAgent plugin / pipeline seam
级联 STT-LLM-TTS另建管线一等路径
工具执行位置sideband backend / applicationAgent 进程 + 自有 Capability Gateway
打断OpenAI + 客户端/sideband 协调AgentActivity + RoomIO + provider truncate
可听历史WebRTC provider 可处理一部分;复杂产品仍需投影显式 playout position 与 transcript/context sync
自托管媒体不可自托管 OpenAI model/edgeLiveKit media 与 Agent 可自托管;模型仍依选择而定
运维成本较低SFU、TURN、Redis、Agent pool、模型连接均需运营
Provider 锁定高较低,但 LiveKit SDK/Room 模型形成平台依赖

两者不是简单替代关系:LiveKit 可以把 OpenAI Realtime 当作其中一个模型 Provider。真正的选择是:

  • 最短路径优先:单用户、Web/App、Provider 固定、业务工具简单 → 直接 Realtime 更合适。
  • 平台控制优先:网页 + 电话 + 多参与者、Provider 可换、复杂工具、自托管媒体 → LiveKit 更合适。
  • 混合:关键消费端走直连 Realtime,企业/电话/多方渠道走 LiveKit;自有业务 Capability Gateway 和长期任务层保持一致。

十五、LiveKit 生态矩阵:完整平台的分层架构与模块职责

15.1 先正确阅读 Ecosystem 截图

livekit-ecosystem-user-screenshot.png

图 15-1:用户提供的 LiveKit Ecosystem 页面截图(1704×844,截取于 2026-09-01)。它把语言入口、示例、UI、控制面 SDK、运行服务、托管平台和社区资源放在一张表中;这是一张能力索引,不是单个应用的部署清单。

截图中有三种不同的“并列关系”:

  1. 替代实现:Browser、Swift、Android、Flutter、ESP32 等 Client SDK 按终端选一个;Python 与 Node.js Agents SDK 按 Agent 技术栈选一个。
  2. 开发资产:Starter Apps、UI Components、Docs、CLI 与 Community 帮助开发和展示,通常不是运行时依赖。
  3. 独立服务:LiveKit Server、Ingress、Egress 与 SIP 是可分别部署的服务;采用 Server 不等于必须部署后三者。

15.2 完整 LiveKit 平台的七层架构

层核心对象 / 模块主要职责掌握的权威状态不负责什么
终端产品层Browser、Swift、Android、ESP32 等 Client SDK;Starter Apps;UI Components采集/播放音视频、呈现 UI、加入 Room、发布/订阅 Track、收发 Data/RPC本地设备、权限、实际扬声器播放位置Agent 业务逻辑、SFU 路由、模型推理
媒体接入层WebRTC、ICE、DTLS-SRTP、RTP/RTCP、Opus建连、链路加密、实时媒体传输、丢包与抖动反馈单条 PeerConnection 与本地媒体队列Room 业务身份、Agent 工具权限
Room / SFU 层LiveKit Server、Room、Participant、Track、SFU信令、房间成员、Track 路由、订阅关系、质量控制、Agent dispatch 入口Room 状态、Participant/Track 注册与媒体路由STT/LLM/TTS、Prompt、真实业务动作
Agent 执行层Agents SDK、AgentServer、Worker、Job注册执行容量、接受 dispatch、为会话启动隔离 JobWorker capacity、Job 生命周期终端 WebRTC 接入、Room 路由
会话智能层AgentSession、RoomIO、VAD/turn、tools/MCP音频与转写 I/O、轮次、打断、模型编排、工具调用与会话事件当前 Session、generation、speech handle、模型上下文投影SFU 转发、业务副作用真相
模型与业务层Realtime Model 或 STT→LLM→TTS;Capability Gateway语音理解/生成、推理、权限校验、幂等动作、记忆和审计Provider generation 与业务 receiptRoom 媒体路由
平台运维层Cloud、Server APIs、Redis、TURN、Ingress、Egress、SIP、Insights/OTel托管、扩容、NAT 中继、外部媒体、录制、电话、观测与管理集群路由、部署容量、录制/电话任务、trace产品 UI 与 Agent Prompt

这七层通过两个共享模型连接:媒体侧使用 Room → Participant → Track,Agent 侧使用 AgentServer → Worker → Job → AgentSession → RoomIO。LiveKit 的价值不是某一个 SDK,而是让不同终端、媒体路由、Agent 生命周期和模型管线采用可组合的公共契约。LiveKit overview Rooms, participants, and tracks

15.3 Ecosystem 每个模块的职责、作用与依赖

06-livekit-ecosystem-module-placement.png

图 15-2:LiveKit 生态模块落位图。中间是产品运行时真正经过的语音主链;上方是开发与产品入口;下方是由公网、规模、电话、录制或外部媒体需求触发的控制、扩展与运维面。Starter Apps 与 UI Components 复用相应 Client SDK;多语言 SDK 是替代项,不是累计安装项。该图是基于公开模块职责绘制的编辑性解释,不是 LiveKit 官方部署拓扑。

先用图定位模块所在平面,再用下表确认它的交付形态、依赖和明确边界:

生态模块交付形态核心职责与作用进入哪条链依赖 / 被谁依赖明确边界
Agents SDK:Python / Node.js应用框架与库提供 AgentServer、Worker/Job、AgentSession、RoomIO、模型插件、tools、turn 与 interruptionRoom Track → AI 执行 → Agent TrackRoom 模式依赖 LiveKit Server;也允许自定义 Session I/O不是 SFU,不原生监听任意客户端音频协议
LiveKit Client SDKs各平台客户端库封装 WebRTC、Room 状态、Track capture/render、重连、Data/RPC 与平台媒体 API终端 ↔ Room依赖 LiveKit Server/Cloud;被 Starter/UI 使用多语言 SDK 是替代项,不是累计依赖
ESP32 SDKESP-IDF 组件在受限硬件上实现 LiveKit Participant、双向音频与设备数据微控制器 ↔ Room依赖 LiveKit Server/Cloud 与硬件 capturer/rendererDeveloper Preview;不是使用 Agents SDK 的前提
Starter Apps可运行样板项目演示 token、入房、媒体、转写、Agent 状态和部署组合开发启动路径依赖对应 Client/Agents SDK可复制、可删除;不是 framework runtime
UI ComponentsReact、SwiftUI、Compose、Flutter 组件波形、设备选择、转写、Agent 状态和交互控件展示层依赖相应 Client SDK不参与媒体路由或 Agent 推理
Server APIsNode/Go/Ruby/Java/Python/Rust/PHP/.NET SDK签 token,管理 Room/Participant/dispatch/recording,执行可信控制面操作业务后端 ↔ LiveKit 控制面依赖 Server/Cloud API只需选后端所用语言;不是实时媒体数据面
LiveKit ServerGo 服务进程WebRTC 信令、NAT traversal、Room 状态、Participant/Track、SFU RTP 转发、QoS 与 Agent dispatchClient ↔ Room ↔ AgentClient SDK 与 RoomIO 都依赖它不是模型 Provider,也不执行 Agent tools
LiveKit Cloud托管平台托管 Server、全球网络、TURN、观测以及可选 Inference/Agent 服务完整托管部署替代自建 Server/相关运维不是使用开源 SDK 的强制前提
Ingress独立 OSS 服务将 RTMP、WHIP 等外部媒体转换为 Room Track外部流 → Room依赖 LiveKit Server普通 Client SDK 发布媒体时不需要
Egress独立 OSS 服务录制 Room/Track、合成布局、导出文件或转推直播Room → 文件/直播依赖 LiveKit Server 与存储/目标平台不负责客户端播放
SIP独立 OSS 服务将电话 trunk、DTMF 与呼叫生命周期映射为 Participant电话网 ↔ Room依赖 LiveKit Server 与 SIP provider非电话产品无需部署
Redis外部数据存储 / 消息总线多节点 Room 路由、节点状态与分布式消息Server 集群内部分布式模式需要;单节点不需要不是对话记忆数据库
TURN媒体中继服务ICE 直连失败时中继媒体Client ↔ TURN ↔ Server跨网、防火墙、复杂 NAT 时需要本机/简单 LAN 不一定需要,但完整公网产品必须准备
CLI命令行工具本地启动、token/Room 调试、部署和运维操作开发与运维调用 Server/Cloud API不进入应用数据链
Docs / Docs MCP文档与机器可读知识接口帮助人和 Agent 查询 API、示例与概念开发知识链无 runtime 依赖不部署到产品运行环境
CommunitySlack、X、YouTube、Developer Community支持、案例、讨论和问题排查生态支持无不属于软件架构
Provider pluginsAgents SDK 插件适配 OpenAI、Google、Deepgram、TTS 或自托管模型的事件与能力AgentSession ↔ Model依赖 Provider API必须统一 cancel、tool、truncate 和 usage 语义

15.4 一次完整语音会话怎样穿过这些模块

  1. 业务后端用一个 Server API SDK 签发短期 Room JWT。
  2. Browser/Swift/Android 等 Client SDK 通过信令加入 Room,再以 ICE + DTLS-SRTP 建立媒体连接。
  3. Client 发布麦克风 Track;LiveKit Server 登记 Track 并由 SFU 转发给订阅者。
  4. AgentServer 预先向 LiveKit 注册 Worker;Room 触发 dispatch 后,某个 Worker 接受 Job。
  5. Job 进程以 Agent Participant 加入 Room;RoomIO 订阅用户 Track。
  6. AgentSession 完成 VAD/turn、Realtime 或 STT→LLM→TTS、tools/MCP 与 interruption。
  7. Agent 的工具调用通过 Capability Gateway 执行真实动作并返回业务 receipt。
  8. RoomIO 发布 Agent 音频 Track;SFU 将它转发给 Client SDK 播放。
  9. 客户端掌握物理播放位置;需要精确可听历史时应回传 playout acknowledgement。
  10. Egress、Ingress、SIP、Cloud、Redis、TURN 和 Insights 只在各自触发条件出现时进入旁路或运维面。

15.5 完整平台的最小切片与扩展模块

类型最小完整 Room 模式何时增加
必选替代项一个 Client SDK;LiveKit Server 或 Cloud;Python/Node Agents SDK 二选一;一条模型路径根据终端、托管方式和 Agent 语言选择,不是全装
可信控制面能签发短期 JWT 的最小后端;必要时调用 dispatch/Room API多租户、动态权限、管理后台出现后扩展
产品展示自有 UI 即可希望快速采用官方交互模式时选 Starter/UI Components
媒体旁路无外部流用 Ingress;录制/直播用 Egress;电话用 SIP
网络与规模单节点可无 Redis;网络简单时可能不走 TURN多节点加 Redis;公网弱网必须准备 TURN;多区域再加路由与观测
托管能力可全部自建不想运营媒体网络、Agent 部署或观测时采用 Cloud

十六、本地应用集成:Cardputer 与桌面 App 直接进入 Agent Runtime

16.1 结论:可以绕过 Server/SFU,但直连的是 AgentSession 自定义 I/O

Cardputer、桌面 App 与本地 Agent 都处于同一设备或简单局域网时,如果产品不需要 Room、多 Participant、标准 Client SDK 互通、SIP/录制或公网 NAT 穿透,那么 LiveKit Server、SFU、Client SDK、WebRTC、JWT 与 RoomIO 都可能是多余的媒体中间层。此时可以只复用 LiveKit Agents 的会话与模型 runtime:

Cardputer / Desktop App
        ↕ 自定义本地音频与控制协议
LocalTransportAdapter
        ↕ Custom AudioInput / AudioOutput
AgentSession
        ↕ Provider plugin / tools
Model + Capability Gateway

但必须精确使用术语:标准 AgentServer 默认是 Worker/Job 生命周期与 dispatch 控制面,不是 WebRTC、UDP 或 PCM 音频服务器。 官方 AgentServer 会向 LiveKit Server 注册并接受 Job;若要“客户端直接对接 Agent Server”,需要在 Agent 进程中新增 LocalTransportAdapter,或者由本地宿主直接创建 AgentSession,再把自定义音频 I/O 绑定到 session.input.audio 与 session.output.audio。当前源码只在传入 Room 且未设置外部音频 I/O 时创建默认 RoomIO,这正是直连模式的扩展 seam。Agent server AgentSession source

官方 console 模式已经证明 AgentSession 可以在没有外部 LiveKit Server 的情况下取得本地/TCP 音频 I/O;但其 fake job / console host 是开发工具,不应未经稳定性审计直接当生产协议。生产实现应建立自己的 LocalAgentHost 和公开、可测试的 transport contract。Agents console source

16.2 本地直连架构

05-local-app-direct-agent-runtime.png

图 16-1:Cardputer 与桌面 App 绕过 Room/SFU,直接通过 LocalTransportAdapter 驱动 AgentSession。图中 AgentServer 只表示可选的生命周期宿主;音频入口来自自定义 AudioInput / AudioOutput,不是 AgentServer 原生媒体协议。该图是待实现设计,不是运行态观测。

16.3 Cardputer 与桌面 App 的两种落地形态

本地客户端推荐进程边界音频与控制入口播放出口为什么不需要 LiveKit Server
Cardputer-ADV + Mac AppSwift Mac App 管设备/UI;Python/Node local-agent sidecar 管 AgentSessionADV 加密 UDP 音频 + BLE/GATT 控制 → Mac DeviceGateway → Unix Domain Socket / localhost framed streamAgent AudioOutput → sidecar IPC → Mac 下行队列 → ADV 扬声器ADV 与 Agent 都只服务一台 Mac;不需要 Room 路由、WebRTC 互通或 NAT traversal
纯桌面端 App若语言兼容可同进程;Swift/Electron + Python Agent 通常使用 sidecarCoreAudio/AVAudioEngine/AudioWorklet → UDS/TCP/IPC → LocalTransportAdapterAgent AudioOutput → App 播放队列客户端与 Agent 在同机,系统 IPC 已提供寻址和可靠传输

本地 sidecar 不需要对局域网开放端口。优先使用 Unix Domain Socket;若跨语言库限制必须用 TCP,只绑定 127.0.0.1,再增加随机会话 secret、peer credential 校验、长度上限与 backpressure。Cardputer 到 Mac 的无线链仍需既有配对、认证加密、序号和重放保护。

16.4 LocalAgentHost 需要补齐哪些职责

本地模块职责替代完整 LiveKit 中的什么权威状态
LocalTransportAdapter接收/发送 AudioFrame 与控制事件,处理 framing、版本、backpressure 和连接生命周期Client SDK + WebRTC + RoomIO 的 I/O 接缝连接、frame 序号、generation id
DeviceGatewayCardputer 配对、UDP 解密、jitter buffer、解码/重采样、下行队列终端 Client SDK 的设备与媒体适配设备会话、无线质量、实际播放回执
SessionRegistry以 device/app session id 创建、查找、关闭 AgentSessionRoom + dispatch 的会话发现本地会话唯一性与生命周期
Custom AudioInput将本地 PCM frame 异步推入 AgentSession,提供 attach/detach 与关闭语义RoomIO 的 Participant audio input输入流边界
Custom AudioOutput接收 Agent 音频、排队、flush、回传真实播放位置RoomIO / Client playout 组合输出 generation、queued/played position
LocalAgentHost加载 Agent/模型、创建 AgentSession、监管任务、崩溃恢复和 graceful shutdownAgentServer/Worker/Job 的本地简化形态Session task 与进程健康
Capability Gateway工具 allowlist、系统权限、幂等、超时、receipt 和审计完整平台外的业务后端真实业务动作
Telemetry贯穿 device/session/generation/tool 的 trace 与延迟指标Insights/OTel 的本地实现可诊断证据

16.5 从用户说话到语音回答的直接链路

  1. 本地 App 启动 Agent sidecar,通过 UDS 握手并协商 protocol version、audio format、session id 与能力。
  2. Cardputer 或桌面麦克风产生 frame;LocalTransportAdapter 校验长度、序号与时间戳,必要时做 jitter buffer 和重采样。
  3. Custom AudioInput 将 frame 推入 AgentSession;PTT/VAD/commit/interrupt 作为独立控制事件传入,不能伪装成音频样本。
  4. AgentSession 运行 Realtime Model,或 STT → LLM → TTS;tools/MCP 仍由 Agents SDK 编排。
  5. 真实动作进入 Capability Gateway,使用本地可信身份,不接受模型伪造的 user/device id。
  6. Custom AudioOutput 收到生成音频,附加 generation id,经 IPC 返回 App;Cardputer 路径再由 Mac 封装成无线下行。
  7. 客户端播放并回报 played_sample / played_ms;LocalAgentHost 据此维护 Playout Ledger 与可听历史。
  8. 打断时同时 cancel 当前模型、flush Custom AudioOutput、清空 App/ADV 播放队列,并让旧 generation 的迟到 frame 被 fence 丢弃。
  9. App 或设备断线时关闭对应 AgentSession;Provider 断线只重建模型连接,不重启 DeviceGateway;sidecar 崩溃由 Mac App supervisor 拉起。

16.6 复用了什么,又主动放弃了什么

维度Agents-only 本地直连完整 LiveKit Room 模式
保留AgentSession、Provider plugins、VAD/turn、interruption、tools/MCP、events、usage/tracing以上全部,加上 Room 媒体平台
音频入口Custom AudioInput / AudioOutputRoomIO + Participant Track
会话发现App 自有 SessionRegistryRoom + dispatch
本地身份UDS peer / 配对密钥 / app sessionRoom JWT + Participant identity
网络UDS、localhost TCP 或自有 UDP/BLEWebRTC、ICE、DTLS-SRTP、RTP/RTCP
得到的收益最少进程、最少复制/编码、低延迟、直接拿到播放回执标准多端 SDK、Room/Track、重连、质量统计、多参与者与媒体扩展
放弃的能力Client SDK 互通、SFU、多 Participant、Data/RPC、SIP、Ingress/Egress、Cloud media需要部署 Server/Cloud 与 token/control plane

16.7 用一个稳定 I/O 接口保留未来迁移能力

不要把 AgentSession 直接耦合到 UDP、Swift IPC 或 Cardputer 包格式。先定义应用自己的深接口:

class SessionTransport(Protocol):
    async def receive(self) -> AudioFrame | ControlEvent: ...
    async def send_audio(self, generation_id: str, frame: AudioFrame) -> None: ...
    async def flush(self, generation_id: str) -> PlayedPosition: ...
    async def send_event(self, event: SessionEvent) -> None: ...
    async def close(self, reason: str) -> None: ...
 
# 当前:CardputerTransport / DesktopIPCTransport
# 未来:LiveKitRoomTransport(内部使用 RoomIO)

这样“本地直连 → 完整 LiveKit”只替换 transport adapter;Agent、模型、工具、Capability Gateway、generation fence、可听历史与测试合同保持不变。

16.8 什么时候重新引入 LiveKit Server

出现下列任一明确需求时,Room/SFU 不再是多余层:

  • 同一 Agent 同时服务浏览器、手机、Cardputer、电话或多人会话;
  • 客户端离开本机,需要 NAT traversal、TURN、弱网重连和质量控制;
  • 需要标准 LiveKit SDK、Participant/Track/Data/RPC 语义;
  • 需要 SIP、Ingress、Egress、录制、远程监看或 Cloud;
  • Agent 数量与会话量需要 Worker dispatch、隔离、容量和弹性调度;
  • 希望第三方客户端无需理解自定义 UDP/IPC 协议即可接入。

16.9 推荐实施顺序

  1. Transport loopback:不接模型,验证 Desktop/Cardputer frame → LocalTransportAdapter → 原样 AudioOutput → 播放,测 backpressure、断线和格式错误。
  2. AgentSession fake path:接自定义 AudioInput/Output 与确定性 fake STT/LLM/TTS,验证 session lifecycle、PTT、flush 和 generation fence。
  3. 真实 Provider:只选 Realtime 或一条 cascade,测首音、取消、断线重连与成本。
  4. Cardputer downlink:补 Mac → ADV 音频、jitter buffer、真实播放回执和连续 100 次 PTT。
  5. Capability Gateway:先接一个只读工具,再验证授权、幂等、receipt 与审计。
  6. Production host:sidecar 签名/打包、UDS 权限、crash supervisor、升级、日志与隐私保留策略。
  7. RoomIO adapter PoC:只有产品出现多端/远程信号后,再用同一 SessionTransport contract 实现完整 LiveKit 模式。

一句话结论:本地应用可以直接复用 LiveKit Agents runtime,但不应把 AgentServer 误当成现成音频网关;真正需要新增的是 LocalTransportAdapter 与自定义 AgentSession I/O。


十七、如果我们自己实现一套类 LiveKit 系统

17.1 不建议从零重写 WebRTC 与 SFU

自己实现“基本相似系统”时,最理性的路径是复用成熟 Media Fabric,而不是从 ICE、DTLS、SRTP、NACK、TURN、拥塞控制和跨浏览器兼容开始。可以采用 LiveKit、mediasoup、Janus、Pion 或托管 RTC;自研价值应集中在语音 Agent 的控制闭环。

推荐模块边界:

模块核心接口权威状态
TokenBrokermint(room, identity, grants, ttl)身份与最小 Room 权限
MediaGatewayjoin/publish/subscribe/data/reconnectParticipant / Track
AgentSchedulerregister/offer/assign/drainWorker capacity / Job lease
SessionActoron_audio/on_text/generate/interrupt/close当前会话和 turn
TurnManagerspeech_event/stt_event/eou/commit谁拥有轮次
ModelPipelinepush_audio/generate/cancel/truncateProvider generation
PlayoutLedgerenqueue/played/flush/audible_text用户可听历史
CapabilityGatewayauthorize/execute/status/cancel真实业务动作
ConversationStoreappend/project/checkpoint/restore持久对话投影
TelemetryPlanespan/metric/audio_ref/audit跨层证据

接口要暴露取消与游标,而不能只有 respond(audio) -> audio:

class ModelGeneration(Protocol):
    generation_id: str
    async def audio(self) -> AsyncIterator[AudioFrame]: ...
    async def text(self) -> AsyncIterator[TextDelta]: ...
    async def cancel(self, reason: str) -> None: ...
    async def truncate(self, audible_audio_ms: int, audible_text: str) -> None: ...
 
class AudioOutput(Protocol):
    async def enqueue(self, generation_id: str, frame: AudioFrame) -> None: ...
    async def pause(self, generation_id: str) -> None: ...
    async def flush(self, generation_id: str) -> PlayoutReceipt: ...
    # receipt 必须返回可用于 conversation projection 的播放位置

17.2 Session Actor 的最低状态机

CONNECTING
  → LISTENING
  → USER_SPEAKING
  → ENDPOINTING
  → THINKING / TOOL_RUNNING
  → AGENT_SPEAKING
  → INTERRUPTING
  → LISTENING
 
任何状态
  → RECOVERING
  → 原状态或 CLOSED

每个异步回调都必须带 session_epoch + turn_id + generation_id。Session 重建时 epoch 增加;上一 epoch 的 STT final、LLM token、TTS frame、tool callback 若迟到,只能记录审计,不能改变当前 UI、播放或 conversation。

17.3 Conversation 应保存事件,再投影成模型上下文

推荐事件:

UserSpeechStarted
UserTranscriptUpdated / Finalized
TurnCommitted
ModelGenerationStarted
ToolProposed / Authorized / Completed
AgentAudioEnqueued
AgentAudioPlayed
GenerationInterrupted
AudibleAssistantTextCommitted
SessionReconnected

由事件投影得到三个视图:

  • model_context:下一次生成需要的上下文;
  • user_transcript_view:UI 显示的稳定对话;
  • audit_view:包含被取消生成、工具尝试和错误的完整证据。

不要让一份 mutable chat history 同时承担三种语义。

17.4 推荐生产部署

Mermaid diagram

Room 节点、Agent worker 和模型 endpoint 应尽量同区域。Agent autoscaling 不应只看 CPU:至少组合 active jobs、reserved slots、dispatch wait、model connections、memory 和 event-loop lag。缩容先 drain Worker;SFU 则遵守 Room drain,不能把活跃会话迁移假设成无损操作。


十八、实施路线:从 PoC 到可上线系统

Phase 0:两条模型路径的技术样机

  • 一个 Web 客户端加入 Room、发布麦克风、播放 Agent Track;
  • 一条 STT → LLM → TTS;
  • 一条 OpenAI 或其他 Realtime Model;
  • 只做一个无副作用查询工具;
  • 采集各阶段 timestamp,建立首音延迟瀑布图;
  • 在耳机与外放下人工测试打断。

退出条件:两条路径均能连续对话、可手动/自动打断,且 Trace 能解释一次慢请求。

Phase 1:会话一致性

  • 实现 turn/generation/session epoch;
  • 接入 RoomIO playout receipt 或客户端 playout ack;
  • 验证 cancel 后迟到 frame 全被 fencing;
  • conversation 只提交 audible assistant text;
  • 完成 false interruption pause/resume;
  • Provider 断线时重建连接并重放最小上下文。

退出条件:连续 100 次随机位置插话不出现旧音频复活,模型不引用未播放内容。

Phase 2:业务与安全

  • Room token broker、租户隔离、Capability Gateway;
  • tool schema、权限、确认、幂等、receipt 和 audit;
  • 长任务迁入持久 workflow;
  • PII redaction、recording consent、retention 与 deletion;
  • E2EE 是否包含 Agent endpoint 的明确威胁模型。

退出条件:重复/越权工具测试、断线重试和审批绕过测试全部通过。

Phase 3:多渠道与生产可靠性

  • SIP inbound/outbound、DTMF、transfer、hangup;
  • Redis、多 SFU、多 Agent Worker、TURN;
  • load/drain、job crash、Redis/TURN/provider fault injection;
  • 真实设备与网络矩阵;
  • 以 P95/P99 和 QoE SLO 驱动扩容。

退出条件:在目标并发、区域和设备矩阵下达到 SLO,发布与缩容不主动中断活跃 Room。


十九、验收矩阵

领域场景通过标准
客户端声学外放时用户插话Agent 不被自身回声反复打断,用户首个有效词后迅速停播
音频连续性5% 丢包、100 ms jitter可理解且不无限积压;恢复后无爆音和旧音频复活
Room 恢复信令短断Participant/Track 恢复,UI 不重复显示旧 turn
完整重连网络切换 Wi-Fi → 4G重建 PC、重发 Track,Session 明确恢复或重开
Dispatch冷 worker / 满负载不超卖 reserved slot;可选其他 Worker;超时有明确错误
Job 隔离单 Job crash / memory limit其他会话不受影响;当前会话按产品策略重建或结束
Turn detection犹豫、长停顿、短回答不频繁抢话,最大等待有界
Backchannel“嗯/对”与咳嗽可 pause 后恢复,不永久丢失回答
真打断任意播放位置连续插话generation、queue、context 三处一致取消/截断
迟到事件cancel 后注入旧 TTS frame/tokengeneration fence 全部丢弃
工具幂等success 后连接断开并重试业务副作用只发生一次,Agent 查询 receipt 后播报
权限模型伪造 user_id/tenant_idGateway 仅使用可信 Session 身份并拒绝越权
Realtime ProviderWebSocket 中断有界重试,远端 chat context 与本地投影重新对齐
SIP入呼、DTMF、转移、挂断Room/SIP Participant/Agent lifecycle 一致,不遗留 Job
隐私recording off / deletion音频、转写、trace、日志均遵循配置和保留策略
DrainSFU/Worker 发布升级新会话不进入 draining 实例,活跃会话按契约完成

二十、最终判断

  1. LiveKit 是实时 AI 的媒体与运行时平台,不是语音基础模型。 它把用户、Agent、电话和设备统一成 Room Participant,把任意模型接在 Agent 之后。
  2. 它真正的架构护城河是跨层状态编排。 SFU 本身重要,但 AgentSession、Worker dispatch、打断、playout ledger 和 conversation truncation 才把 RTC 变成可用的语音 Agent 平台。
  3. 原生 Realtime Model 没有消灭 Agent runtime。 在 LiveKit 拓扑中,模型仍由 Agent 进程桥接;工具、身份、房间、多渠道和可听历史依然在模型外。
  4. 自然打断必须同时取消生成、清空物理播放并修正语义历史。 只做 VAD 或 response.cancel 都不完整。
  5. LiveKit 的代价是额外 hop 与更大的运维面。 单用户、单 Provider、最短路径应用可能更适合客户端直连 Realtime;平台化、多渠道、可替换和自托管场景才充分发挥 LiveKit 价值。
  6. 自建同类系统最应该复用媒体底座,自己掌握控制闭环。 Session Actor、Turn Manager、Playout Ledger、Capability Gateway、Conversation projection 与 Telemetry 才是业务差异化所在。
  7. LiveKit 生态是菜单,不是必须全装的发行版。 远程、多参与者和多渠道产品采用 Client SDK → Server/SFU → RoomIO → AgentSession 的完整平台链;Cardputer-ADV + Mac 或单机桌面 App 若没有这些网络与互通需求,则可省去 Client SDK、WebRTC、LiveKit Server、SFU、Room 与 RoomIO,只保留 Agents SDK、AgentSession、模型插件、tools,并用 LocalTransportAdapter + Custom AudioInput/AudioOutput 接入本地音频。这里的 AgentServer 仍是可选的生命周期宿主,不是现成的 PCM/UDP 媒体端点。

一句话概括:

OpenAI Realtime 更像可直接连接的实时语音智能引擎;LiveKit 更像让任意智能引擎进入真实多人、多设备、多渠道世界的实时操作系统内核。


Source Manifest

本报告的 5 张原创机制图、完整生成提示词、SHA-256 与逐图视觉验收记录见 ImageGen Manifest。这些图是基于下列固定源码与官方文档的编辑性解释,不是 LiveKit 官方架构图或运行态观测。

A. 固定源码快照

来源固定版本 / commit使用范围许可证验证方式
livekit/livekitServer v1.13.5; 788d4c354474383956067e3a22ffba88dd4803e4Room、Participant、Transport、SFU Receiver/DownTrack、RedisRouter、signal bridge、AgentService、AgentDispatchServiceApache-2.02026-08-23 shallow clone;逐文件 rg / line-level read;版本与 release 核对
livekit/agentsPython Agents 1.7.0; da6af86ac640a3bc54585764e64321d7048c1c16AgentServer/Worker、Job process pool、AgentSession、AgentActivity、RoomIO、自定义 Session I/O、pipeline nodes、OpenAI Realtime pluginApache-2.02026-08-23 shallow clone;2026-09-01 复核 AgentSession 外部 AudioInput/AudioOutput 与 CLI console 的无 Room I/O 路径
livekit/client-sdk-jsJS SDK 2.22.0; f3732d14bf3162981e4a57d1daa7305a1f3ab7b5getUserMedia、AEC/NS/AGC defaults、PCTransportManager、RTCEngine reconnect、RemoteAudioTrackApache-2.02026-08-23 shallow clone;逐文件 rg / line-level read;版本与 release 核对

B. LiveKit 官方文档

来源用于支持访问日期
Agents overviewAgent 作为 Room Participant、WebRTC bridge、模型插件和工具2026-08-23
LiveKit overviewRoom / Participant / Track 与平台边界2026-08-23
Connecting to LiveKitaccess token、room/identity/grants、建连职责2026-08-23
Agent server 与 lifecycleWorker 注册、Job 生命周期、dispatch 与 recovery2026-08-23
Agent dispatchautomatic / explicit dispatch2026-08-23
Agent sessionAgentSession 角色、I/O、tools、turn options2026-08-23
AgentSession source 与 session I/O source外部 AudioInput/AudioOutput 可直接绑定到 Session;只有 Room 模式才需要默认 RoomIO2026-09-01
CLI console source本地/TCP AudioInput/AudioOutput 与 unregistered fake Job 证明无 Server/Room I/O 在技术上可行;仅作为开发工具证据,不当作生产传输协议2026-09-01
Running LiveKit locallymacOS 安装、本地 livekit-server --dev、默认 127.0.0.1:7880 与 LAN bind 边界2026-09-01
LiveKit Swift SDKiOS/macOS Client、Room/Track、音频与数据能力,以及本机 Gateway Participant 的实现入口2026-09-01
Publishing audio tracks自定义 audio source、PCM frame、发布 Track 与内部发送缓冲语义2026-09-01
Track managementTrack / TrackPublication、publish / subscribe 与 mute 边界2026-09-01
Data packets 与 RPCPTT、状态、播放回执与设备控制的数据面选择2026-09-01
Turn detection and interruptionssemantic/VAD/STT/manual/model turn modes 与打断行为2026-08-23
Pipeline modelsSTT-LLM-TTS、Realtime、half-cascade 的选择边界2026-08-23
OpenAI integrationOpenAI LLM/STT/TTS/Realtime plugin 的官方用法2026-08-23
Distributed multi-regionRedis、room affinity、signal bridge、drain、多区域2026-08-23
Encryption overviewmedia/data E2EE、key distribution、signaling boundary2026-08-23
Telephony introductionSIP Participant、trunk、dispatch rule 与自托管 SIP 边界2026-08-23
Testing and evaluation文本行为测试、simulation 与音频 E2E 的边界2026-08-23
Export traces 与 Agent insightsOpenTelemetry 导出与 Cloud Insights 边界2026-08-23
Agent frontends 与 Starter appsClient SDK、Starter App、UI Components 是按平台选择的入口,不是累计依赖2026-09-01
ESP32 microcontrollers 与 Hardware & devicesESP32-S3/P4 支持、Track 限制、最小 Room 状态、capturer/renderer 与 AEC 责任2026-09-01
client-sdk-esp320.3.10、Developer Preview、Opus/AEC/Data/RPC、固定版本要求2026-09-01
ESP32 custom hardware example 与 sdkconfig非预置开发板的 I²C/I²S/codec 适配方法,以及示例板的 PSRAM 配置2026-09-01
Self-hosting overviewCloud / self-hosted 边界,以及 Ingress/Egress/SIP 等独立可选服务2026-09-01

C. 关联综合、实现与对照材料

来源用途
实时语音 Agent 端到端架构媒体、会话、业务行动、观测治理四平面综合
OpenAI Realtime API 端到端实现逆向分析对照客户端直连模型、sideband、Conversation 与闭源边界
Cardputer-ADV 硬件与资源边界ESP32-S3、512KB 片上 SRAM、8MB Flash、无额外 PSRAM及实时音频资源心智模型
Cardputer Bridge 实机实现固定 v0.10.5 的 ES8311/I²S 音频、加密 UDP、Mac 虚拟麦克风、BLE、OTA 与 Harness 证据
用户提供的 LiveKit Ecosystem 截图 88bd19fe…4888记录生态页面的视觉呈现,并作为“能力目录容易被误读为部署依赖图”的界面证据;原图归档于 references/livekit-ecosystem-user-screenshot.png,1704×844;接收日期 2026-09-01

D. 未执行与未知边界

  • 未使用真实 LiveKit Cloud 项目或 OpenAI/Google 等 Provider 账户执行端到端建连。
  • 未在浏览器、iOS、Android、蓝牙、外放和 SIP 真机上测量 AEC、打断和首音延迟。
  • 未部署多节点 LiveKit、Redis、TURN、SIP 与 Agent pool,也未做故障注入或压测。
  • 未实现本文建议的 ADV → Mac Device Gateway → LocalTransportAdapter → Custom AudioInput/AudioOutput → AgentSession → 模型/工具 → ADV 扬声器闭环;当前只有既有 ADV → Mac 麦克风链证据,图 16-1 是待实现设计而非运行态观测。
  • Cloud Inference、增强噪声消除、Agent Insights 后端、全球调度和 SLA 只按公开文档描述,没有内部源码证据。
  • 固定源码中的默认值是该版本实现,不应当作未来稳定 API;生产决策需重跑版本审计与 E2E。