← 调研中心 VOICE QUALITY · UPDATED 2026-09-05

Inbound AI Contact Center · FreeSWITCH · MiniMax TTS

多呼叫中心桥接
语音质量监控方案

把“某一端卡顿”从主观投诉变成可定位的证据链:同一通话串联 TTS 分块、每个 FreeSWITCH call leg、逐跳 RTP/RTCP、播放缓冲和终端录音。

48 SOURCES2 EXECUTABLE RUNBOOKS11 ABLATION GROUPS16 TEST SCENARIOS
证据边界

本页是公开资料、GitHub 仓库和社区个案形成的参考方案,未接入你的现网。操作手册固定到 HOMER 11.0.336、HEPipe commit 5895a6c 与 VoIPmonitor commit 9dfb2fc;FreeSWITCH 版本、codec/ptime、SRTP、direct media、MiniMax 接入方式和具体异常侧仍需现场确认。

01 · Decision

不要选一个工具;先建立相邻 hop 的比较能力

平均 MOS、节点 CPU 或一份 CDR 都会丢失局部断续和因果顺序。最小正确方案是让每个观测点都能回答:上一跳什么时候产出、这一跳什么时候收到、缓冲是否归零、下一跳发出了什么。

推荐组合

A → B/C → D 分阶段混合

  • A:TTS Gateway 分块埋点 + FreeSWITCH ESL/CDR + Prometheus/日志/trace;
  • B/C:HOMER/HEPipe 或 VoIPmonitor 增加逐跳 SIP/RTP/RTCP 证据;
  • D:SIPp 主动呼入 + 异常 PCM/PCAP 抽样,补最终可听真值。

一个稳定主键

conversation_id 串联 MiniMax trace_id/session_id、SIP Call-ID/X-cid、FS UUID、RTP SSRC/五元组和录音。桥接后 Call-ID 可能改变,不能靠单字段硬拼。

核心判断:哪一跳先出现差异,问题就在最后一个正常观测点与第一个异常观测点之间。证据不足时标记 unlocalized,不要直接归因 MiniMax 或某台 FreeSWITCH。

02 · Evidence boundary

官方事实、仓库能力和参考重构要分开

官方披露

MiniMax 有会话字段

WebSocket 返回音频、trace_id、session_id、is_final 与结束统计;公开 schema 没有逐块业务序号和生成时间轴,需客户端自建。

官方披露

FreeSWITCH 有每流计数

RTP 入/出 packet/bytes、skip、jitter packet 等是只读诊断变量;RTCP 可按配置启用。

仓库自述

HOMER / VoIPmonitor 能补网络视角

前者侧重 HEP、呼叫流与可选 VQRTCP/SIPREC;后者把 RTP 质量、PCAP 和录音做得更一体化。

仓库自述

SIPp 与 mod_audio_stream 补真值

SIPp 可做周期合成呼入;mod_audio_stream 可从 media bug 旁路 L16 PCM,但必须控制背压和版本/edition 边界。

社区个案

CDR jitter 字段不能盲信

FreeSWITCH 邮件列表有人列出 XML CDR jitter 字段,同时明确说“不知道准确性如何”;需用当前版本与 PCAP 校准。

尚未确认

你的真实媒体拓扑

版本、codec、ptime、转码、SRTP、direct media、jitter buffer、MiniMax 协议和异常侧都仍需现场盘点。

03 · Reference architecture

五个观测点,把同一通电话还原成一条证据链

媒体主链不被监控组件阻塞;所有观测异步进入统一关联层。O1–O5 的节点、字段和采集方式可按实际拓扑扩展。

O1 · PROVIDERMiniMax TTStrace/session、音频块、结束统计
O2 · GATEWAY解码与播放缓冲local seq、chunk gap、audio ms、buffer、underflow
O3 · LEG AFreeSWITCH AESL、CDR、codec/ptime、RTP out
O4 · LEG BFreeSWITCH BRTP in/out、RTCP、转码、jitter buffer
O5 · AUDIBLE运营商 / 终端主动探针、终端录音、最终可听异常

证据存储

Prometheus 聚合指标;日志/trace 存事件;短 TTL 对象存储保存异常 PCAP、双轨 WAV 和哈希。

统一关联与相邻 hop 差分

conversation_id + leg_id + stream_id + window。把块时间线、call flow、RTP 序号与最终录音同屏展示。

告警与取证

先告警症状,再给疑似组件;证据不足时自动提升该通话的音频/PCAP 抽样。

完整架构图:独立页面采用 doc-wide 视图,标明参考重构与复杂度取舍。

打开全宽架构图 →

04 · Metrics contract

从“首包到了”推进到“缓冲没有断、下一跳真的发了”

MiniMax / TTS Gateway

first_audio · interarrival · decoded_audio_ms · buffer_ahead · underflow
  • 每块本地编号并记录单调时钟;
  • 用解码后的样本数算可播放时长;
  • 保存 trace/session 与本地 generation 映射;
  • TTFB 正常但 buffer 归零仍是卡顿。

FreeSWITCH 每个 leg

