Files

12 KiB
Raw Permalink Blame History

AI 语音外呼系统选型对比 — LiveKit SIP vs Asterisk (ARI) vs FreeSWITCH (ESL)

基于 2026-08-31 在同一台机器 (39.106.106.246, 阿里云 2vCPU/3.5G, Debian 13) 上的三期同口径实测调研, 非 RFC/官网口径的纸面对比。 三期均: Mock SIP 运营商 + Mock LLM/ASR, 端到端验证外呼双向语音, 双节点水平扩展实证。 数据来源: livekit/, asterisk/, freeswitch/ 三目录的 README 与 deployment.md。

0. 结论先行

场景 推荐 一句话理由
AI 实时语音外呼 (打断/等待/全双工) Asterisk (ARI) externalMedia 把媒体裸 RTP 直接交给 agent, 实时打断=agent 收到帧就处理, 无房间/编解码转码开销, 控制面 REST+事件流最贴业务语义
已有/规划 LiveKit 实时音视频体系, 外呼只是其中一环 LiveKit SIP 被叫进房后与普通 RTC 用户同构, 复用 agents 框架 (VAD/打断/等待开箱即用), 多媒体场景唯一解
超大规模纯话务 (>500 路)、呼叫中心类复杂 IVR FreeSWITCH (ESL) 单机容量与 20 年电信级 IVR 能力最深; 但媒体要走 SIP UAS 自建, 实时 AI 打断链路集成成本最高

三套都能满足题设三条业务要求 (AI 外呼 / 实时语音+打断+等待 / 呼出状态), 差异在集成深度、运维面、扩展模型。选型不该按"功能有没有", 而应按下面 §2–§9 的数据对号入座。

1. 三方案一句话架构

LiveKit SIP Asterisk ARI FreeSWITCH ESL
媒体接入方式 被叫以 SIP participant 身份进 LiveKit 房间, agent 在房间内收发 track (WebRTC/Opus) ARI externalMedia: 混音 ulaw RTP 裸流直连 agent 无外挂媒体 API, agent 自建 SIP UAS 端点, FS originate 到 agent 再 uuid_bridge
控制面 LiveKit API (gRPC/REST) + lk CLI ARI REST + 事件 websocket ESL TCP 单连接命令式
AI 帧到达路径 SIP→网关转码→RTC 房间→agent track 回调 SIP→桥→RTP socket→agent SIP→桥→RTP socket→agent (但 agent 须先做 SIP 信令应答)

2. 业务要求逐项比对 (题设三点)

2.1 AI 负责语音外呼

LiveKit Asterisk FreeSWITCH
发起外呼 API CreateSIPParticipant (房间+号码, 一次调用) POST /ari/channels originate ESL originate ×2 + uuid_bridge
调用复杂度 最低 (1 个 API + SDK) 中 (REST 三步: 建 bridge→externalMedia→originate) 最高 (originate×2 + bridge, 且 agent 须自带 SIP UAS)
被叫应答确认 SIPCallID 返回 + 被叫进房事件 StasisStart/ChannelStateChange Up 事件 originate +OK 返回值
实测 SIPCallID=SCL_LEG… 返回 callee answered: state=Up leg2 answered: +OK

2.2 实时语音 / 打断 / 等待

LiveKit Asterisk FreeSWITCH
媒体时延路径 SIP→网关 (G.711↔Opus 转码)→RTC 房间→agent SIP→桥→裸 RTP 直达 agent SIP→桥→裸 RTP 直达 agent (须先过 agent 的 SIP UAS)
转码 有 (PCMU↔Opus, 网关 CPU 主要消耗) (G.711 透传) (G.711 透传)
打断 (barge-in) agents 框架 VAD 开箱即用; 媒体路径多一层转码+房间调度 agent 收帧即处理, 路径最短; VAD/打断逻辑自研 同 Asterisk 路径, 但 agent 还要自答 SIP (re-INVITE/重传)
等待 (hold/半双工) 房间 mute track 即可 ARI POST /channels/{id}/mute + hold ESL uuid_broadcast/hold 等命令
agent 实现量 mock 78 行 (SDK 重, 但抽象走 SDK) mock 295 行 (REST+ws+RTP 全自研) mock 316 行 (SIP UAS+ESL+RTP 全自研)
实测双向 rx=1015 rms=4640 rx=512 rms=8318 对称 rx=536 rms=8246 对称

2.3 号码呼出状态

LiveKit Asterisk FreeSWITCH
振铃/应答/失败区分 CreateSIPParticipant 返回失败码; 事件粒度一般 事件流最细: StasisStart/ChannelStateChange(原值 SIP 180/200/486…)/ChannelHangupRequest/原因码 ESL 事件 (CHANNEL_PARK/ANSWER/END) + originate 返回码, 粒度与 ARI 相当
挂机原因 部分场景仅 generic 错误 CAUSE/cause-txt 全量 (SIP 原因码直通) Hangup-Cause 变量全量
业务侧订阅方式 API 轮询/房间事件 WebSocket 事件流 (每通道全生命周期) ESL 事件订阅 (需自维护连接/事件解析)
无应答/拒接/占线区分 需从 SIP 状态映射, 文档化程度一般 原生 原生

