语音信箱与应答机检测

11 分钟读完

V22
实战手册 · 语音与实时智能体

先等应答机检测出结果、再开口,在构造上就是一次被放弃的呼叫——检测器要约四秒,而规则只给你两秒。

Twilio 自家的 FAQ 把应答机检测的耗时写成"在默认配置下,接通后约四秒返回结果";而美国的电话营销规则把"被放弃的呼叫"定义为:在被叫方说完问候语后两秒内未接入真人代表,并把放弃率上限定在任意 30 天活动窗口内已被真人接起呼叫的 3%。于是,任何把第一句话卡在检测结果之后的外呼语音智能体,在设计上就已经不合规——而且它把这段静默,支付在那 5%–10% 真的接通了人的拨号上,也就是全部价值所在的那一小部分。请在接通的那一刻就开口,让检测并发地跑,并把"留一条语音信箱消息"当成一个有自己同意记录的、独立的受监管行为,而不是一个兜底分支。

步骤 1两个时钟,无法同时满足。

先把数字摆上桌,因为这个冲突是算术,不是判断问题。以下数字截至 2026 年 10 月。

检测器的时钟。Twilio 的应答机检测文档描述了两种模式。默认模式会在听到足够多的应答方声音后给出结论,厂商自己的 FAQ 把它表述为"在默认配置值下,接通后约四秒"。在 DetectMessageEnd 模式下,"是真人"会立即上报,但"是机器"的结论只在问候语结束时才到——通常是在那声提示音处——因为那才是你真的能留言的时刻。MachineDetectionTimeout 的默认值是 30 秒。第三方文章把真实的"问候语结束"延迟普遍放在 10–30 秒区间,这是厂商侧的估计而非已公布的数字,但形状没有争议:问候语结束检测要花掉一整段问候语的时间。

规则的时钟。FCC 在 47 CFR 64.1200 下的投递限制规定:若呼叫在被叫方说完问候语后两秒内未接入真人销售代表,即视为被放弃;并禁止在按活动计、每个连续 30 天期间内,放弃超过已被真人接起的电话营销呼叫的百分之三。同一规则还要求:未被接起的呼叫在断线前至少振铃 15 秒或四声;以及在没有代表可用时,主叫方须播放一段预录身份信息,内容仅限企业名称、其电话号码,以及该呼叫系用于电话营销之目的。

The incompatibility, on one timeline (US telemarketing, Oct 2026).

  t=0.0s   call answered, callee says "Hello?"
  t=1.2s   greeting complete            <-- rule's clock starts here
  t=3.2s   deadline: live rep connected <-- 2s after completed greeting
  t=4.0s   AMD default verdict arrives  <-- 0.8s too late, every time
  t=10-30s DetectMessageEnd verdict     <-- only at the beep
  t=30s    MachineDetectionTimeout default

Gate the greeting on detection -> abandoned by construction.
Cap is 3% of live-answered calls per 30-day campaign.

这里面坐着一个诚实的未知:一个对话式智能体是否算规则所设想的那个"真人销售代表"。监管条文从未预想过它,而更稳妥的读法——也是外呼语音智能体在拨号节奏与放弃率上普遍采取的读法——是:无论监管最终把你放在这条线的哪一侧,上限都适用。请把设计做成"这个问题不决定你的合规性"。

本页以美国电话营销规则为参照来写,因为它最具体、诉讼最多。其他法域在数字上不同,在结构上不然:例如英国 Ofcom 的放弃呼叫制度有自己的比率和自己的身份告知要求。请核对你所在法域,并把这里的数字当成问题的形状,而不是法律意见。

步骤 2机器才是常态,而检测把账单开给了那些接通人的呼叫。

团队之所以把语音信箱处理做成兜底分支,是因为他们脑子里的那通电话大多接通了人。而已公布的接通率并不描述那个世界。2026 年一份分析覆盖了上一年记录的超过 175,000 条拨号,给出每次拨号 9.9% 的冷呼接通率;按潜客计则升到 24.5%,因为有些人是在后续尝试中才被联系上的。Gong 覆盖超过 3 亿通呼叫的数据集被引述为 5.4% 的平均接通率,头部表现者为 13.3%。Cognism 的 2026 年外呼报告把行业冷呼成功率放在 2.7%(上一年 2.3%),并给出使用已验证联系数据的团队 13.3% 的"被接起率"。2026 年一份厂商分析提醒:其客户计入"已接起"的,大约有一半其实是语音信箱、运营商拦截功能,或六秒内挂断。同一批文献引用的 Pew 数据显示,只有约 19% 的人表示自己通常会接陌生号码。