uuid · bridge · codec · ptime · rtp in/out · skip · jitter · RTCP
  • ESL 负责实时生命周期;
  • CDR 负责挂断后的最终汇总;
  • 累计计数转成 1–5 秒 interval delta;
  • 同时关联 CPU、run queue、NIC drop。

逐跳 RTP/RTCP

seq gap · duplicate · reorder · timestamp · SSRC · burst loss
  • FS-A 出站对比 FS-B 入站;
  • 关注 max delta 和局部 burst,不只均值;
  • RTCP/XR 只在端点实际生成时有效;
  • 抓包器自身 drop 必须单独可见。

PCM / 可听证据

near silence · frozen frame · discontinuity · clipping · audible onset
  • 仅异常或小比例抽样,避免全量旁路;
  • 确定性 gap/freeze/clipping 先于模型分;
  • NISQA/DNSMOS 只作趋势补充;
  • 双轨角色和录音完整性必须校验。

播放缓冲是 TTS 卡顿的关键真值

更新公式max(0, buffer_before − elapsed_wall_ms) + decoded_audio_ms
欠载事件speech_expected && buffer_before − elapsed_wall_ms ≤ 0
候选阈值max(3 × 正常 p99 块间隔, 经事故校准的可感知下限)

候选阈值只是校准起点,不是生产默认值。不同模型、区域、codec、ptime 和初始 buffer 会改变正常分布。

05 · GitHub and community options

四条实施路线,以及每条路线看不到的东西

AGPL · 11.0.336

B · HOMER + HEPipe

FreeSWITCH 原生 HEP、X-cid 关联 B2BUA,HEPipe 把 ESL/RTCP 送入 HEP;HOMER 11 统一 ingest、DuckLake、API 与 UI。

  • 强项是 SIP call flow 与跨节点关联;
  • HEPipe 固定 5895a6c,仍按实验性组件门禁;
  • 没有 RTCP/媒体源时不会凭空产生听感。
下方有完整 runbook
GPL-2.0 · 9dfb2fc

C · VoIPmonitor

通过 SPAN/TAP/ERSPAN/SBC 镜像采集 SIP/RTP/RTCP,提供 MOS、jitter、loss、PCAP;Web GUI 另行商业采购。

  • 媒体视角成熟、取证一体化;
  • GitHub 无当前 release,按 commit 锁定;
  • SRTP/direct media、存储与隐私要算。
下方有完整 runbook
GitHub · GPL/MIT 混合

D · 主动探针 + PCM 抽样

SIPp 周期呼入已知语料;异常通话用 `mod_audio_stream` 或 SIPREC 旁路 PCM。

  • 能验证真正端到端回归和局部断续;
  • 合成探针不覆盖全部真实用户长尾;
  • 旁路背压、并发、号码和合规需门禁。
上线门禁与疑难故障
工具真正适用不能单独证明许可/边界
Wireshark单次 PCAP 的 sequence/delta/jitter/skew、错误时间戳和插入静音取证常驻告警与统一业务关联官方工具
prometheus-freeswitch-exporter节点、通道、网关、ESL 健康基线可听卡顿和逐跳 RTPApache-2.0;活跃度现场评估
NISQA录音/切片的 overall 与 discontinuity 等辅助分卡顿发生在哪一跳代码 MIT;预训练权重 CC BY-NC-SA
DNSMOS降噪/整体语音质量的补充分数TTS buffer 欠载和 RTP 序号缺口DNS Challenge 代码 MIT;当前集成文件复核
Pipecat MiniMax adapter现有 TTFB/usage 与 frame 处理的埋点参考trace/session、块间隔、buffer underflow作为代码参考,不等于现网方案

06 · Executable runbooks

HOMER/HEPipe 与 VoIPmonitor:从安装到回滚

下面的命令用于隔离 POC 节点,不代表已在你的现网执行。每条路线都区分官方命令、本文参考配置和必须现场确认的边界;生产上线前仍要按你们的 FreeSWITCH 版本、网络与合规要求评审。

共同前提:先画清 FS-A / FS-B / SBC / carrier 的 SIP 与 RTP 实际路径,确认 NTP、codec/ptime、SRTP、direct media、镜像方向和 10 条正常 + 5 条故障样本。两个工具都看不到 MiniMax chunk 与播放 buffer,不能替代 A 路线埋点。
RUNBOOK B · HEP / SIP / RTCP

HOMER 11 + FreeSWITCH HEP + HEPipe

适合跨呼叫中心看 SIP ladder、B2BUA 两腿关联和 FreeSWITCH RTCP。HOMER 11 已是 ingest + DuckLake + API + UI 一体化,不应再照搬 HOMER 7/10 的旧栈教程。

REPRODUCIBLE SNAPSHOTHOMER 11.0.336
93fdb78 · 2026-08-28
HEPipe 5895a6c
01

部署点与端口

每台 FS 的 mod_sofia 把 SIP 以 HEP3 发往 HOMER;本机 HEPipe 通过回环 ESL 8021 读取 RTCP event,再以 HEP UDP 发往 HOMER。仅允许已知 FS 源访问 9060;UI 8080 与 metrics 9090 只对管理/监控网开放。

