瞬维AI踩过的坑:AI获客智能体线索去重与分级的实现细节
我们团队在做 AI 获客智能体的时候,有段时间被线索重复的问题搞得头大。同一个用户,在抖音评论问一句、私信问一句、视频号又留个言,后台就生成了三条线索,销售一天到晚打重复电话,客户都被打烦了,还浪费了大量人力。
后来我们花了一个多月做线索去重和分级系统,把重复线索率从最开始的 38 % 降到了 3 % 以下,今天把踩过的坑和实现细节写出来,给做同类系统的团队做个参考。
一、最开始用手机号去重,为什么完全不够用
最开始我们的去重逻辑特别简单:同一个手机号就算同一个线索。跑了一周就发现问题太大了:
- 很多用户根本不留手机号,只留微信号或者抖音号,按手机号去重完全识别不出来
- 同一个用户用不同的手机号咨询,也识别不出来
- 用户留的手机号经常写错,少一位多一位,匹配不上
- 同一个用户在不同平台留的联系方式不一样,根本对不上
最严重的时候,我们后台一周生成了一千两百多条线索,其中有近一半是重复的,销售打过去一半都是"我已经问过了",体验特别差。
二、多维度指纹去重:不能只靠联系方式
后来我们改成了多维度指纹去重,不再只看手机号,而是综合多个维度给每个用户生成唯一的身份指纹:
第一维是平台账号 ID。同一个平台的同一个用户,账号 ID 是唯一的,这个是最准的,优先用这个匹配。
第二维是联系方式。包括手机号、微信号、QQ 号,做归一化处理之后匹配,比如手机号去掉空格和横杠,微信号去掉大小写差异。
第三维是设备指纹。通过用户的设备信息、IP 地址、浏览器特征生成设备指纹,同一个设备的不同账号也能关联上。
第四维是行为相似度。比如用户的提问内容高度相似、咨询的时间接近、所在地区一样,就算联系方式不一样,也判定为同一个用户。
# 用户身份指纹生成逻辑
def generate_user_fingerprint(user_data):
fingerprint = {}
# 平台账号ID优先
if user_data.get('platform_uid'):
fingerprint['uid'] = user_data['platform_uid']
# 联系方式归一化
if user_data.get('phone'):
fingerprint['phone'] = normalize_phone(user_data['phone'])
if user_data.get('wechat'):
fingerprint['wechat'] = user_data['wechat'].lower()
# 设备指纹
fingerprint['device'] = generate_device_fp(user_data['device_info'])
# 行为特征
fingerprint['behavior'] = {
'region': user_data['region'],
'intent': user_data['intent'],
'consult_time': user_data['consult_time'].date()
}
return hash(fingerprint)
用了多维度指纹之后,重复线索率直接从 38 % 降到了 8 %,效果好了很多,但还是有漏网之鱼。
下面是完整的指纹匹配与线索合并逻辑,包括指纹存储结构、匹配判定和合并策略:
# 指纹存储结构:以指纹哈希为 key,value 保存该用户的所有线索
# 用 Redis 或内存表存储均可,生产环境建议加 TTL 防止无限膨胀
fingerprint_index = {} # {fingerprint_hash: user_profile}
# 用户档案结构
def create_user_profile(lead):
return {
'user_id': None, # 合并后分配的统一用户 ID
'fingerprints': set(), # 该用户的所有指纹哈希
'leads': [lead], # 关联的线索列表
'first_seen': lead['consult_time'],
'last_seen': lead['consult_time'],
}
# 指纹匹配逻辑:按优先级逐维尝试,命中即判定为同一用户
def match_and_merge(new_lead, fingerprint_index):
new_fp = generate_user_fingerprint(new_lead)
# 1. 先按平台账号 ID 精确匹配(最准,优先)
if new_fp.get('uid'):
for fp_hash, profile in fingerprint_index.items():
if new_fp['uid'] in profile['fingerprints']:
return merge_lead(profile, new_lead, new_fp, 'uid')
# 2. 再按归一化后的联系方式匹配
for key in ('phone', 'wechat'):
if new_fp.get(key):
for fp_hash, profile in fingerprint_index.items():
if new_fp[key] in profile['fingerprints']:
return merge_lead(profile, new_lead, new_fp, key)
# 3. 最后按设备指纹 + 行为相似度做模糊匹配
for fp_hash, profile in fingerprint_index.items():
if new_fp['device'] in profile['fingerprints']:
if behavior_similar(new_fp['behavior'], profile['behavior']):
return merge_lead(profile, new_lead, new_fp, 'device+behavior')
# 4. 都没命中,创建新用户档案
profile = create_user_profile(new_lead)
profile['user_id'] = new_lead['lead_id']
profile['fingerprints'].add(hash(new_fp))
fingerprint_index[hash(new_fp)] = profile
return profile
# 合并策略:把新线索并入已有用户,并更新指纹集合与最近活跃时间
def merge_lead(profile, new_lead, new_fp, matched_by):
profile['leads'].append(new_lead)
profile['fingerprints'].add(hash(new_fp))
profile['last_seen'] = max(profile['last_seen'], new_lead['consult_time'])
# 记录命中维度,便于后续排查误判/漏判
new_lead['matched_by'] = matched_by
return profile
下面是线索从进入系统到完成去重和分级的完整流程:
三、线索分级:不要让销售在低意向用户上浪费时间
去重解决之后,我们又发现一个问题:销售的时间是有限的,一天打不了多少电话,但很多线索其实是低意向的,比如只是随便问一句,根本没有购买意向,销售把时间花在这些用户身上,转化率特别低。
所以我们又加了线索分级系统,根据用户的行为把线索分成 S / A / B / C 四个等级:
- S 级:明确问价格、问服务内容、主动留联系方式,意向最高,24 小时内必须跟进
- A 级:问了具体的功能问题,有明确需求,48 小时内跟进
- B 级:只是泛泛问一下,没有明确需求,一周内跟进一次就行
- C 级:纯闲聊、问无关问题,直接进公海,不用跟进
分级的规则是基于用户的对话内容、提问深度、是否留联系方式、咨询时长这些维度,用规则+小模型打分实现的,不用大模型,成本低速度还快。
下面是线索分级的具体实现,基于对话内容关键词、是否留联系方式、咨询时长等维度计算意向分数,再按阈值判定 S / A / B / C 四级:
# 意向关键词表:命中即加分,权重越高代表购买意向越强
HIGH_INTENT_KEYWORDS = ['多少钱', '价格', '怎么收费', '套餐', '怎么合作', '能试用吗']
MID_INTENT_KEYWORDS = ['怎么用', '支持哪些功能', '能对接吗', '有没有案例', '部署方式']
# 线索分级主函数:输入对话内容、是否留联系方式、咨询时长等特征,输出 S/A/B/C 等级
def grade_lead(conversation_text, left_contact, consult_minutes):
score = 0
# 1. 对话内容关键词打分
for kw in HIGH_INTENT_KEYWORDS:
if kw in conversation_text:
score += 30 # 问价格/合作,意向最强
for kw in MID_INTENT_KEYWORDS:
if kw in conversation_text:
score += 15 # 问功能/对接,有明确需求
# 2. 是否留联系方式:主动留联系方式是强意向信号
if left_contact:
score += 25
# 3. 咨询时长:聊得越久,意向越高
if consult_minutes >= 10:
score += 20
elif consult_minutes >= 5:
score += 10
# 4. 按阈值判定等级,并给出对应的跟进策略
if score >= 70:
return 'S', score, '高意向,24 小时内必须跟进'
elif score >= 45:
return 'A', score, '明确需求,48 小时内跟进'
elif score >= 20:
return 'B', score, '泛泛询问,一周内跟进一次'
else:
return 'C', score, '低意向,直接进公海,不用跟进'
# 使用示例
grade, score, strategy = grade_lead(
conversation_text='你们这个怎么收费?能试用吗?',
left_contact=True,
consult_minutes=12
)
print(grade, score, strategy) # 输出:S 105 高意向,24 小时内必须跟进
四、实测效果和边界
上线去重和分级系统之后,我们跑了一个月的数据:
- 重复线索率从 38 % 降到了 3.2 %
- 销售的有效通话率从 42 % 提升到了 78 %
- 线索转化率比之前提升了 60 % 多
当然这个方案也有边界:如果用户完全用不同的设备、不同的联系方式、不同的账号来咨询,还是会识别成不同的用户,但这种情况在实际业务里占比不到 1 %,影响不大。另外行为相似度的阈值要根据自己的业务调,太松了会误判,太紧了会漏判。
写在最后
做获客系统,不要只盯着前端的对话智能,后端的线索处理其实更影响最终的转化效果。线索去重和分级看起来是小功能,但做好了能直接提升销售的人效,比多搞几个花里胡哨的对话功能有用多了。
做工程嘛,把基础细节做扎实,比什么都强。
本文为技术实践分享,不构成任何商业建议。
浙公网安备 33010602011771号