外呼客户管理系统配任务分两层:名单池先定来源与去重,分配规则再定分给谁分多少,拒呼标记、重复拦截与每日上限放在最后
自有系统生产库里客户表 656 行,拿 17 个字段逐个查「有值率」,结果很扎眼:group、stage、data_type、file_type 四个字段各有 653 行有值(99.5%),star_level 和 lead_level 各 647 行(98.6%),channel 646 行(98.5%);而 folder_id 只有 17 行(2.6%)、level 只有 6 行(0.9%)、request_amount 一行都没有。
这意味着什么?如果你在配拨打任务时把筛选条件写在「名单池」或者「客户等级」上,任务会筛出个位数甚至 0 条,然后你会以为是系统有 bug。实际上系统没错,是字段没值——外呼客户管理系统配任务这件事,八成的问题不在分配算法,而在「你用来筛选的那一列,本来就没人填」。
这篇不讲选型,只讲配置顺序:两层结构怎么拆、名单池拿什么当筛选条件、分配规则设几个参数、拒呼与重复拨打拦在哪一层、每日上限怎么跟冷却天数联动。文中数字全部来自自有系统生产库实测(2026-10-26),只描述字段与结构,不涉及任何真实客户信息。
一、外呼客户管理系统配任务分两层:先把名单池和分配规则拆开
很多人配任务是一步到位:选一批客户、选几个坐席、点确定。这样配出来的任务,出问题时你没法判断是「选错了人」还是「选错了客户」。正确做法是先拆成两层,配的时候按顺序来:
第一层,名单池——「这批客户是谁」。它回答的问题只有一个:这一批要打的客户,是按什么条件圈出来的?圈出来多少条?谁圈的、什么时候圈的?这一层的产出是一份快照:圈定那一刻的客户集合,之后客户状态变了,任务里的名单不变。
第二层,分配规则——「这批客户怎么分」。它回答:平均分还是按人指定、一人分多少、分不完怎么办、分下去几天内必须打完。这一层的产出是一组归属关系:客户 → 坐席 + 期限。
两层分开的好处,在本库的数据里能直接看到。33 条拨打任务里,只有 13 条带名单池标识(folder_id 有值),占 39.4%,涉及 3 个不同的名单池;剩下 20 条任务没有名单池标识,说明这 20 条任务在配置时是「直接圈客户」而不是「引用一个池」。这两种做法在数据上的差别是:前者可复用(同一个池可以反复建任务),后者不可复用(每次都要重新圈,圈的条件没有留痕)。
再补一个结构事实:全库 74 张表里,没有任何一张以 folder 命名的表。也就是说,「名单池」在这个系统里不是一个实体对象,只是一个挂在客户行上的外键字段(folder_id)。这带来两个后果:一是名单池没有名字、没有创建人、没有描述,事后没法知道「这 17 个客户当初是按什么条件进的池」;二是名单池不能带自己的筛选条件,只能靠人工往里面放。
所以如果你正在配第一套任务,建议按这个顺序落地,一步都不要跳:
第一步,定池。先明确这一批客户的来源(哪个渠道、哪次导入、哪个业务员名下),把它做成一个可命名的池。池要存三样东西:名字、筛选条件(存成条件表达式而不是结果)、创建人与时间。
第二步,验池。点一下「预览条数」,确认圈出来多少。条数为 0 或个位数,先回头查字段有值率(第二节给方法),别急着建任务。
第三步,建任务。任务指向这个池,记录池的标识和当时的条数快照。
第四步,配规则。选分法、填每人条数、定截止时间(第三节)。
第五步,加拦截。先把拒呼标记和重复拨打拦上,再放坐席开打(第四、五节)。
第六步,定上限。最后才设「每人每天打多少通」和「打不通的隔几天再打」(第六节)。
这个顺序的道理很简单:前两步错了,后面全是白干;拦截放在分配之前,能少分出去一批不该打的号;上限放在最后,因为它是个调节阀,不是准入条件。
二、名单池:来源、去重、可筛字段三件事
名单池最容易被忽略的是第三件事——你打算用来筛选的那一列,到底有多少行有值。本库 656 个客户的实测,按「能不能当筛选条件」分三档:
第一档:能筛,有值率 97% 以上。group 653 行、stage 653 行、file_type 653 行、data_type 652 行、star_level 647 行、lead_level 647 行、channel 646 行、last_follow_at 640 行。这八个字段可以放心作为筛选维度,筛出来的量级和总量接近。
第二档:勉强能筛,89% 左右。communication_status 585 行(89.2%)。差的那 71 行会在筛选时悄无声息地掉出去,所以用它当条件时,要意识到你筛的是「填过沟通状态的客户」,不是「全部客户」。
第三档:一筛就空,不到 10%。source_lead_id 53 行(8.1%)、assignee_id 21 行(3.2%)、folder_id 17 行(2.6%)、level 6 行(0.9%)、next_follow_up 6 行(0.9%)、call_task_id 5 行(0.8%)、industry 1 行(0.15%)、request_amount 0 行。这一档里,assignee_id 和 folder_id 最危险——它们看起来是最自然的筛选条件(「我名下的客户」「这个池里的客户」),实际几乎全空。
为什么这几个字段这么空?不是录入偷懒,是业务流程还没走到那一步:assignee_id 只在「分配给人」时才写,folder_id 只在「放进池」时才写,level 只在「评过级」时才写,request_amount 只在「登记过需求金额」时才写。换句话说,这些字段是「动作的结果」,不是「客户的属性」。用结果字段去筛选,等于在问「哪些客户已经被做过某个动作」,而不是「哪些客户符合某个特征」。
结论很直接:筛选条件优先用属性字段,别用结果字段。属性字段是 group / stage / data_type / channel / star_level / file_type;结果字段是 assignee_id / folder_id / call_task_id / level。前者天然有值,后者取决于动作有没有发生。
再说来源和去重这两件事,它们决定名单池的质量上限:
来源要落到「批次」而不是「渠道」。本库 channel 只有 4 个取值(646 行有值,其中 614 行集中在同一个渠道名上)。这个粒度太粗——同一个渠道可能进了十批名单,质量差别巨大,但库里看起来是同一堆。正确做法是每次导入生成一个批次号,批次上带:导入时间、文件名、总行数、成功行数、失败行数、去重掉了多少行。任务指向批次,而不是渠道。
去重要在入池前做,不要在分配后做。同一个客户在两个池里,两个池各建一个任务分给两个人,就是撞单。去重的键要选对:手机号是最常用的,但本库存在一个号码对应多个客户的情况,所以号码只能当第一道粗筛,真正判定要靠客户 ID + 业务唯一标识。具体怎么设计去重规则,见助贷线索去重怎么做,那篇把重复率的算法和下降路径都写了。
这一节的验收动作:打开你的客户表,用一条 SQL 数一遍每个候选筛选字段的有值行数,除以总行数。低于 90% 的,从筛选条件里删掉——不是删字段,是别拿它当条件。这一条能省掉后面 80% 的「任务里怎么只有 3 条客户」的排查。
三、分配规则:三种分法各自的适用场景与参数
分法不多,但选错分法的代价很大。客户管理系统里这一层通常只有三个按钮,背后是三套完全不同的分配逻辑。本库 33 条任务用的分法只有两种:CUSTOM(按人指定)29 条,AVERAGE(平均分)4 条。其中按人指定的 29 条任务一共分了 4789 个客户,平均一条任务 165 个客户;平均分的 4 条任务一共分了 15 个客户,平均一条任务 3.75 个客户。
这两个数不是用来比大小的,是用来说明两件事:一是「按人指定」在实际使用中承担了绝大多数量(4789 / 4804 = 99.7%),说明大家习惯先圈一大批再手动挑人;二是「平均分」用得非常少(4 条、15 个客户),说明它被当成了试验功能或者应急功能,而不是常规分法。
三种分法,各自的适用场景:
① 平均分(AVERAGE)。把名单池里的客户按坐席数均分,除不尽的余数给前面几个人。适合:名单质量一致、坐席能力接近、要做公平对比的场合(比如新人培训期的练习名单、A/B 测试两套话术)。不适合:名单里混着高意向和低意向客户——均分会把好客户平均稀释掉,谁都不满意。
② 按人指定(CUSTOM)。人工把客户或客户段指定给具体坐席。适合:老客户回访(客户认人)、按区域或行业分工、按能力分配高价值客户。代价是它把分配变成了手工活,量大时必然出错(本库一条任务塞 165 个客户,很难相信是逐条挑的)。
③ 按规则分(条件路由)。按条件自动路由,比如「channel = A 的分给一组、data_type = 企业主的分给二组、剩余的平均分」。这是最理想的一种,但对字段有值率要求最高——条件字段没值,路由就全落到「剩余」那一档。本库暂时没有看到用这种分法的任务,原因从第二节的数据能猜到:能用来自动路由的字段就那么几个。
参数要填四个,缺一个就会出怪事:
每人条数——一次分多少。填 0 或不填,有的实现会理解成「不限」,结果一个人被分了上千条。
是否允许同一客户分给多人——默认必须是否。允许的话就会撞单,两个坐席同时打同一个客户,客户体验极差,内部还要打一架分业绩。
分不完怎么办——剩下一部分没分出去的(比如 100 条分给 7 个人,余 2 条),要么留池等下一轮,要么给指定的人兜底。这个规则要显式定,别留给程序自己决定。
截止时间——任务到哪天结束。本库 33 条任务里,状态为 EXPIRED(已过期)的有 27 条,占 81.8%;COMPLETED(已完成)只有 3 条,DELETED(已删除)3 条。过期远多于完成,说明绝大多数任务是被时间推着结束的,不是被「打完」结束的。
这一节的验收动作:建一条 10 个客户的测试任务,选平均分、分给 3 个人,然后看分完的结果——是不是 4/3/3?剩余 1 条去哪了?再建一条按人指定的,看能不能把同一个客户指定给两个人(应该被拦住)。两个测试跑完,分法的行为就摸清了。
四、拒呼标记:库里没有独立的黑名单表,先定用哪个字段承载
「客户说了不要再打」这件事,必须有一个地方记。本库的现状是:74 张表里,没有任何一张以 black、block、refuse 或 opt_out 命名的表;客户表里也没有屏蔽类字段(40 个列逐一看过,没有 status 这种开关,表示阶段的字段叫 stage)。
没有专用表,就得先用现有字段承载。三种可选做法,按推荐顺序:
① 用 group 字段承载(最快落地)。本库 group 有 653 行有值(99.5%),现状取值以 normal 为主、vip 一个。做法是新增一个取值 refuse(或你习惯的叫法),标记时把 group 改成 refuse,同时在备注里写清「什么时候、因为什么、谁说的」。好处是立刻可用,且因为 group 有值率高,筛选「group ≠ refuse」不会掉数据。坏处是语义混用——group 本来是客户分组,现在兼职做屏蔽开关。
② 用独立字段承载(推荐)。给客户表加一列 refuse_call(布尔)+ 一列 refuse_reason(文本)+ 一列 refuse_at(时间)。三列的成本很低,好处是语义清晰、可审计、不会和分组逻辑打架。
③ 用独立表承载(最规范,但要改代码)。建一张 refuse_list:号码、客户 ID、来源(客户口头/投诉/内部标记)、原因、生效时间、失效时间(有些拒呼是有期限的)、操作人。好处是「同一个号码换了客户还是不能打」这种情况能覆盖——拒呼的对象其实是号码,不是客户行。
这三条不是互斥的,实际落地通常是 ②+③:客户行上放一个快标识(查询快),独立表放完整记录(可审计)。①只适合今天就要用、来不及改结构的场合。
不管用哪种,有三条规则必须写进配置里,否则标了也白标:
规则一:标记必须在拨打前生效,不是拨打后。很多系统的做法是先分下去、开打之后再检查,结果是被拒呼的客户还是被打了一次。正确做法是在「建任务圈名单」那一步就排除掉,让拒呼客户进不了任务。
规则二:拒呼要能撤回,但要留痕。客户过半年又说可以打了,这种情形真实存在。撤回时不要直接把标记删掉,要写一条「解除」记录(谁解的、依据是什么),否则以后没法解释「为什么这个客户被标记过又打了」。
规则三:拒呼的粒度是号码,不是客户。同一个客户换了号码,新号码理论上可以打;同一个号码换了客户名,仍然不能打。如果你的拒呼只挂在客户行上,第二种情况必然会漏。
这一节的验收动作:找一个测试客户,标上拒呼,然后建一条包含他的任务,看他还进不进得来。进得来就说明拦截没在圈名单那一步生效,得往前挪。
五、重复拨打拦截:三层拦截,拦在不同位置
「同一个客户天天被打」是外呼业务里投诉量最高的一类问题,也是最容易用配置解决的一类。要拦它,得先分清三种「重复」,因为它们发生在不同层级、要用不同办法拦:
第一层,任务内重复。同一批名单里,同一个客户出现了两次(导入时没去重,或者同一个号码对应了两个客户行)。本库的号码重复情况是:566 个号码里,488 个对应 1 个客户、72 个对应 2 个、1 个对应 3 个、5 个对应 4 个——78 个号码对应了多行。这批号码如果进了同一个任务,就会被分给不同的人,各打一遍。
拦法:在圈名单那一步按「号码 + 客户 ID」做一次内部去重,同一个号码只保留一行(保留哪一行要定规则:最近跟进的?最新创建的?金额最高的?)。
第二层,客户级重复(跨任务)。客户在昨天的任务里,今天又出现在新任务里。这在新人团队里非常常见:主管每天圈「未接通」的客户建新任务,昨天没接通的今天自然又进来了,如果昨天那个人还在跟进,就是两个人打同一个客户。
拦法:圈名单时加一个条件——「最近 N 天内被拨打过的排除」,N 就是冷却天数。这个条件是配置里最该有、最常被漏掉的一个。
第三层,号码级重复(跨坐席)。客户在 A 坐席名下,但号码被 B 坐席的任务圈进去了。这属于归属与名单的冲突,光靠拨号拦截拦不住,要在分配那一步校验「这个客户当前归属人是谁」。
拦法:分配时校验归属。归属人为空才允许分配;归属人非空时,要么跳过,要么走转交流程(转交要留记录)。本库 assignee_id 只有 21 行有值(3.2%),意味着当前绝大多数客户是无归属状态——这既解释了为什么跨坐席重复打的问题还没爆发,也提醒你:一旦开始大规模分配,归属冲突会集中出现。
三层拦完,客户管理系统里还要配一个「当天重复」的兜底:同一客户同一天内被拨打超过 N 次就提示。这个 N 建议设成 1(接通的情况下)或 2(未接通、隔几小时再试一次),别设成 5——设成 5 等于没拦。
这一节的验收动作:拿三个测试客户建一条任务——一个号码重复两行、一个昨天刚打过、一个有归属人。三条任务建完,看这三个客户分别被拦在哪一层、提示语说的是什么原因。三个都拦住了,这套拦截才算配通。
六、每日上限与冷却天数:两个参数怎么联动
这两个参数经常被当成两个独立的数字来填,其实它们是同一件事的两端:每日上限管「一个人一天能打多少」,冷却天数管「一个客户几天内不能被再打」。只调其中一个,另一个会立刻成为瓶颈。
先说清楚它们各自约束的是谁。每日上限约束的是坐席:本库这类参数按角色分档,普通成员、主管、管理员各有一个每日可认领的上限(本库的配置是普通成员 20、主管 10、管理员 10)。冷却天数约束的是客户:一个客户被拨打后,多少天内不能再进入新任务(本库回收冷却天数是 15 天)。
联动关系可以这样算:假设 10 个坐席、每人每天上限 20 通,一天最多消耗 200 通;如果名单池有 600 个客户,一轮要 3 天打完。这 3 天里,打过的客户如果 15 天冷却,那么第 4 天开始就没名单可打了——除非新名单持续进来。这就是最常见的「任务建了却打不完」的算术原因:不是坐席不努力,是名单池的补充速度跟不上消耗速度。
反过来的情况也常见:冷却天数设得太短(比如 3 天),名单池又小,于是同一个客户三天两头被不同的人打,投诉量上升,接通率下降,坐席越打越没劲。接通率的下降幅度通常比名单质量下降得更快,因为客户开始标记骚扰了。
推荐的三组搭配,按名单池规模选(这是经验值,不是行业标准,你自己的数据要自己调):
名单池远大于日消耗(比如池里几万条、日消耗几百条):冷却天数设长一点(15–30 天),把「打过的先放一放」当成常态。此时瓶颈在坐席产能,不在名单。
名单池与日消耗接近(一轮 3–5 天打完):冷却天数设 7–10 天,同时准备「二次跟进」的独立名单——第一次没接通的客户进一个专门的回访池,别和全新名单混在一起。
名单池明显不够:这时候不要调短冷却天数来凑量,那是在透支客户耐心。正确做法是降低每日上限(让有限的名单摊得更均匀),或者去补名单来源。补来源的路径和成本结构,见助贷获客成本怎么算。
还有两个参数容易和上面两个混:
单任务领取上限——一个人一次能从任务里领多少条(本库配置里有一个「单人最多锁定 50 条」的参数)。它的作用是防止一个人把整个池子锁死,让其他人没得打。它约束的是「未打先占」,不是「当天产出」,和每日上限是两件事。
锁定超时——领了没打多久自动释放。这个必须有,否则坐席一次性领 50 条、打了 5 条就下班,剩下 45 条锁在那里,别人看得见打不着。
这一节的验收动作:拿本月的实际数据算一笔——总名单数 ÷(坐席数 × 每人每日上限)= 理论打完天数;再看冷却天数是不是大于这个天数。小于的话,你一定会遇到「名单不够打」;大于太多,你一定会遇到「池子里全是打过的」。
七、任务跑完不结:27 条过期任务的成因与结案规则
本库 33 条任务的状态分布:EXPIRED 27 条(81.8%)、COMPLETED 3 条、DELETED 3 条。没有任何一条是「进行中」——这本身是个信号:任务要么过期,要么删掉,很少有正常走完的。
再结合另一组数:33 条任务的 total_count 与 assigned_count 完全相等(33/33 都是分出去多少就记多少,本库这两列一直相等)。这说明「分配」这一步是成功的,问题出在分配之后——客户分下去了,但任务没有被正常收尾。
任务不结案带来三个后果,每一个都会让后续配置变形:
后果一:统计口径失真。过期任务里的「已打/未打」不再更新,你按任务看完成率,看到的是历史快照,不是现状。后果二:名单被占。任务里的客户如果没有随着任务结束而释放,下次圈名单时会被「已在本任务中」这个条件排掉,名单池看起来越来越小。后果三:责任不清。过期任务没人复盘,打不完的原因(名单质量、坐席产能、拦截太严)永远不会被定位,下一条任务还是同样的参数。
结案规则建议定三条,都很简单:
规则一:到截止时间自动结案,并把未打的客户释放回池。释放时打上标记(来源任务、释放时间),这样下次圈名单能区分「从没打过」和「打过没打完」。
规则二:打完就结,不要等截止时间。判据是未打条数为 0。很多实现只在定时任务里检查过期,没检查「提前打完」,于是打完的任务要挂到截止日才结案,白占名单 3 天。
规则三:结案必须留一条结果记录。至少要能回答:总条数、已打、未打、接通多少、平均时长、结案原因(打完/到期/人工终止)。没有这条记录,一个月后没人能复盘。
还有一件事要顺手做掉:任务建的时候把当时的筛选条件原文存下来(不是存结果,是存条件)。本库 33 条任务里,filter_params 大部分是空对象或者只带一个分配数量,等于没有留痕。有条件原文,下次建同类任务就能复制;没有,就只能凭记忆重配一遍,配出来还不一样。
这一节的验收动作:打开任务列表,按截止时间倒序,看最近 10 条任务里「未打条数 > 0 且已过期」的有几条。这几条对应的客户现在能不能被新任务圈到?圈不到,说明释放规则没做。
八、外呼客户管理系统配任务常见问题
为什么我圈出来的名单只有几条,明明客户表里有几百个?
九成是筛选字段没值。先在客户表上数一遍你用的那个字段有多少行有值:本库 assignee_id 只有 21/656(3.2%)、folder_id 只有 17/656(2.6%)、level 只有 6/656(0.9%)。换成 group、stage、data_type、channel 这类有值率 98% 以上的属性字段,条数立刻就对了。
名单池到底要不要建?直接用条件圈不行吗?
能用,但不可复用。用条件圈的是「一次性结果」,条件本身没被存下来,下次建任务要重新配一遍,配出来还未必一样。建池的价值是把条件留痕,并且让「这个池打了多少轮、每轮接通率多少」变成可比的数据。本库 33 条任务里只有 13 条带池标识,剩下 20 条就是「一次性圈」的典型。
坐席说名单不够打,是名单问题还是上限问题?
先算一笔账:名单总数 ÷(坐席数 × 每人每日上限)= 理论打完天数。如果这个天数小于冷却天数,就是名单不够;如果大于冷却天数很多,就是上限压得太低。两个数都对上还打不完,才去看拦截规则是不是太严(比如把「最近 15 天打过的」全排掉了)。
拒呼标记没有独立表,先用 group 字段顶着行不行?
能顶,但要接受两个代价:一是语义混用,group 本来是分组的,现在兼职屏蔽开关,以后做分组统计时要记得把它排除;二是粒度问题,group 挂在客户行上,同一个号码换了个客户名就拦不住了。短期用 group 顶,同时给客户表加 refuse_call + refuse_at 两列,是成本最低的过渡方案。
回到开头那两个数:653 行有值和 17 行有值。它们的差别不是数据质量问题,是「属性」和「动作结果」的差别——属性天生就有,动作没发生就是空。配任务的功夫,八成花在分清这两类字段上:用属性圈名单,用动作结果做校验。前者决定你能圈出多少人,后者决定你圈出来的人该不该打。想继续看这两条线怎么接,可以顺着看助贷线索怎么自动分配里路由规则的部分,或者客户公海池怎么设计里回收与再分配的部分;分配下去之后怎么提高日呼量,见助贷团队怎么提升日呼量;号码被投诉封停的风险,见助贷电销怎么防封号;打完之后的质检,见电销智能质检怎么做;移动端坐席怎么看到这批名单,见电销APP要哪些功能才够用;客户档案这一侧的整体搭法,见贷款中介客户管理系统怎么搭;拒呼与名单来源的合规边界,见助贷AI外呼合规吗;版本与参数能力对照见价格与版本说明。