FS-A mod_sofia --HEP3/SIP--┐
FS-A ESL:8021 -> HEPipe ---┼--UDP:9060--> HOMER 11
FS-B mod_sofia --HEP3/SIP--┤             ├─ UI :8080
FS-B ESL:8021 -> HEPipe ---┘             └─ metrics :9090
02

安装正式发行包并核验 SHA-256

官方发布资产 AMD64 deb 的 SHA-256 来自 GitHub Release API;ARM64 包与 hash 见发布页。发行包只放置 homer.json.example,必须复制成真实配置后再启动。

curl -fLO https://github.com/sipcapture/homer/releases/download/11.0.336/homer-core_11.0.336_amd64.deb
echo "ae08448285f31f860f4ed48f8339a79bc2c4ae9c1da9f3d9b74cb4dc4d7708b9  homer-core_11.0.336_amd64.deb" | sha256sum -c -
sudo apt install ./homer-core_11.0.336_amd64.deb
sudo install -m 0600 /usr/local/homer-core/etc/homer.json.example /usr/local/homer-core/etc/homer.json
sudo install -d /data/homer/parquet /var/lib/homer
/usr/local/homer-core/bin/homer version

官方 Docker quick start 约需 8 GB 内存且 Compose 引用 HOMER/RustFS latest 与示例 Token。若走 Docker,先锁镜像 digest、换凭据、限端口,不能直接作为生产清单。

03

加固 HOMER 配置并首次启动

本文参考配置 下列只是需要覆盖/核对的关键字段,不可直接替换官方完整 JSON。node token 与 coordinator node token 相同;JWT 使用另一随机值;对外访问用防火墙或反向代理。

"ingest": {
  "udp": {"enable": true, "host": "0.0.0.0", "port": 9060},
  "sip": {
    "aleg_ids": ["X-CID", "X-Session-ID"],
    "custom_headers": ["X-Trace-ID"],
    "force_aleg_id": false
  }
},
"node": {"flight_server": {
  "host": "127.0.0.1", "port": 50051,
  "auth_token": "REPLACE_WITH_RANDOM_NODE_TOKEN"
}},
"coordinator": {
  "http_server": {"host": "127.0.0.1", "port": 8080},
  "nodes": [{"name":"local", "host":"127.0.0.1", "port":50051,
             "token":"REPLACE_WITH_THE_SAME_NODE_TOKEN", "priority":1}],
  "jwt": {"secret":"REPLACE_WITH_DIFFERENT_RANDOM_JWT_SECRET", "expire_hours":24}
},
"prometheus": {"enable":true, "host":"127.0.0.1", "port":9090, "path":"/metrics"}
sudo systemctl daemon-reload
sudo systemctl enable --now homer-core
sudo systemctl status homer-core --no-pager
sudo journalctl -u homer-core -b --no-pager | grep bootstrap_password
curl -fsS http://127.0.0.1:9090/metrics | head

首次管理员密码是随机值,只在首次日志写入一次;首次登录后立即更换。不要把日志或 Token 放进报告、截图或前端。

04

接入 FreeSWITCH 原生 HEP 与 HEPipe RTCP

HOMER Wiki 原始参数 FS-A 使用 capture_id=1001,FS-B 使用 1002;桥接前写 X-cid。配置先在 POC profile 重载,现网 profile 重启会影响通话,必须走维护窗口。

<!-- autoload_configs/sofia.conf.xml -->
<param name="capture-server"
       value="udp:HOMER_MANAGEMENT_IP:9060;hep=3;capture_id=1001"/>

<!-- sip_profiles/internal.xml / external.xml -->
<param name="sip-capture" value="yes"/>

<!-- bridge 之前 -->
<action application="set" data="sip_h_X-cid=${sip_call_id}"/>
<action application="set" data="rtcp_audio_interval_msec=5000"/>
fs_cli -x "sofia global capture on"
fs_cli -x "sofia global capture off"
fs_cli -x "sofia profile internal capture on"
fs_cli -x "sofia profile internal capture off"

HEPipe 固定配置 ESL 必须绑定 127.0.0.1:8021 并更换默认 ClueCon;HEP_ID 与该 FS 的 capture_id 一致。

git clone https://github.com/sipcapture/hepipe.js.git
cd hepipe.js
git checkout --detach 5895a6cb304733e07c518f91612db2181957decb
var config = {
  hep_config: {debug:false, HEP_SERVER:'HOMER_MANAGEMENT_IP', HEP_PORT:9060},
  esl_config: {
    debug:false, ESL_SERVER:'127.0.0.1', ESL_PORT:8021,
    ESL_PASS:'REPLACE_WITH_RANDOM_ESL_PASSWORD', HEP_ID:1001,
    report_call_events:false, report_rtcp_events:true, report_qos_events:false
  }
};
module.exports = config;
docker compose up -d --build
docker compose ps
docker compose logs --tail=100 hepipe

当前 HEPipe 会订阅 ESL ALL;即使只上报 RTCP,也会接收全部事件。HEP 输出为 UDP,无 TLS/确认/独立健康检查,先单节点小流量验证,并置于管理网或 VPN。

