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. 选型决策树
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 认证生产化收尾。