简介:面向企业IT负责人、客服管理者及需要从云租赁转向自建呼叫中心的项目人员,这份建设计划书围绕自建背景、建设目标、建设原则与实施步骤展开,重点回应租赁成本高、客户数据安全不可控等问题。压缩包仅含1个docx文档,大小约51KB,正文以目录化方式组织,便于按章节查阅和复用为立项材料。已有204人学习。文档不仅给出基于CTI与计算机网络技术的一体化系统目标,还细化了先进性、可靠性、开放性、扩展性、实用性、可管理性和安全性等原则,并将建设划分为基础坐席、多媒体渠道接入、冗余热备三个阶段;建设蓝图部分则从节约成本、规范服务流程、整合内部资源等角度说明自建价值,适合用于方案汇报、需求梳理与后续招标参考。
1. 从一张二十万的年费单说起
去年帮一个朋友核算他们客服部门的年度预算,一张表看得我直皱眉:二十个座席,一年光系统租赁费就是二十万整,摊到每个座席头上一年一万。而他们真正天天用的功能,掰着手指头数得过来——电话打进来、排队、录音、导话单。更别扭的是客户资料全躺在别人的机房里,想加一个稍微复杂点的满意度回访流程,得提工单等排期。这份《呼叫中心建设计划书》就是从那个节点长出来的东西:它不讲概念,讲的是呼叫中心自建这条路怎么走通——为什么自建、建成什么样、分几期建、每一期交付什么。里面有一期到三期的呼叫中心建设流程,有七条建设原则,还有成本和安全这两笔账的算法。适合两类人看:正在用第三方云坐席、规模过了十人、开始对数据存放位置敏感的客服或 IT 负责人;以及接了“帮我搭一套呼叫中心”这种活、需要照着它去拆设备清单和接口清单的实施工程师。
2. 自建背景与建设目标:把年租金还原成一张五年账单
2.1 云租赁模式的三个隐性成本
计划书里把自建的理由写得很直白:系统只有使用权没有所有权,租赁合同一解,使用权立刻收回;核心客户信息存在服务商机房,公司对这些数据的去向缺乏有效监管;再加上逐年支付的租金,从运营成本角度看已经不合身。这三句话翻译成工程语言,就是三个隐性成本。
第一个是资产成本。租赁模式下你付的是“服务费”,不进固定资产,账面上轻,但五年下来就是一百万,且合同到期后手里什么都没有。自建是把这笔钱前置成一笔资本开支加每年的运维开支,设备、软件 license、录音存储盘都在自己手上。我一般给决策层算账的时候会拉一张五年表,把一次性投入拆成硬件、平台软件、集成实施、线路这四块,运维侧按设备原值的百分之十到十五估年维保,再和租金做交叉对比——通常第三年到第四年是拐点,座席规模越大拐点越早。
第二个是数据成本。这一条在计划书里被单独拎出来强调,因为客服系统里最值钱的不是话务能力,是客户名单和通话录音。录音里有身份证号、订单号、住址,这些东西落在别人机房,一旦泄露对公司利益和企业形象就是不可挽回的损失。自建的实质是把数据的物理边界收回到自己可控的网络里,再叠加权限分级和审计日志。
第三个是弹性成本。云坐席按座席数计价,促销季临时加十个座席,费用是按月甚至按年跳的;自建以后加座席只是加 license 和话机,边际成本低得多。反过来说,如果你的坐席规模长期在五人以下、话务量波动极大,自建反而是负担,这一点计划书没写,但选型时必须自己心里有数。
| 成本科目 | 云租赁(按年) | 自建(首年 / 次年及以后) |
|---|---|---|
| 系统使用 | 约 20 万(20 座席 × 1 万) | 平台软件一次性 license |
| 硬件与网络 | 含在租金内 | 服务器、网关、话机一次性采购 |
| 线路中继 | 含在租金内 | 按中继数付月租 |
| 运维人力 | 服务商承担 | 自担或外包年维保 |
| 数据归属 | 服务商机房 | 自有网络内 |
提示:五年 TCO 表里最容易漏的是“线路月租”和“运维人力”两项,前者往往占自建年支出的三到四成,后者要么算一个人月的成本,要么算外包维保费,别当零。
2.2 建设目标拆成可验收的技术指标
计划书对目标的表述是:采用计算机电话集成(CTI)技术和计算机网络技术,平台一体化设计,建成智能化、集成化、稳定性高的信息系统,并且要能提供开发接口与公司业务系统整合。这句话如果直接交给供应商,回来的方案十有八九是漂亮的 PPT。得往下拆。
CTI 这三个字是整套系统的中枢。它的作用是把电话网里的事件——振铃、应答、挂机、按键——翻译成计算机能处理的消息,再把计算机的指令翻译成电话动作,比如发起外呼、转接、监听。没有 CTI,交换机就只是一台交换机;有了 CTI,来电号码才能在坐席屏幕上弹出客户档案,通话结束后话单才能自动落到业务库里。所以验收时第一个要看的就是 CTI 中间件对外暴露的接口清单,而不是界面长什么样。
平台一体化是第二个关键词。它的反面是拼装:IVR 一套系统、录音一套系统、报表又一套系统,三份数据对不上,坐席工号在三个库里分别是三个 ID。一体化意味着 ACD 排队、IVR 导航、录音、坐席状态、报表共用同一套数据模型和同一份话单。判断方法很朴素:问一句“一个呼损电话,在报表里能不能追到它在 IVR 的哪一层按键放弃的?”能答上来,基本就是一体化的底子。
我把目标整理成了下面这张接口验收清单,招标或者内部立项时可以直接拿去用。
| 接口 | 方向 | 关键字段 | 验收口径 |
|---|---|---|---|
| 座席签入签出 | 业务系统 → CTI | 工号、分机、技能组 | 签入后 3 秒内可分配来电 |
| 来电弹屏事件 | CTI → 业务系统 | 主叫号、被叫号、会话 ID、进入时间 | 振铃后 1 秒内推送 |
| 外呼发起 | 业务系统 → CTI | 被叫号、坐席分机、任务 ID | 返回会话 ID 可反查 |
| 话单与录音索引 | CTI → 业务系统 | 会话 ID、通话时长、录音路径、挂机原因 | 挂机后 30 秒内可查 |
| 状态同步 | CTI → 业务系统 | 坐席状态、队列长度、等待时长 | 每分钟至少一次全量或增量 |
接口的报文形态,常见做法是 HTTP 回调加 JSON,或者消息队列。一份能直接拿来对字段的回调长这样:
{ "event": "call.answered", // 事件类型:ringing / answered / released "session_id": "20240612-0001-8837", // 会话唯一标识,话单和录音都靠它对上 "caller": "13800000000", // 主叫号,匿名来电走 IVR 时为空 "callee": "4008001234", // 被叫号,对应哪个业务线 "agent_id": "A1024", // 应答座席工号 "skill_group": "after_sale", // 技能组,路由依据 "queue_wait_ms": 18500, // 排队等待时长,考核 ACD 的核心指标 "ivr_path": ["1", "3", "0"], // 走过的 IVR 按键路径,做漏斗分析用 "timestamp": "2024-06-12T10:21:07+08:00" }session_id是整条链路的串联键,录音文件名、话单主键、业务工单里的关联字段都用它;ivr_path这一项很多方案里没有,加上以后才做得了“客户在哪一层按键流失”的分析;queue_wait_ms要区分“含 IVR 时长”和“纯排队时长”,否则报表和坐席感受永远对不上。
2.3 七条建设原则翻译成采购与验收条款
计划书列了七条原则:先进性、可靠性、开放性、扩展性、实用性、可管理性、安全性。这七个词本身没问题,问题在于它们太正确,正确到没法验收。我的做法是每一条都落一条可测的条款。
先进性落到实处就是协议版本和架构形态:接入侧支持 SIP 中继而不只是传统数字中继,媒体协商走标准 SDP,未来上视频或文本坐席时不用换核心。可靠性落到指标上是年可用率不低于 99.9%、核心设备双电源、平台服务支持进程级自愈。开放性落到条款上是“提供标准协议接口和二次开发接口,接口文档随系统交付”,这句话必须写进合同附件,否则交付时给一个只有截图没有字段说明的 PDF。
扩展性最容易被含糊过去。硬件侧的表述应该是“端口数可按槽位线性扩展”,软件侧是“座席 license 可按个增购,不要求整套升级”。实用性我一般用操作步数衡量:坐席完成一次“接听—查单—记录—挂机”全流程,点击次数不超过若干次,这是唯一能拿给一线试用的标准。可管理性是业务量监控,得有实时队列看板和历史话务曲线,能看出哪个时段该扩容。安全性是分级授权、录音加密存储、操作日志留存不少于六个月。
| 原则 | 落地条款 | 验收方式 |
|---|---|---|
| 先进性 | 支持 SIP 中继、信令媒体分离、预留多媒体接入 | 查看组网方案与协议抓包 |
| 可靠性 | 年可用率 ≥ 99.9%,核心设备双电源,服务进程自愈 | 试运行期统计中断时长 |
| 开放性 | 提供标准接口与二次开发文档,字段级说明 | 接口文档评审 + 联调跑通 |
| 扩展性 | 端口与 license 线性扩容,不换核心平台 | 书面承诺 + 扩容报价单 |
| 实用性 | 单次通话操作步数达标,新坐席半天上手 | 一线试用打分 |
| 可管理性 | 实时队列看板、历史话务报表、告警阈值可配 | 现场演示 |
| 安全性 | 权限分级、录音加密、日志留存 ≥ 6 个月 | 安全测评与日志抽查 |
注意:“先进性”这一条最怕写成对未来技术的无条件承诺。合理写法是约定“未来新增渠道时通过标准协议接入,不更换核心交换与 CTI 组件”,把范围框住,否则供应商要么不敢签,要么签了做不到。
3. 建设蓝图与总体架构:一通路电话从外线到耳麦要走几层
3.1 五层链路拆解
计划书里的“建设蓝图”只有三行文字——节约成本、规范服务流程、整合公司资源。要把它变成能落地的架构,得先知道一通电话从运营商外线进来,到坐席耳麦出声,中间经过哪些环节。我按职责把它拆成五层,这个分层在后续做故障定位时特别管用,因为每一层的排查手段完全不同。
接入层负责和运营商对接,形态上是数字中继(E1)或者 SIP 中继。数字中继稳定、时延低,但需要专门的网关设备和线路施工;SIP 中继开通快、按并发计费灵活,但对网络质量敏感。多数新建项目会选 SIP 中继起步,保留一路数字中继做备份。
交换与媒体层是软交换或者 IP-PBX,管信令接续和媒体流转发,同时提供录音所需的媒体旁路能力。这一层是整个系统的心脏,也是唯一不建议用“够用就行”思路选型的地方——它的并发能力和编解码支持直接决定了后面能不能上视频。
CTI 层是中间件,做事件转换和状态机管理,对外提供接口。业务应用层是坐席真正看到的东西:ACD 排队、IVR 导航、录音、坐席工作台、报表。数据层是业务库、录音文件存储和日志。录音文件不要放数据库,走独立存储或者对象存储,数据库里只存索引,这个决定在容量测算那一节会体现得很清楚。
| 层次 | 典型组件 | 关键指标 | 常见故障表现 |
|---|---|---|---|
| 接入层 | SIP 中继 / 数字中继网关 | 并发路数、接通率 | 外线打不进、单通 |
| 交换媒体层 | 软交换 / IP-PBX | 并发通话数、CPU、丢包率 | 通话断续、无声 |
| CTI 层 | CTI 中间件、状态服务 | 事件时延、接口可用率 | 弹屏慢、状态卡死 |
| 业务应用层 | ACD、IVR、录音、工作台、报表 | 排队时长、IVR 完成率 | 排队异常、录音缺失 |
| 数据层 | 业务库、录音存储、日志 | 磁盘余量、慢查询 | 报表打不开、写入超时 |
排查的时候按层往下切就行:外线打不进先看接入层中继状态;能进但没声音,多半在交换媒体层的媒体协商;能通但坐席屏幕不弹,去 CTI 层看事件有没有推出来;弹了但记不了单,才轮到应用层和数据层。这套顺序能省掉大量扯皮。
3.2 交付物清单:一份计划书应该拆成哪些文档
计划书本身是母版,真正推进项目时它得被拆成一组文档,否则每次开会都在重复讨论同一件事。我一般按下面的结构组织,一个目录对应一个交付节点,谁负责、什么时候给,一目了然。
call-center-build/ ├── 01-现状与需求/ │ ├── 现状调研.md # 现有坐席数、话务量、系统短板 │ ├── 业务需求清单.md # 按技能组拆的功能需求 │ └── 非功能需求.md # 可用率、并发、留存期、安全等级 ├── 02-方案设计/ │ ├── 总体架构.md # 五层链路 + 组网拓扑说明 │ ├── 编号与路由规划.md # 分机号段、技能组、IVR 流程编号 │ ├── 网络与安全方案.md # 地址段、端口开放清单、权限矩阵 │ └── 接口协议.md # 字段级说明,联调的唯一依据 ├── 03-采购与实施/ │ ├── 设备清单BOM.md # 型号、数量、单价、到货周期 │ ├── 实施计划.md # 分期里程碑与责任人 │ └── 割接方案.md # 回退步骤必须写死 └── 04-验收与运维/ ├── 验收标准.md # 每条对应一个可执行用例 ├── 试运行记录.md # 中断、投诉、工单统计 └── 运维手册.md # 日常巡检项与常见故障处置这份结构里我最看重两份:编号与路由规划.md和接口协议.md。前者定死了分机号段、技能组编码、IVR 每一层的按键含义,后面所有报表、录音命名、权限分配都依赖它,改一次牵动全局;后者是联调时唯一能吵架的依据,字段名、类型、空值含义写清楚,能省掉两周的来回。
至于那份 docx 原件,它的价值在于把“为什么建”讲清楚了,可以直接作为立项材料的第一章。但它的后半部分(步骤、蓝图)颗粒度太粗,不能直接当实施方案用,得按上面的目录展开。很多项目翻车就翻在这里——拿着立项文档直接开工,做到一半发现没人定义过“什么叫验收通过”。
3.3 容量测算:二十个座席到底要多少中继和磁盘
计划书里只有“满足现有座席规模”这一句,具体数字得自己算。三个参数最关键:中继并发数、录音存储、带宽。
中继并发不能按座席数一对一配。坐席不可能同时都在通话,行业内常用的并发系数在 0.1 到 0.3 之间,取决于业务类型——售后报修这类通话时长长、排队多的场景取值偏高,回访外呼偏低。二十个座席按 0.2 算就是 4 路同时通话,但中继要留突发余量,实际配置一般上浮到 8 到 10 路。有个反直觉的点:中继配得比并发少,高峰期客户听到的就是忙音,而报表上的“接通率”反而好看,因为打不进来的根本不计入。
录音存储按码率乘时长算。G.711 单声道是 64 kbps,一小时约 27.5 MB,双声道翻倍。留存期按合规要求来,金融类往往要求半年以上。下面这段脚本把这几件事一次算完,改几个常数就能出采购参数。
# 呼叫中心容量估算:中继并发、录音存储、带宽 SEATS = 20 # 座席数 CONCURRENCY_RATIO = 0.2 # 并发系数,售后类偏高,外呼类偏低 BURST_MARGIN = 2.0 # 中继突发余量倍数,避免高峰忙音 AVG_CALL_SEC = 180 # 平均通话时长(秒),含 IVR 停留 REC_KBPS = 64 # G.711 单声道录音码率 CHANNELS_PER_REC = 1 # 录音声道数,双声道填 2 KEEP_DAYS = 180 # 录音留存天数 DAILY_CALLS = 900 # 日均呼叫量,按忙时话务 × 8 粗估 # 1) 中继并发:理论并发 × 突发余量,向上取整 concurrent = SEATS * CONCURRENCY_RATIO trunk_channels = int(concurrent * BURST_MARGIN + 0.9999) # 2) 单路每小时录音体积:kbps -> KB/s -> MB/h mb_per_hour = REC_KBPS * 1000 / 8 * 3600 / 1024 / 1024 * CHANNELS_PER_REC # 3) 每日录音量 = 日呼叫量 × 平均时长 × 单路每秒体积 bytes_per_sec = REC_KBPS * 1000 / 8 * CHANNELS_PER_REC daily_mb = DAILY_CALLS * AVG_CALL_SEC * bytes_per_sec / 1024 / 1024 storage_gb = daily_mb * KEEP_DAYS / 1024 # 4) 带宽:每路通话上下行各一份 RTP 流,再留 30% 余量 bandwidth_mbps = concurrent * REC_KBPS * 2 / 1024 * 1.3 print(f"建议中继并发: {trunk_channels} 路") print(f"单路每小时录音: {mb_per_hour:.1f} MB") print(f"每日录音量: {daily_mb:.0f} MB") print(f"{KEEP_DAYS} 天录音存储: {storage_gb:.0f} GB") print(f"坐席侧带宽: {bandwidth_mbps:.1f} Mbps")按这组参数跑出来,二十个座席配 8 路中继,录音每天约 4.6 GB,半年留存约 830 GB,坐席侧带宽不到 1 Mbps。这几个数字看着不大,但它们是采购单上的硬指标:录音盘要按这个量再乘一点五备容量,因为峰值日和补录会超出均值;带宽那 30% 的余量不是可选项,同一栋楼里如果坐席和服务器之间还要跑办公流量,得单独划 VLAN。
DAILY_CALLS这个参数最容易拍脑袋。合理做法是拿现网云坐席的历史话单,导出最近三个月每天的通话条数,取第 90 百分位而不是平均值,否则一到大促就爆盘。
4. 三步走实施路线:一期保通话、二期上多媒体、后期补冗余
4.1 一期:最小可用系统的功能排序与割接
计划书对一期的定义是“使用自建方式建设一套呼叫中心系统,满足现有座席规模与功能需求”。这句话在实施时会被无限放大,因为“现有功能需求”可以列出一百项。我的做法是强制排序,只保六件事:座席签入签出、来电弹屏、IVR 导航、ACD 排队、全程录音、基础话单报表。在线客服、满意度评价、质检打分这些统统推到二期,理由是它们都建立在话务主线跑通的基础上,主线没稳就上这些,等于在沙地上盖楼。
一期的时间安排里,线路开通是最长的前置项,运营商中继从申请到开通动辄两三周,必须第一个启动。平台部署和 IVR 流程设计可以并行,业务系统对接放在平台跑通之后。真正要留足时间的是试运行——至少两周双系统并行,老系统接一部分话务,新系统接一部分,每天比对两边的通话条数和录音完整性。差异超过千分之五就不许割接。
割接当晚最怕的是“上去了才发现录音没写进去”。我习惯写一个冒烟脚本,每一项检查失败就停下,不许继续。
#!/usr/bin/env bash # 割接夜冒烟检查:任一项失败立即中止,走回退方案 set -u FAIL=0 check() { # $1=名称 $2=命令 if eval "$2" >/dev/null 2>&1; then echo "[OK] $1" else echo "[FAIL] $1"; FAIL=1 fi } # 1) SIP 中继信令端口是否可达(按实际 IP 与端口替换) check "SIP 中继 5060" "nc -z -w3 10.10.10.1 5060" # 2) CTI 事件服务是否在监听 check "CTI 事件服务 8080" "nc -z -w3 127.0.0.1 8080" # 3) 业务库连通 check "业务库 3306" "nc -z -w3 10.10.20.5 3306" # 4) 录音盘剩余空间 ≥ 50GB,防止一晚上写满 check "录音盘余量" "test $(df -m /data/rec | awk 'NR==2{print $4}') -ge 51200" # 5) 分机注册数是否等于座席数(按实际接口取数) check "在册分机数" "test $(curl -s http://127.0.0.1:8080/api/agents | grep -o '\"reg\"' | wc -l) -ge 20" [ $FAIL -eq 0 ] && echo "全部通过,可以开始拨测" || { echo "存在失败项,暂停割接"; exit 1; }nc -z只验证端口通不通,验证不了协议是否正常,所以最后一步一定要用真实话机拨测:内线互拨、外线呼入、IVR 按键转人工、挂机后查录音——四个用例走完,才叫真的通。df那一项看着土,但录音写满是自建系统最常见的一类事故,把它前置到割接前检查,比事后补数据便宜太多。
注意:割接方案里必须写死回退步骤和回退判定条件,例如“割接后两小时内呼损率超过 15% 或录音完整率低于 95%,立即回退”。没有回退方案的割接不叫割接,叫赌。
4.2 二期:多媒体接入统一到一张会话表
二期要上在线客服、微博、微信、APP 这些渠道。最容易犯的错误是每个渠道单独建一套系统,结果客服要开四个窗口,客户在微信问了一半转到电话,坐席完全不知道之前说过什么。正确的姿态是在一期就把数据模型设计成渠道无关的,二期只是往里灌新渠道的数据。
核心是一张会话表。所有渠道的进线,无论是电话、网页、公众号还是 App 内消息,都落成一条 session 记录,用channel字段区分,用customer_key做客户识别(电话号、OpenID、设备号各取其一),用统一的skill_group做技能组路由,用统一的status表达生命周期。这样二期上线时,报表、路由、质检都不用改结构。
-- 渠道无关的统一会话表:一期只写 voice,二期加渠道不改表结构 CREATE TABLE cc_session ( session_id BIGINT PRIMARY KEY, channel VARCHAR(16) NOT NULL, -- voice / webchat / wechat / app customer_key VARCHAR(64) NOT NULL, -- 电话号 / OpenID / 设备号,做客户归并 skill_group VARCHAR(32) NOT NULL, -- 路由依据,与座席技能组对齐 agent_id BIGINT, -- 会话结束时归属的座席 start_time DATETIME NOT NULL, -- 进入系统的时刻,排队时长从此刻起算 first_resp_at DATETIME, -- 首次响应时刻,算 SLA 的起点 end_time DATETIME, -- 结束时刻,未结束为 NULL status TINYINT NOT NULL, -- 1排队 2处理中 3已结束 4已放弃 priority TINYINT DEFAULT 0, -- 会员/VIP 提升路由优先级 ticket_id BIGINT, -- 关联业务工单,渠道流转靠它串起来 KEY idx_customer (customer_key), KEY idx_status_skill (status, skill_group) );字段里有两处值得多说。customer_key必须在二期之前就想清楚归并规则,同一个人用手机号打进电话、用 OpenID 发微信,系统得认得是同一个人,否则“全渠道客户视图”就是一句空话,这块通常要在业务库里建一张客户主数据映射表。first_resp_at单独存一列而不是靠计算,是因为 SLA 考核里首次响应时长是硬指标,靠start_time减出来的口径一旦有争议就扯不清。
路由策略上,多媒体渠道和电话的区别在于没有“占线”概念,一个坐席可以同时挂五六个文字会话,所以并发控制不能沿用电话那套“一条线一个坐席”的模型,得给每个坐席配一个“最大并行会话数”,并且文字会话的排队排序要引入等待时长和优先级的组合权重,否则 VIP 客户在微信里等十分钟没人理,比电话打不进来还伤。
4.3 后期:双机热备、数据库主从与录音冗余的取舍
计划书把双机热备、数据库双机热备、录音冗余放在后期,这个顺序是对的。一期就上全套冗余,投入产出比很差,而且复杂性会把上线时间拖垮。但“后期”不等于“不做”,关键是知道每一块冗余解决什么问题、付出什么代价。
CTI 双机有主备和双活两种。主备是一台工作、一台待命,靠心跳检测,主挂了 VIP 漂移到备机,切换时间通常在几十秒,代价是备机长期闲置。双活是两台同时处理事件,容量翻倍,但对状态同步要求高,座席的签入状态、通话上下文必须实时复制,做不好会出现“切换后坐席全部掉线”这种事故。多数二十到五十座席的规模,主备足够,把省下的钱投到录音冗余上更实在。
数据库这块,主从复制解决读扩展和备份,主备切换解决可用性,两者的 RTO 差一个量级。话单和录音索引这类数据,我的倾向是主从加定时全备,切换靠人工或半自动脚本,因为业务库一旦自动切换出错,数据一致性修复的成本远高于停服十分钟。
录音冗余分两层:一是存储冗余,本地盘加集中存储双写,或者异步复制到另一台机器;二是路径冗余,录音服务的网口做镜像,保证媒体流不经过应用进程也能被抓到。第二层比第一层更常被忽略,但它决定了录音服务进程崩掉时,正在进行的通话还能不能留下音频。
| 组件 | 冗余方式 | 切换时间 | 成本量级 | 建议阶段 |
|---|---|---|---|---|
| CTI 中间件 | 主备 + VIP 漂移 | 30 秒内 | 中 | 后期第一批 |
| 数据库 | 主从复制 + 定时全备 | 分钟级(人工) | 中 | 后期第一批 |
| 录音存储 | 本地 + 集中双写 | 无感 | 低 | 一期就该做 |
| 录音链路 | 交换机端口镜像 | 无感 | 低 | 一期就该做 |
| 软交换 | 双机集群 | 秒级 | 高 | 规模过百座席再考虑 |
这张表里我把录音的两项标成“一期就该做”,因为它们的成本极低——一块盘、一个镜像口——但价值极高。冗余投入要按“故障后果 ÷ 实现成本”排序,而不是按计划书里的时间顺序照抄。
5. 避坑与排查:自建呼叫中心最容易翻车的五个点
5.1 上线阶段的三类硬伤
第一类,分机注册成功、能振铃,接起来双方都没声音。现象很迷惑人,因为信令是通的。原因基本都在媒体协商:坐席在 NAT 后面,SDP 里带的是内网地址,对方按这个地址发 RTP 包,自然收不到。解决办法是把媒体服务器的公网地址写进配置,强制走媒体中继,同时把 RTP 端口段整段放开,别只开 5060。还有一个隐蔽原因是有防火墙或路由设备开了 SIP ALG,它会把 SDP 内容改写坏,症状和 NAT 一模一样,排查时把 ALG 关掉先试一次,能省半天。
第二类,录音只有主叫没有被叫,或者整段是静音。现象是录音文件存在、时长正常、播放只有一方声音。原因是媒体流没经过录音服务——录音靠的是媒体旁路或端口镜像,如果坐席和网关之间的流量走的是另一条路径,镜像口上什么都抓不到。解决方式是把录音服务串进媒体路径,或者在核心交换机上把对应 VLAN 的流量镜像过来,两种做法的取舍是前者增加单点风险、后者增加交换机负载,我一般选后者配双网卡。
第三类,割接当晚一切正常,第二天早上九点系统卡死。现象是早高峰电话能进但排队不动,数据库 CPU 打满。原因通常是报表慢查询——夜里没人查报表,早上一上班所有人同时打开话单页面,一条没建索引的聚合查询把连接池占满。解决办法是在试运行阶段就把报表查询单独走从库,并且给话单表按时间建分区,历史数据归档到冷表。
5.2 运行阶段的两类慢性病
第四类,坐席天天抱怨排队久,报表上的平均等待时长却只有十几秒。现象是数据和体感严重背离。原因多半是放弃呼叫没被计入口径:客户等了六十秒挂掉,这通电话在系统里是“未接通”,很多报表默认只统计已接通的会话,于是等待时长被系统性低估。解决办法是把放弃呼叫单独统计,并且记录放弃发生时所在的队列和已等待时长,这两个字段才是扩容决策的真正依据。
第五类,双机热备切换演练成功,真出事那天切换过去,所有坐席掉线。现象是备机起来了,业务不可用。原因是 license 绑定在主机的硬件指纹或网卡 MAC 上,备机没有有效授权;或者坐席的签入状态存在主机的内存里,没有持久化。解决办法是 license 申请时就要主备两台机器都授权,签入状态落到共享存储或数据库,切换后由 CTI 服务重建状态机。演练的时候一定要拔网线拔电源,而不是在管理界面点“模拟故障”,这两种方式暴露的问题完全不是一个量级。
这五条有个共同点:都不是“设备坏了”,而是设计阶段少问了一句“这条链路断了会怎样”。自建的自由度大,代价是所有边界条件都得自己想。
6. 二次开发与改造:把 docx 里的目标翻译成能验收的东西
这份计划书不是代码,改造它的方式和改一个开源项目完全不同——你要改的是它的可执行性。我的习惯是先把三个东西固化下来,剩下的都好办。
第一个是接口契约。把第 2 章那张表扩成字段级文档,最好直接用 OpenAPI 写一份,谁对接谁按这个来。空值的语义必须写清楚,比如agent_id为空到底代表“未分配”还是“机器人应答”,这两种含义在报表里差得远。契约一旦定稿就冻结,改动走版本号,别让联调变成每天对一遍字段。
第二个是关键路径的时序。一通电话从振铃到挂机,每个环节的耗时都要能被度量:中继接入耗时、IVR 停留时长、排队时长、振铃时长、通话时长。把这些做成一条时间轴,任何性能问题都能定位到具体环节,而不是笼统地说“系统慢”。
第三个是验收用例。计划书里的七条原则,每条至少对应一个能跑一遍的用例,跑不过就是没交付。
| 改造点 | 优先级 | 验证方式 |
|---|---|---|
| 接口契约字段级定稿 | 高 | 双人评审 + 联调跑通全部事件 |
| 话单时间轴埋点 | 高 | 抽 100 通电话核对各环节耗时 |
| 录音落盘路径与命名规范 | 高 | 按 session_id 反查,完整率 ≥ 99% |
| 报表口径与放弃呼叫统计 | 中 | 与坐席体感抽样比对 |
| 双机切换演练脚本 | 中 | 真实断电演练一次 |
| 多媒体渠道数据模型预留 | 低 | 二期上线时不改表结构即为通过 |
如果二期打算自己写坐席工作台,前端不用从零造,接口通了以后工作台就是一个长连接加几个状态渲染;真正费时间的是状态机——坐席有签入、空闲、忙、小休、话后处理五六种状态,每种状态下能做什么操作、超时怎么处理,这些规则不写清楚,工作台就会变成一线天天骂的东西。我的建议是先做一张状态迁移表,把每个事件和状态转移写成可执行的判断,再动手写界面。
验证方法上,别等真话务来压。常见做法是用压测工具模拟并发呼叫,按第 3 章算出来的中继路数往上加两成,跑满一小时,看 CTI 事件有没有堆积、录音有没有丢、数据库连接池有没有被打满。压测跑过一遍,比上线后被动救火省心得多。
说个自己的教训。早些年做类似项目,我把注意力全放在功能清单上,录音落盘路径随手写了个相对路径,结果应用升级换了工作目录,历史录音全部失联——文件还在盘上,索引里的路径全废了,几百个小时的通话记录只能靠文件名手工对回去。从那以后我每次接这类项目,都先把录音落盘路径、话单主键、session_id 命名规范这三样写进验收表,联调第一件事就是拿一通测试电话从头查到尾。希望帮到你。
本文还有配套的精品资源,点击获取