05

验证、故障定位与回滚

  1. 确认 9060/8080/9090 的监听与来源限制;短时 tcpdump -ni any udp port 9060 证明 HEP 到达。
  2. 发起带已知 X-cid 的测试通话;在 HOMER 用 Call-ID/X-cid 找回两条 B2BUA leg。
  3. 确认 HEPipe 出现 ESL ready,HOMER 同时收到 SIP 与 HEP type 5 RTCP。
  4. 对 10 正常 + 5 事故样本核对方向、SSRC、时间窗、loss/jitter 与最终录音。
有 SIP、无 RTCP

查 RTCP interval、对端是否真正产生 RTCP、ESL 密码/重连;无 RTCP 时不能凭 HOMER 推断卡顿。

两条 leg 分裂

查 B-leg INVITE 的 X-cid、HOMER aleg_ids;需要时再启用受限 Lua correlation,不盲开 force。

HEPipe 负载高

它订阅 ALL;只保留 RTCP flag、小流量、每 FS 单实例,并观测 CPU/RSS/ESL event rate。

回滚

先 profile/global capture off,再 stop HEPipe,最后停 HOMER;保留数据卷,不执行 down -v。

POC 门槛

15 条已知测试通话 100% 找回正确两腿;SIP/RTCP 方向不串;采集器无可见 drop;关闭采集不影响媒体;至少一个实验室故障定位到正确 hop。

RUNBOOK C · PASSIVE RTP SENSOR

VoIPmonitor Sniffer + SPAN/TAP

适合在中心边界被动计算 RTP/RTCP、MOS、jitter/loss 并保存取证头部。开源 sniffer 是 GPL-2.0;Web GUI 单独商业。GitHub 没有当前 Release,不能虚构“latest release”。

COMMIT PIN · NOT A TAG9dfb2fc9aa0552a0
2026-07-21
subject: release 2026.07.1
01

镜像点与可见性先验

sensor-A / sensor-B 各自接专用 SPAN/TAP 接口并使用唯一 id_sensor。镜像必须含双方向 SIP 和实际 RTP/RTCP;direct media 绕路、单方向 SPAN 或 SRTP payload 加密都不会被工具自动补全。

FS-A/SBC ──SPAN/TAP──> sensor-A (id=101) ─┐
                                           ├─ MySQL / 商业 GUI(可选)
FS-B/SBC ──SPAN/TAP──> sensor-B (id=102) ─┘
02

Debian 12 源码安装并锁 commit

仓库 Debian 指引 current-stable 静态包会漂移;可复现 POC 采用固定源码。先在 MySQL 建独立数据库与最小权限账号。

sudo apt-get update
sudo apt-get install build-essential git libmysqlclient-dev libvorbis-dev libpcap-dev unixodbc-dev libsnappy-dev libcurl4-openssl-dev libssh-dev libjson-c-dev librrd-dev liblzo2-dev liblzma-dev libglib2.0-dev libxml2-dev libzstd-dev liblz4-dev
git clone https://github.com/voipmonitor/sniffer.git
cd sniffer
git checkout --detach 9dfb2fc9aa0552a02152aca3ac9b6187dc333a2f
./configure
make -j2
sudo make install
command -v voipmonitor
03

先用低留存配置,不复制仓库高成本默认值

本文 POC 参考配置 仓库样例当前实际启用 savertp=yes、savertcp=yes、savegraph=yes。这里改为 RTP header、无音频、无 graph;生产保留期再按合规与事故样本调整。

[general]
interface = eth1
id_sensor = 101
name_sensor = fs-a-span
managerip = 127.0.0.1
managerport = 5029
sipport = 5060

mysqlhost = 127.0.0.1
mysqlport = 3306
mysqlusername = voipmonitor
mysqlpassword = REPLACE_WITH_RANDOM_DB_PASSWORD
mysqldb = voipmonitor

spooldir = /var/spool/voipmonitor
savesip = yes
savertp = header
savertcp = yes
saveaudio = no
savegraph = no

savertp=header 仍可基于在线 RTP 计算 sequence/jitter/loss,但不把语音 payload 写入 PCAP。若数据库 sensor_conf 开启加载,它可能覆盖文件配置,验收要核对最终生效值。

04

前台验证,再交给 systemd

README quick start 写 --config,但当前源码帮助、init 脚本与配置注释一致使用 --config-file;本手册采用后者。先在前台看到镜像流量和 DB 初始化成功,再启用 service。

sudo /usr/local/sbin/voipmonitor --config-file /etc/voipmonitor.conf -k -v 1
sudo install -m 0755 config/init.d/voipmonitor /etc/init.d/voipmonitor
sudo install -m 0644 config/systemd/voipmonitor.service /etc/systemd/system/voipmonitor.service
sudo systemctl daemon-reload
sudo systemctl enable --now voipmonitor
sudo systemctl status voipmonitor --no-pager

官方 systemd unit 实际调用 init 脚本,init 再调用 --config-file /etc/voipmonitor.conf;两份启动文件与配置必须一起纳入变更和回滚。

05