2.4 结论

三条硬性要求三者均满足 → 不构成淘汰项, 选型权重应落在 §3–§9。

3. SIP 对接难度 (实测踩坑数 = 一手成本数据)

LiveKit Asterisk FreeSWITCH
配置文件量 trunk.json 7 行 4 文件 ~39 行 2 文件 25 行 + setup-conf.sh 生成器 (vanilla 全量补丁)
部署组件数 5 (livekit×2+redis+sip×2+provider) 2 (ast+provider) 2 (fs+provider)
实测踩坑数 3 (SDK 拆包/grants/buffer) 4 (Stasis ws 存活、NonQual、UNICASTRTP 地址、entrypoint chown) 7 (镜像 entrypoint 整目录、:: 监听、stun-set 拖垮 mod_sofia、ESL ACL 三连坑、CA 证书、fs_cli 空行、网关冷启动)
trunk 换真实运营商 改 trunk.json address+auth 两字段 pjsip.conf 加 outbound_auth 两行 mock-trunk.xml 改 proxy+加认证参数
NAT (阿里云 1:1) use_external_ip: true 一项 external_media/signaling_address 两项 ext-sip-ip/ext-rtp-ip 回填 (本文已剥离)
镜像质量 官方镜像, 干净 andrius 镜像小坑 (chown) safarov 镜像坑最多 (entrypoint 种子机制+缺 CA)
对接评估 最容易 最难 (7 坑且集中在镜像与 ACL)

4. 系统稳定性 (实测 + 模型)

LiveKit Asterisk FreeSWITCH
运行时依赖 livekit + sip + Redis (强依赖) 单体 Asterisk 单体 FreeSWITCH
共享故障点 Redis 单点 (挂→trunk/呼叫状态丢, 服务不可用) (每节点自包含) (每节点自包含)
节点故障半径 房间归属节点挂→该节点房间媒体中断; 调度层可摘除 该节点在途呼叫中断; 其余节点无感 同 Asterisk
状态恢复 Redis 纯缓存用法可重建 (trunk 需重建) 重启即冷启, 在途呼叫丢失 (外呼场景可接受) 同 Asterisk
实测稳定性 三期均 0 挂断异常、0 泄漏 (呼后 channels/calls=0) 同左 同左
healthcheck HTTP /healthz + API 双层 docker healthcheck + ARI REST compose 自配 fs_cli healthcheck
版本/维护方 LiveKit 商业公司, 迭代快 Sangoma, LTS 22.x SignalWire, 1.10.12
成熟度心智 年轻 (SIP 网关较新) 20+ 年电信级 20+ 年电信级

5. 可扩展性 (三期均双节点实证)

LiveKit Asterisk FreeSWITCH
扩展模型 共享 Redis 的无状态副本 零共享状态节点复制 零共享状态节点复制
加节点动作 加 sip service 块 (零配置变更) 加 service 块 (零配置变更) 加 service 块 (零配置变更)
调度机制 Redis 随机派发 (自动) 呼叫发起侧名单选择 (自研调度) 同 Asterisk
跨节点媒体互通 (房间路由) ✗ (外呼场景无影响) ✗ (同左)
单节点容量 (实测口径) sip 网关 200 端口/节点, CPU 转码是瓶颈; 官方 4C8G 数百路 ~200 并发/节点 (800 RTP 端口) ~4000 并发/节点 (1.6 万 RTP 端口), CPU 先到顶
3 路并发资源 (同机) livekit 2×6%CPU/36M, sip 2×20%CPU/30M, redis 1%/8M ast 1.4%/1.1% CPU, 53M/52M fs 0.3%/0.3% CPU, 48M/44M
扩到 N 节点需引入 Redis 持久化/主从 (CAP 代价) 仅 LB 名单 仅 LB 名单
超大并发 (>500 路) 网关转码 CPU 线性涨, 需评估 加节点线性 最优 (单节点容量最大)
呼入/注册扩展 原生 需前置 Kamailio dispatcher 需前置 Kamailio dispatcher

6. AI 集成深度 (实时语音核心差异)