这些定义彼此差异大到没有一个数字可以直接互比——有的把语音信箱计为已接起,有的按拨号计、有的按潜客计——但它们每一个都把"接通真人"放在每次拨号的个位数到十几个百分点之间。于是:

  • 机器不是例外。在冷名单上,大多数完成的连接都是一段语音信箱问候、一段拦截提示,或一次六秒内的挂断。一条当作事后补丁搭起来的语音信箱路径,恰恰是你大部分流量要走的那条路。
  • 但检测延迟是向真人收费的。那四秒静默在每一通被接起的呼叫上都要付,而唯一可能产生成交、工单解决或预约确认的,是那少数由人接起的呼叫。你在用 9% 的体验,去给 91% 做分类。
  • 四秒静默不是中性的。它听起来像掉线或骚扰电话,被叫方会挂掉,或者直接对着这段空白说话——这会把你的智能体在一句话都还没说之前就推进打断状态。首词的延迟预算远低于一秒;检测花掉四秒。

这份不对称就是整个设计约束。它也解释了为什么一个"热接触"活动——给已知客户发预约提醒、人接起大多数电话的那种——通常应该完全关掉检测,改用一段简短得体、对人说和对信箱说同样成立的消息。

步骤 3接通即开口;让检测在对话旁边跑。

同时满足两个时钟的架构并不聪明,只是顺序与教科书不同。在通道被接起的那一刻就启动智能体,并把检测结果当成一个"可能在你说话中途才到"的事件来订阅。

# WRONG: the verdict gates the first word. ~4s of dead air on every
# answered call, and the 2s post-greeting deadline is already gone.
result = await telephony.detect_answering_machine(call)   # blocks
if result == "human":
    await agent.start(call)

# RIGHT: greet immediately, treat detection as a concurrent signal.
await agent.start(call)                        # first word < 1s
detect = asyncio.create_task(telephony.amd_events(call))

async for verdict in detect:
    if verdict.kind == "human":
        break                                 # nothing to do; keep talking
    if verdict.kind.startswith("machine"):
        await agent.stop(reason=verdict.kind)   # stop mid-sentence
        await voicemail_policy.handle(call, verdict)
        break
    if verdict.kind in ("fax", "unknown"):
        await call.hangup(); log(verdict); break
# invariant: agent.start() is never downstream of a detector.

这个顺序带出三条性质,值得当成需求而不是副产品来写明。智能体的问候语必须能被你自己的代码打断,而不只是被来电者打断——大多数实时栈都暴露了"取消正在播放的话语"以支持打断,而这就是同一个机制换一个触发源,实时架构一页把它称为 cancel-and-flush。检测结果必须是事件流而不是返回值,这样一个迟到的"是机器"仍然能叫停一段已经开始的对话。而每一个结论类别都需要显式分支,因为 unknown 很常见,而把它默默当成真人,正是一段推销话术最后被录进传真机磁带的方式。

这个顺序的代价是:当结论说"是机器"时,你已经把问候语的一部分说进了信箱。这是真实的缺陷,而下一步讲的就是如何让它只是个小缺陷。

步骤 4把开头八个词设计成"被截断也仍然是一条好消息"。

如果检测结论可能在你问候语的第四秒才到,那你问候语的前四秒就是你唯一控制得住的部分。把它写成"足以独立成为整条消息"。具体说:身份、目的、回拨方式,按这个顺序,放在任何寒暄动作之前。

# Bad opener: nothing useful survives truncation at 4s.
"Hi there! How are you doing today? I'm calling on behalf of--"

# Good opener: identity + purpose + callback inside ~4 seconds.
"This is the Northgate Clinic scheduling line, about your
 Thursday appointment. You can reach us on 555-0147."
#  ^ who          ^ why                      ^ how to respond
# Truncated at 4s it is a usable voicemail; heard in full by a
# person it is a normal opening. One script, both outcomes.

这同时提前履行了告知义务,而这件事本身也重要:智能体必须说明自己是智能体,而把它放在第一口气里,意味着一条被截断的消息也仍然带着它。在通话中披露智能体身份有按法域展开的细节;这里只讲顺序。

然后把各个结论类别分别处理,因为它们携带的信息不同。Twilio 的问候语结束模式会区分 machine_end_beep、machine_end_silence 与 machine_end_other,另有 human、fax 与 unknown。提示音是"信箱正在录音"的可靠信号;静默通常意味着问候语结束而没有提示音,留在那里的消息可能被捕获也可能没有。请在日志里把它们当成三种不同结果,而不要塌缩成"机器",否则你的重试逻辑会不停重拨那些你其实已经成功留言过的号码。

不要试图靠"一检测到机器就立刻挂断"来撤回那段已说出口的问候。一通不到一秒、留下半句话的呼叫,正是消费者投诉的典型形态;而在电话营销活动里,它也正是放弃呼叫规则存在的目的所在。把你设计好的那四秒开头说完,然后再决定要不要继续说成一整条消息。

步骤 5留言是一个独立行为,需要它自己的同意记录。