逐层验收、故障判别与回滚

  1. 短时执行 tcpdump -ni eth1 -c 200 'port 5060 or udp portrange 10000-40000',确认 VLAN、双方向和端口。
  2. 发一通已知 Call-ID/X-cid 的测试呼叫;确认 CDR 落到正确 sensor,caller/called 方向正确。
  3. 核对 RTP stream、RTCP、loss/jitter/MOS 与同窗 PCAP;检查 spool 不含 WAV/完整 RTP payload。
  4. 检查 NIC、libpcap/进程日志与 DB queue 无 drop/积压,按一周峰值外推磁盘和数据库。
SELECT id_sensor, calldate, callend, caller, called
FROM voipmonitor.cdr
ORDER BY calldate DESC
LIMIT 10;
有 SIP、无 RTP

查 direct media、单向 SPAN、SDP/NAT 端口;“没抓到”不能等同于“对端没发”。

loss 异常偏高

先查 NIC ring、sensor CPU、libpcap drop、镜像口 oversubscription,分离采集丢包与业务丢包。

磁盘暴涨

查 savertp/savegraph/saveaudio、PCAP/tar 与 TTL;POC 默认 header/no-audio/no-graph。

回滚

stop + disable service,确认进程退出后由网络团队撤销明确 SPAN;默认保留 DB/spool,另审批清理。

POC 门槛

15 条通话全部落到正确 sensor/Call-ID;双方向 RTP 与 PCAP 对上;一个实验室 burst loss 在正确窗口识别;sensor 自身 drop 可测;成本可外推;关闭 sensor 不影响媒体。

07 · First divergence

同一时间窗内,找第一个从正常变异常的观测点

MiniMax chunk gap 先升高,buffer 归零MiniMax / TTS 网络 / Gateway 入口查 trace/session、重连、区域、解码队列和供应商响应。
MiniMax 块正常,Gateway buffer 归零解码 / 队列 / event loop / 背压查 queue wait、CPU、线程停顿、generation drop 和播放器。
FS-A 出站连续,FS-B 入站 sequence gap中心间网络 / SBC对比两端 PCAP、RTCP、NIC drop、路由和抓包器自身 drop。
FS-B 入站连续,出站 gap 或 timestamp 跳变FS-B 转码 / 调度 / jitter buffer核对 codec/ptime、转码 CPU、media bug、flush 与 timestamp rewrite。
RTP 正常,PCM 出现重复帧或断续解码 / PLC / 播放 / 录音点比较同 hop 编码前后 PCM 与 underflow event。
服务端 hop 都正常,终端录音异常运营商 / 接入段 / 终端按地区、运营商、设备和时间做主动探针切片。
告警措辞:先写“AI 下行疑似断续,影响 N 条有效会话”;只有差分证据充分时才填 suspected_component。一个 MOS 下降不能直接变成“MiniMax 故障”。

08 · Ablation study · 2026-09-05

拿掉一层观测,定位能力会损失多少?

固定同一批电话,逐层屏蔽证据;再以真实进程启停测成本。用配对结果回答 TTS 埋点、FreeSWITCH、HOMER/HEPipe、VoIPmonitor 和可听特征分别带来的增量。

实验设计 · 待实测

分组、故障剂量、样本量和门槛都是参考设计。离线评分工具已提供,真实采集、故障注入、适配器和性能结果待执行。组件沿用 2026-09-02 的固定快照;本次没有将其重新宣称为最新版本。

11 组

完整组 + 6 个证据消融组 + 4 个产品组,覆盖 HEPipe 独立增量和 H/V 组合。

16 类

8 类故障候选 + 8 类健康/可见性对照;以终端金标确认实际是否受损。

320 × 11

POC 建议留出 320 通测试电话、3,520 条配对预测;同一通话仍只算一个样本。

先划清证据家族,才能真正“去掉”一层

删除原始字段时,也删除它的副本、派生指标和预生成告警
家族保留时可见消融完整性检查
T · TTS/播放chunk arrival、样本数、FIFO 水位、underflowtrace/log 中的复制值与 TTS 派生根因也屏蔽
F · FS 内部ESL 生命周期、bridge、codec/ptime、调度包计数归 N;RTCP、相关 MOS 归 R,不混入 F
R · RTCPSR/RR/XR、接收端质量报告同时去掉直接 ESL、HEPipe、VoIPmonitor 的 RTCP 副本
N · RTP 头部逐跳 sequence、timestamp、arrival、loss/jitterFS 包计数、原始头部和依赖它们的派生值同时屏蔽
A · 可听特征PCM gap/click/freeze、端侧 playout、声学评分仅删除检测器输入;独立金标录音与盲审继续保留
C · 跨源关联conversation↔TTS↔UUID↔Call-ID↔SSRC 映射删除 join map、X-cid、全局文件名;按源保留局部匿名 ID

每条事件带 family/source/derived_from/event_time/available_at/visibility。屏蔽任一父家族,其派生输出也屏蔽;缺数据标 unavailable。DROP_C 必须接收多通并发交错的独立源流,不能把已经按通话拼好的 bundle 交给“无关联”检测器。随机 case_id 只给事后评分器。

