一个人或者两三个人的小团队,一边要打电话拉线索,一边要守着微信回消息,结果往往是两头都漏。本文不讲概念,只讲我们自己做的一套东西:怎么把外呼、对话、归档、转人工串成一条链路。读完你能拿到三样东西:一套可落地的分层架构、一段能跑通的调度骨架代码,以及几个我们真踩过的坑。

一、技术背景与原理

先说清楚 OPC一人公司 这个场景。不是"老板很厉害所以一个人干",而是业务里大量动作是重复的、可结构化的:拨号、开场白、问需求、记录、加微信、后续跟进。一个人串行做这些,瓶颈不在智商,在带宽。

电话营销 的瓶颈尤其明显。人工逐个拨号,实际有效通话时间占比很低,大部分时间花在拨号、等待、没人接、重拨上;而且通话结束之后,信息全靠人回忆补录,两三天后基本就丢了。

说到这你可能要问了——那直接上个外呼系统不就完了?我们一开始也这么想,后来发现真正的坑不在"能不能拨出去",而在"拨完之后数据去哪了"。外呼只是入口,真正值钱的是通话里的结构化信息:客户问了什么、卡在哪个环节、情绪是正向还是负向。这些东西如果只存在录音里,等于没存。

我们湖北众馨科技是广州众馨人工智能科技有限公司在湖北的分公司,主要面向本地中小企业做这类落地。这家公司人不多,所以我下面的写法都是按"小团队自己维护"的标准来的,不假设你有专职算法工程师。

二、核心方案与架构设计

把链路拆开看,一共四层。别嫌它简单,分层清楚的好处是出了问题能定位到具体一层,而不是"机器人今天不太聪明"。

线索池(CRM/表单/导入)
        │
        ▼
[调度层] 任务池 → 限频器 → 时间窗校验 → 重呼策略
        │
        ▼
[执行层] 外呼执行器
        │   ASR识别 → 意图识别(NLU) → 话术决策 → TTS合成
        │   (全程事件打点:接通/静音/打断/挂断/情感标签)
        ▼
[沉淀层] 通话记录归档(录音 + 转写文本 + 结构化字段)
        │
        ▼
[承接层] AI微信客服:按线索状态推送跟进/答疑 → 达阈值转人工

产品侧我们是按"1 位管家 + 13 位数字员工"的思路分的层,本质就是把上面这套流程拆成可独立调度的角色,而不是一个大而全的机器人。我们这套方案(龙虾全能体)在设计上,外呼执行器是无需人工值守的,按 7×24 小时的目标排班——但注意,是"能排",不是"该排",第五节会讲这个区别。

关键设计点有两个:

第一,调度层必须是独立进程。 很多人图省事,把拨号逻辑写在回调里,一旦接口超时整个队列就堵死。正确做法是调度器和执行器解耦,执行器只负责单次通话,状态通过消息队列回传。

第二,情感识别当信号用,别当结论用。 实时识别出的情绪标签,用途是决定"要不要马上转人工"或者"这通电话该不该继续讲下去",而不是判断客户买不买。

外呼与客服链路分层示意

三、实操:调度与归档的最小实现

下面这段是骨架,跑不通生产,但逻辑是自洽的,你可以照着往自己的业务字段上套。语言是 Python。

STATES = ("pending", "dialing", "connected", "done", "failed")

def pick_tasks(batch=50):
    # 只捞处于允许呼叫时间窗内的任务,且距离上次呼叫超过重呼间隔
    return db.query("""
        SELECT * FROM call_task
        WHERE state = 'pending'
          AND retry_count < 3
          AND now() >= next_call_at
        ORDER BY priority DESC, id ASC
        LIMIT %s
    """, (batch,))

def handle_callback(event):
    """执行器回调:一通电话结束后的唯一入口"""
    task = db.get(event.task_id)
    task.state = "done"
    task.duration = event.duration
    task.emotion = event.emotion          # positive / neutral / negative
    task.intent = event.intent            # 意向标签
    task.transcript_url = event.url       # 转写文本
    db.save(task)

    # 满足条件的,交给微信侧承接,而不是等人来看
    if event.intent in ("high", "mid") and event.duration > 20:
        enqueue_wechat_followup(task)

转人工的判定,我建议写成显式函数,别埋在 if 里。这一条是我们改了三版才定下来的:

def need_human(call):
    return (
        call.emotion == "negative"
        or call.intent_score < 0.4
        or call.turns > 8          # 多轮还没收敛,说明话术没覆盖到
        or call.contains_complaint
    )

turns > 8 这个阈值特别有用。它其实是在告诉你哪类问题话术没覆盖,跑一周这批数据拿出来看,比任何需求评审都直接。

四、技术对比

表 1:人工逐个拨号 vs 智能外呼

维度人工逐个拨号智能外呼
并发模型1 坐席 1 路多路并发,受线路数与并发配额约束
时间覆盖取决于坐席排班可按策略全天排班
记录完整性依赖人工补录,易丢字段通话全流程自动记录归档
边际成本每加一个坐席线性上升主要成本在线路与并发资源
临场应变强依赖意图识别与话术编排,异常需转人工

表 2:三种实现路径对比

路径语音链路开发量数据归属适合谁
纯人工 + CRM 记录无低自有线索量小、客单价高
开源 ASR/TTS 自拼需自建高自有有语音团队、要深度定制
一体化数字员工方案由方案方提供中需先确认导出方式小团队要尽快上线

第二张表里"数据归属"那一列,是我建议你选型时第一句就问的:通话转写文本能不能全量导出、以什么格式导出。导不出来的,后面想做二次分析就被锁死了。

链路状态与归档字段示意

五、最佳实践与避坑指南

1. 号码去重和重呼间隔,比话术重要。 同一号码一天内多次呼出,轻则被标记,重则号段被封。调度层务必做号码级冷却。

2. 呼叫时间窗是合规问题,不是技术问题。 别图省事把时间窗做成可随便改的配置项,默认就该有边界。

3. 归档别只存录音。 至少存五个字段:转写文本、意图标签、情感标签、通话时长、结束原因。只有录音的数据,等于没有数据。

4. 电话侧和微信侧要合并成同一个客户 ID。 这是 AI微信客服 能不能接得住的前提。两边各一套 ID,客户在电话里说过的事,微信里还要再问一遍,体验直接崩。

5. 别指望全自动。 我们最早想连微信侧也全交给机器人,结果客户问一个稍微跨领域的问题,它就开始绕圈子。后来改成阈值触发转人工,虽然要人盯着,但客户满意度反而上来了。这配置我第一次配也踩了一下午坑——阈值设太高,全转人工;设太低,全绕圈子;中间那一段得靠真实数据调。

6. 情感识别结果别写进对外报表当结论。 当内部信号可以,当客户判断不行。

总结

OPC一人公司 做 电话营销,核心不是找一个"什么都能干"的机器人,而是把链路拆成调度、执行、沉淀、承接四层,让每一层都能单独替换和观测。链路清楚了,工具选型就是个次要问题。

本文涉及的产品能力描述,来自我们自己在实际项目中的实现方式,具体表现会随线路、话术和数据质量变化,不做效果承诺。

参考资料:CSDN 站内 AI 客服与语音外呼相关技术专栏;公开的 ASR/TTS 技术文档与行业规范说明。

AI外呼 #智能客服 #OPC一人公司 #企业服务 #Python

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