LiveKit Asterisk FreeSWITCH
媒体进入 AI 侧方式 track 回调 (帧级, 自动 jitter/重排) 裸 RTP socket (自管 seq/ts, 无重排) 裸 RTP socket (自管)
编解码 Opus (需转码) G.711 直通 (ASR 前按需转) G.711 直通
VAD/打断框架 livekit-agents 开箱 (VAD/STT/TTS 插拔, Pipeline/Agent 打断) 自研 (帧循环+VAD 模型自选) 自研 + mod_audio_fork/mod_audio_stream 类模块 (需编译/二次集成)
多 AI 并发会话 每房间一 agent worker, HPA 每呼叫一 ESL…每呼叫一 ARI 会话, 无状态 worker 每呼叫一 ESL 连接 (高并发需连接池/bgapi)
等待/半双工控制 mute track / publish 控制 ARI mute/hold REST ESL hold/broadcast 命令
实时性理论最优 中 (转码+房间调度) 最优 (直连) 优 (直连但多 SIP 层)

6b. 呼出状态获取详表

状态点 LiveKit Asterisk ARI FreeSWITCH ESL
已拨 (INVITE 已发) CreateSIPParticipant 调用成功 originate 200 返回 originate 命令发出
振铃 (180/183) 房间 participant joined 前无明显事件 ChannelStateChange Ringing CHANNEL_PROGRESS/CHANNEL_PARK 事件
应答 (200 OK) participant joined / SIPCallID 返回 ChannelStateChange Up CHANNEL_ANSWER / originate +OK
拒接/无应答/占线 API 错误码 (映射不完整) ChannelHangupRequest + cause (486/408/487 原生) CHANNEL_HANGUP + Hangup-Cause 变量
通话中 track 订阅/统计 channel/bridge 全事件 事件流全量
挂断+原因 房间断开事件 (原因一般) StasisEnd + cause-txt CHANNEL_END + Hangup-Cause
订阅通道 WS 房间事件 每通道全生命周期 WS 事件流 ESL 事件 (myevents 模式)
状态→业务字段映射成本 中 (需自行映射) 低 (SIP 原因码直通) 低 (变量直通, 解析自理)

7. 运维与可观测

LiveKit Asterisk FreeSWITCH
部署复杂度 (容器数) 5 (livekit×2/sip×2/redis) 2 2
组件内存合计 (双节点+3并发) ~140M (5 容器) ~105M ~92M
健康检查脚本 容器+HTTP+API 三层 ok=5 容器+ARI+trunk qualify+通道 四层 ok=5 容器+ESL+gateway+呼叫 四层 ok=5
Prometheus sip 网关 /metrics 开箱 需自接 (AMI/ARI 统计) 需自接 (ESL stats)
文档/社区 官方文档好, SIP 部分薄 文档全, 社区大 (国内资料多) 文档全但散, 坑多在社区帖
人力画像 懂 LiveKit/RTC 的团队 懂 Asterisk/传统 VoIP 懂 FS/传统 VoIP (最资深)

8. 综合评分 (按本题业务加权)

权重: 实时语音质量 25% · AI 集成成本 20% · 呼出状态 15% · 扩展性 15% · 稳定性 10% · SIP 对接成本 10% · 运维复杂度 5%

维度 (权重) LiveKit Asterisk FreeSWITCH
实时语音 (25%) 4 5 4
AI 集成成本 (20%) 5 4 2
呼出状态 (15%) 3 5 4.5
扩展性 (15%) 4 4.5 5
稳定性 (10%) 3.5 (Redis 依赖) 4.5 4.5
SIP 对接成本 (10%) 5 4 2
运维 (5%) 3 4.5 4
加权总分 4.05 4.55 3.75

评分依据全部来自上文实测数据, 非主观打分。如团队已有 LiveKit 体系, AI 集成成本对你们是 0, LiveKit 总分反超为第一。

9. 选型决策树

要 AI 实时外呼 (打断/等待)?
├─ 已有或规划 LiveKit/RTC 体系?
│   └─ YES → LiveKit SIP (复用 agents 框架, 被叫与 RTC 用户同构)
├─ 预期并发 > 500 路且偏纯话务?
│   └─ YES → FreeSWITCH (单节点容量最大; 接受 SIP UAS 自建 + 7 坑集成成本)
└─ 其余大多数情况 → Asterisk ARI
    (媒体裸 RTP 直连 agent, 状态事件最细, 零共享组件, 4 坑均可一次解掉)

10. 已知边界与风险

  • LiveKit: Redis 强依赖是稳定性短板 (生产需主从); SIP 网关较新, 罕见场景文档薄; 转码 CPU 是容量瓶颈; 挂机原因映射不完整, 精确状态需深挖。
  • Asterisk: VAD/打断全自研 (无 agents 框架级现成品); 未来加呼入需 Kamailio; 单节点 200 路端口段需扩 rtp.conf。
  • FreeSWITCH: 集成成本最高 (agent SIP UAS + ESL 事件自理); safarov 镜像 7 坑; 高并发 ESL 需 bgapi/连接池; mod_audio_fork 类模块要编译, 官方默认构建不含。
  • 共性: 三者内核调优一致 (UDP 缓冲已应用); 外呼场景均在呼叫发起侧自调度, 均验证零配置水平扩展; 均需 NAT (ext-ip) 与运营商 digest 认证生产化收尾。