实验矩阵:证据消融与产品取舍分别比较

组 ID该组可见内容主要检验
FULLT F R N A C,HOMER/HEPipe 与 VoIPmonitor 均采集完整参考组,同时作为 H+V 产品组
DROP_T完整组去掉所有 T缺料与 Gateway 消费停顿还能否区分
DROP_F完整组去掉所有 FFS 内部处理区间是否变成盲区
DROP_R完整组去掉所有 RRTP 头部可否替代接收端质量报告
DROP_N完整组去掉所有 N短突发与 RTP timestamp 异常是否漏检
DROP_A完整组去掉所有 ARTP 连续时的毛刺/终端 freeze 是否可见
DROP_C完整组去掉跨源 C多 FS、换腿、并发流是否串线或误定位
P_BASET F A C;不消费 R/N/HEP自建低侵入 MVP 的覆盖范围
P_H_SIPP_BASE + 原生 HEP SIP + HOMERSIP 关联的增量;关闭所有 RTCP 输入
P_HP_H_SIP + HEPipe RTCP,无 VoIPmonitor 输入与 P_H_SIP 配对测 HEPipe 的增量
P_VP_BASE + VoIPmonitor SIP/RTP/RTCP,header/no-audioVoIPmonitor 路线;不消费 HOMER/HEPipe 输入

FULL − P_V 衡量整个 HOMER/HEPipe 通路的边际价值;P_H − P_H_SIP 衡量没有替代 RTCP 副本时 HEPipe 的价值。所有组共享冻结的检测规则和基础可见性监测,产品原生 UI 的人工排障时间另测。

ΔL(去掉 X) = L(FULL) − L(DROP_X)
H/V 交互 = L(FULL) − L(P_H) − L(P_V) + L(P_BASE)
L = 正确区间定位通话数 / 全部真实故障通话数

边际贡献不具可加性。H/V 比较需相同 T/F/A/C 基础、采集位置与 available_at;会后 CDR 不能提前喂给实时告警。仅屏蔽字段无法测进程运行成本。

16 个场景:同时测试漏检和误报

场景单一变量 / 建议起点独立真值和判定
F01 · TTS 停供稳定出话中暂停 chunk 释放 300/600 ms有实际可听故障才标阳性;定位 tts_path
F02 · buffer 消费到料正常,Gateway consumer 暂停 100/300 ms比较入队与出帧;gateway_playout
F03 · 单向丢包独立测试 RTP 出口短时 100% loss,目标 4/8 包实际剂量由两侧 PCAP 确认;inter_center
F04 · 晚到/抖动目标下行 delay 60±20 ms,固定接收 buffer核验 late 与可听缺口;inter_center
F05 · RTP 时钟测试重放器插入 timestamp 跳变,seq 连续按 codec 时钟核验;一批内固定注入位置
F06 · FS 媒体专用 FS 容器减少 CPU quota,语料/负载不变对比入站和出站首次差异;fs_media
F07 · PCM 毛刺实验分支重建 resampler / 重复样本,分开测试RTP 可能正常;gateway_playout
F08 · 终端 freeze可控终端 playout 暂停 200/500 ms独立端侧记录;外部区间 post_fs_path
C01 · 健康同等时长、语料、并发,无注入无媒体质量告警
C02 · 合法停顿自然静音,speech_expected=false停顿不应被当作 TTS 卡顿
C03 · 用户打断取消当前 generation、停止旧音频取消后的空窗不应报 underflow
C04 · DTX/CNG协商正确的静音抑制 / 舒适噪声合法 RTP 间隔不应机械判丢包
C05 · 采集丢包只降低观测支路容量,媒体链不动告采集退化,不误报业务丢包
C06 · 无 RTCP测试对端关闭 RTCP,媒体健康报告 unavailable,不假填零丢包
C07 · 录音损伤只有一份监控录音重采样出错另一份端侧记录正常;不能判用户卡顿
C08 · 换腿/盲区转接、re-INVITE、SRTP、direct media 分变体测试保留可见性缺口,避免串线和误定

注入成功不等于可听故障成立:缓冲可能吸收 300 ms 的上游停供。A 的检测特征与 gold 必须独立标注;gold 录音始终保留。B2BUA 两侧 SSRC/seq 可能重建,应先按各流时钟对齐,不能直接相减序号。

八步执行:冻结、盲评、配对评分

  1. 冻结环境与版本。 记录 codec/ptime、缓冲、镜像位置、采集器版本、语料 hash、detector commit;在独立测试 trunk/namespace 接线。
  2. 建立独立 gold。 控制器记录实际注入时刻和剂量,端侧录音盲审可听故障及区间。先完成 16×2=32 通接线冒烟。
  3. 划分样本。 每场景建议 30 通:10 校准、20 测试,合计 160/320 通。源语料/事故/线路时段 block 隔离;480 通只是 POC 起点。
  4. 一次采齐全组输入。 保存 T/F/R/N/A/C、available_at、collector drop 和时钟偏差;金标损坏或注入失败进入统一台账。
  5. 导出 11 个屏蔽视图。 按 family/source allowlist 删除原始和派生值,审计文件名、缓存与预先 join;DROP_C 使用并发交错流。
  6. 按 available_at 回放。 冻结阈值和告警去重,所有组相同;超时/采集失败显式保留。重新调优仅使用校准集并另出表。
  7. 冻结预测再合并 gold。 每通每组 JSONL,独立评分进程计算召回、误报、正确区间、时间与配对 CI,按场景/线路分层复查。
  8. 测运行开销和 probe。 物理启停按随机顺序重复;巡检从 incident_start 计时,包含等待下一次探针的时间。