这是团队最常跳过的一步,也是下行风险最大的一步。把一段预录或合成的消息投进信箱,不是"更安静版本的打电话"——在美国法下,它就是一次呼叫。FCC 2022 年 11 月 21 日的解释性裁定(FCC 22-85,CG Docket 02-278)认定:投递到无线号码的所谓"无铃声语音信箱"属于以人工或预录声音发出的"呼叫",因而需要消费者的同意;委员会明确表示它并非禁止这一技术,只是确认 TCPA 覆盖它。"消息从未经过用户话机"这一技术事实,被拒绝作为豁免依据。

对一个智能体平台来说,实际后果是你的同意模型需要第二个字段。"我们可以拨打这个号码吗"和"我们可以在这个号码留下人工声音的消息吗"是两种不同的许可,而只采集了前者的流程不应该去投递消息。

# Two permissions, not one. Check the second before the drop.
contact = {
  "number":            "+1555...",
  "consent_call":      {"granted": True,  "source": "web_form_2026_08_14"},
  "consent_prerec":    {"granted": False, "source": None},
  "line_type":         "wireless",
}

if verdict.kind.startswith("machine"):
    if contact["consent_prerec"]["granted"]:
        await leave_message(call, script=approved_vm_script)
    else:
        await call.hangup()          # no drop without the 2nd grant
    audit.record(call, verdict.kind, left_message=...)   # always

有三个细节能让这套做法在审查中站得住。请对每一通呼叫都记录结论与"是否留了言",而不只记录出问题的那些——这是几个月后回答一宗投诉的证据,它该和你其余的审计轨迹放在同一处。请把语音信箱话术本身当成一个固定的、已审批的产物,而不是让模型逐通生成,因为一段生成出来的消息就是一段未经审查的预录消息,而没有录音你无法证明当时说了什么。还要在活动开始前解析号码的线路类型,因为无线那一类承载的是更严格的同意要求。

催收及类似的受监管外呼还要再加一层:到底谁有权听到这条消息,以及当信箱被债务人以外的人接走时可以说什么。催收与催缴智能体讲了那些第三方披露规则——正是它们让一条热情、详尽的语音信箱消息在该领域构成违规。

步骤 6该量什么,以及检测什么时候值得它那份延迟。

检测是你呼叫路径里的一个分类器,就按分类器来做埋点。真正驱动决策的四个数字:

  • 从接通算起的首词时间。目标远低于一秒;一旦有人重新引入阻塞式检测器,就是这个指标先变坏。请对 p95 而不是均值告警——一条阻塞的呼叫路径会先表现为双峰分布,很久之后均值才动。
  • 按方向而不是按总体统计的误分类率。把机器判成真人,浪费一段对话,还可能让你的智能体对着一卷磁带讲话。把真人判成机器更糟:你在一个真人说话中途切断了他,而在电话营销活动里还可能构成放弃呼叫。这两种错误代价不同,所以单一的准确率数字毫无用处。请对着你真正面对的那份不对称去调阈值。
  • 按活动、按 30 天窗口计的放弃率,并挂一个紧急停止开关。规则的分母是"已被真人接起的呼叫",窗口是滚动的活动周期,所以请那样计算,而不是按天、按全站算。外呼语音智能体讲的是同一指标的拨号节奏那一侧。
  • 按运营商与地区分布的结论构成。问候习惯、运营商拦截功能与网络音质的差异大到:在一个市场上调好的检测器,在另一个市场上会无声退化。分布漂移是早期预警;投诉是迟到的那个。

把这些放进与智能体其余部分同一套评测流水线,而不是放进一个没人打开的电话系统看板——评测语音智能体讲了录音回放,而机器应答的音频采集便宜、也很好做回归测试,因为它不会变。

那么检测什么时候值得它的代价?三种情形,而且比默认配置暗示的要窄得多。当你需要"问候语结束"的时点,因为这通电话的目的就是在提示音处留下一段录音消息——此时 DetectMessageEnd 的长延迟是特性,而且根本没有人会被怠慢。当活动是冷名单且话术很长,于是"对着磁带讲话"的期望浪费超过"四秒静默"的期望损害。以及当下游系统需要这个分类来做路由或抑制——把一个号码标为"今日已触达信箱",使下一次尝试不是一次重拨。除此之外,在热名单上配短话术,诚实的配置是:关掉检测,写好一段开头。

按这个顺序上线。先写那四秒开头——身份、目的、回拨方式——并确认它既作为对人说的完整问候成立,也作为被截断的语音信箱成立。然后在接通时就启动智能体,把检测作为并发事件流订阅,并为每一个结论类别(包括 unknown 与 fax)都写显式分支。再加上第二个同意字段,没有它就拒绝投递语音信箱。把"从接通算起的首词时间"和两个方向的误分类率分开量,并把"按活动、按 30 天窗口"的放弃率接到紧急停止开关上。如果你今天只改一件事,就把检测器前面那个 await 删掉:在默认配置下它要花掉约四秒去对抗一条两秒的规则,而且这段静默是花在那十通里有一通真的被人接起的那一通上。