# 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 认证生产化收尾。