操作示例:SIPp 媒体回放与隔离 netem

SIPp 使用已经在测试 trunk 验证过的 INVITE/200/ACK/BYE 场景,媒体 action 调用 play_pcap_audio。播放异步执行,应保留足够 pause,并核验实际协商 codec 和终端录音;echo/发包成功不能证明听感。以下 namespace 与接口需预先建好,只承载单向测试 RTP。

<nop><action>
  <exec play_pcap_audio="fixtures/g711a.pcap"/>
</action></nop>
<!-- pause 需覆盖这份媒体的实际时长 -->
<pause milliseconds="12000"/>
# 只读确认独立 namespace、测试接口与队列;不覆盖已有根队列
ip netns list
ip -n vq-ablation link show rtp-out
ip netns exec vq-ablation tc qdisc show dev rtp-out

# F04 建议起点,tc 版本需支持 seed
ip netns exec vq-ablation tc qdisc add dev rtp-out root handle 7a10: \
  netem delay 60ms 20ms distribution normal seed 20260905
ip netns exec vq-ablation tc -s qdisc show dev rtp-out

# 完成本条测试后撤销本次队列并验证恢复
ip netns exec vq-ablation tc qdisc del dev rtp-out root handle 7a10:
ip netns exec vq-ablation tc qdisc show dev rtp-out

F03 可在独立测试接口短时使用 netem loss 100%;80 ms 不保证精确丢 4 包,必须记录实际启停时间和两侧 PCAP。F01/F02/F05/F07 的测试钩子需要接入 Gateway/重放器,当前文档未提供现成注入 CLI。

评分:漏检、未定位和超时都留在分母

指标计算口径限制
发现召回onset 到 deadline 内有媒体告警 / 全部可听故障通话建议 deadline=onset+5 s;注入类别不直接充当 gold
定位召回 L第一条有效告警区间正确 / 全部故障通话错误、未定位、漏检均不是成功;后续纠正另报
误报与可用性健康通话有告警 / 全部健康通话另报 collector_error、健康告警/失败并集,防止停采换低误报
发现时延命中子集 p95 + 漏检取 5 s 的 capped mean/p95提前/逾期告警单列;capped 不是无限检测时间的估计
配对增量FULL − 对照的 L;2,000 次 paired block percentile bootstrap95% CI 探索性、未多重比较校正;样本不足时继续采集
运行开销core-seconds/call、RSS、bytes/call、disk/day、queue/drop、媒体帧延迟真实进程启停测量,计入外置 sensor 与数据库

统一通话观察时长,按 call 配对、按线路/时段/语料依赖 block 重采样。所有条件的预测冻结后才读取 gold。post_fs_path 可以是正确区间,不能因此断言线路商 transcoder 根因。

确认性决策预注册 1–2 个主比较;全部十项显著性判断需另做多重比较校正。480 通不代表功效充分。零误报的独立样本近似 95% 上界约 3/N,要支持低于 1%,至少约 300 通独立健康样本且零误报,相关样本需要更多。

离线评分工具:输入契约、命令与能力边界

工作区 voice-quality-ablation/score.py 使用 Python 3.9+ 标准库。已实现完整配对矩阵检查、漏检与失败计入分母、首次误定位、分场景统计和 block CI;采集、注入、特征屏蔽与检测适配器仍需在实验环境接入。

cd voice-quality-ablation
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v
python3 score.py --gold /lab/gold/test.csv \
  --predictions /lab/predictions/test.jsonl \
  --data-kind lab --seed 20260905 --resamples 2000 \
  --output /lab/results/ablation-001.json

gold CSV 列:case_id, block_id, scenario, affected, onset_ms, deadline_ms, obs_end_ms, gold_hop。预测每通每组一行,仅含 case_id/group/status/alerts;alerts 是 {at_ms,hop} 数组。未定位填 unlocalized;失败写 timeout/collector_error、空数组,不能删行。输出文件排他创建并记录输入 SHA-256。

仅给接口/统计自测的 fixture 不填入实验结果表。该评分器没有算物理开销、probe 覆盖或事件级 precision;详细契约在同目录 README 与 Markdown 母本第十四章。

结果表保持空白,等真实数据进入

组召回 / L / 误报ΔL 与 CIcapped TTD / 错误率运行成本
FULL待实测参考组待实测待在线实测
DROP_T / F / R各组待实测各组待实测各组待实测另做物理启停
DROP_N / A / C各组待实测各组待实测各组待实测另做物理启停
P_BASE / H_SIP / H / V各组待实测按预注册对照各组待实测同条件实测
状态为 planned,所有成绩留空。

物理开销、主动探针与取舍门槛

运行开销六组

O0 媒体+独立金标;O1 加 T/F/A/C;O2 加 HOMER SIP;O3 再加 HEPipe;O4 为 O1+VoIPmonitor;O5 全开。10%/50%/100% 测试负载,预热 5 min、测 15 min,每档至少三个 block、随机组顺序。先 drain 再切组,外置采集器成本也计入。

主动探针三组

PASSIVE、+5 min、+15 min。分别测试 0.2–3 s 短故障与 15 min 持续故障,随机发生时刻。从 incident_start 算至首个覆盖受影响路由的有效 probe 和告警;未覆盖保留漏发现/删失,另报额外电话数。

保留或减配

示例主门槛:定位增益至少 5 个百分点且 CI 支持收益,或覆盖关键盲区。减配需预注册 2 个百分点非劣界并排除更大劣化;“不显著”不是可删除的证明。误报、可用性与真实开销同时达标。

单线路黑盒边界

己方 FS 出口正常、终端异常时保留 post_fs_path。用固定语料、PCMA/PCMU、预编码、本地闭环和不同终端重复验证;没有线路商双侧证据,不填写具体内部转码金标。

09 · Delivery path

先做事实盘点,再补网络和声学真值

P0 · 1 WEEK

拓扑与样本

画清 B2BUA/转码/SBC/录音点;收集 10 条正常 + 5 条卡顿的 UUID、Call-ID、日志、PCAP 和录音。

P1 · 2–4 WEEKS

低侵入 MVP

统一 conversation/X-cid;补 TTS 块与 buffer;接 ESL/CDR;建立逐通话时间线和四条差分规则。

P2 · 2–4 WEEKS

被动逐跳

单链路 POC HOMER 或 VoIPmonitor;验证 SRTP/direct media 可见性、抓包丢包和存储成本。

P3 · 3–6 WEEKS

主动与 PCM

SIPp 关键地区定时呼入;异常通话旁路 PCM;事故回灌回归样本与发布门禁。

第一周必须拿到的配置事实

问题为什么影响方案证据
FreeSWITCH 版本与节点拓扑决定 HEP/ESL 字段、B2BUA 关联与采集点版本输出、dialplan、SIP ladder
codec / ptime / 转码关系决定包频率、timestamp、CPU 和正常 gap 基线SDP、实际 codec 变量、PCAP
SRTP / direct media决定被动 sniffer 能否看到明文媒体SIP/SDP、媒体五元组、SBC 配置
MiniMax HTTP/WSS/Bidi决定 chunk schema、重连和埋点位置Gateway 代码与请求日志
录音点与通道映射决定最终录音能证明哪一段、AI/用户轨是否可信录音配置、人工抽听、已知语料

10 · Safety and operations

监控不能成为新的卡顿来源

旁路不阻塞媒体

bounded queue、超限丢弃、熔断;监控 WebSocket 慢时先丢观测,不拖住 RTP。

抽样而非全量

正常通话保留聚合指标;异常窗口才保存短 PCAP/WAV,控制成本与隐私暴露。

PII 不进 label

手机号、转写和原始音频不进入 Prometheus label 或 trace baggage。

证据加密与短 TTL

对象级最小权限、访问审计、自动过期;密钥和 ESL 密码不出现在前端。

采集器也要被监控

packet drop、queue drop、clock skew、CPU/RSS 和 event-loop lag 都要显式上报。

模型分只是辅助

NISQA/DNSMOS 不能覆盖确定性 chunk、RTP sequence、buffer underflow 与最终录音。

相关专题:端到端 SLA 说明“首字节、首 RTP、可听起音”不是同一事件;离线无声质检说明最终录音只能证明症状,不能独立定根因。

端到端 SLA · 无声质检

11 · Sources

48 条官方、固定版本源码与社区证据

组件资料截点 2026-09-02;消融实验方法资料核验于 2026-09-05。runbook 配置链接到固定 release/tag/commit;仓库自述与社区线索不自动等于独立复现。Markdown 母本另保留转码毛刺与抓包专项来源。

sipcapture/homer

HEP、可选 VQRTCP/SIPREC;当前仓库许可证为 AGPL-3.0。

voipmonitor/sniffer

SIP/RTP/RTCP、RTCP-XR、MOS、jitter/loss、PCAP/录音;sniffer GPL-2.0、GUI 商业。

SIPp/sipp

SIP 流量生成、场景、PCAP 媒体播放;GPLv3。

gabrielmittag/NISQA

overall、noisiness、coloration、discontinuity、loudness;代码 MIT,权重 CC BY-NC-SA。

W3C Trace Context

跨服务 trace 传播基础;不应把完整 PII 放入 baggage。

VoIPmonitor · FAQ

官方常见问题;仓库 README 的 /doc/Configuration 本次检查返回 404,未采用。

SciPy · Paired bootstrap

2026-09-05 核验:配对重采样与置信区间;本地评分器为标准库 percentile block 实现,不调用 SciPy/BCa。