销售昨天看过一条办公室搬迁需求,今天又在“新线索”里看到它。如果对方已经暂停搬迁,第二次出现带来的只是一次重复阅读;如果需求范围变了,沿用昨天的沟通准备还可能问错问题。
星河卓越旗下意客AI根据业务描述寻找匹配需求,将需求原文和相关依据积累到销售线索库,供销售继续开发客户。线索库越积越多,产品就越需要回答一个具体问题:哪些材料可以复用,哪些判断必须重做?
本文结合意客AI的原文入库与匹配实现,拆开同一来源的重复、内容变化和业务范围变化。关键在于复用已经取得的原文,不把旧需求状态当成今天的新机会。
方法图解:同一页面更新后,本轮匹配不回退到更容易命中的旧版本。
同一页面,为什么不能先做关键词过滤
例如,一家企业IT服务商要找办公室搬迁和网络调整需求,确认的搜索表达包含“办公室 网络”。同一页面先后保存了两份原文:
| 原文观察 | 保存的内容 | 与搜索条件的关系 |
|---|---|---|
| 较早一次 | 办公室要搬到新楼层,想找人调整网络 | 包含“办公室”和“网络” |
| 较晚一次 | 搬迁暂缓,暂不找服务商了 | 不再包含这组搜索词 |
如果先筛出包含关键词的版本,再从筛选结果里取最新一条,较晚的内容会先被丢掉。系统最后选中较早的原文,销售看到的仍是“正在找人调整网络”。
意客AI的CandidatePoolMatchStore.match_task()把顺序反过来:先为每个来源选择最新观察,再对这份原文做文本过滤。查询中的顺序可以从两处看出来:
SELECTDISTINCTON(o.source_id)o.source_id,o.version_id,o.observation_id,o.observed_at,o.received_at,s.source_identity,v.content-- 原代码此处拼接原文库关联与账号条件ORDERBYo.source_id,o.observed_atDESC,o.received_atDESC,o.observation_idDESC这部分先生成latest集合,外层查询随后才检查关键词、排除词,并限制本轮返回量。前面的例子因此不会回退到旧版本。
这里的“最新”是库中已保存的最新观察,排序依据是观察时间、接收时间及观察ID。它不表示系统已经发现网页上所有后续变化,也不能替代采购有效期。原文今天再次读到,里面提到的项目仍可能是去年的。
一份原文,要分清来源、版本和观察
把一次页面读取直接存成一个新客户,线索库很快就会膨胀。意客AI在candidate_ingestion.py中分别保存这些关系:
| 保存对象 | 解决的问题 |
|---|---|
来源source_id | 本次读取是否来自已知的同一个来源 |
内容版本version_id | 保存的内容是否出现了新的版本 |
观察observation_id | 这一次何时读到材料、对应哪份内容 |
候选candidate_id | 在当前业务画像与策略范围内,销售处理的是哪条候选 |
入库时,代码先查来源身份,再查该来源的内容版本;存在的来源与版本继续使用原ID。一次新的观察有自己的记录,不必因此创建一个新来源。
这对销售线索统计很关键:同一页面读了三次,不应当直接被计成三个新客户;原文改了服务地点,也应保留变化,而不是覆盖过去的材料后让同事失去比较依据。
新研究可以复用候选,内容变化则推进版本
候选的复用还有业务范围。匹配代码按账号、业务画像版本、策略版本与来源一起查找候选,实际使用的范围是:
scope=(tenant,claims.user_id,task['profile_version_id'],task['strategy_version_id'],original['source_id'])因此,同一来源在同一业务范围内再次命中时,可以延续已有candidate_id。它仍是一条可追溯的候选;本轮匹配有新的match_id,用来记录这次任务为什么带回它。
如果保存的原文版本变化,代码在合适的观察顺序下推进候选的revision,并指向新版本。相同内容版本则保留当前候选观察绑定,不为每次重复读取都创建新候选。
业务画像或策略版本变了,不能只沿用旧范围里的适配结论。例如,IT服务商从北京扩展到天津,或者停止承接服务器运维,原文与新业务的关系就需要重新判断。材料值得保存,不意味着以前的“适合我们”永远有效。
这一机制处理的是来源身份与业务范围内的复用。不同网站转载了同一件事,仍需要额外判断它们是否指向同一需求;不能把这里的来源去重解释成跨平台语义重复全部消失。
查询完成以后,还要防一次并发变化
还有一个不容易在正常演示里出现的问题:匹配查询取得了版本A,准备保存候选时,采集端已经收到同一来源的版本B。
如果只相信第一次查询结果,本轮仍可能保存旧版本。match_task()会取得与入库端一致的来源事务锁,在等待结束后再查一次最新观察。核心判断是:
cursor.execute('SELECT o.observation_id '+_POOL_FROM+''' AND o.source_id=%s ORDER BY o.observed_at DESC,o.received_at DESC, o.observation_id DESC LIMIT 1''',(tenant,claims.user_id,original['source_id']))ifcursor.fetchone()!=(original['observation_id'],):continue最新观察与第一次选择不一致时,这条旧选择不继续写入本轮候选。此处选择保守跳过,不把等待锁之前取得的内容当作仍然最新。
这比在界面里简单提示“数据已更新”更靠前:它约束的是本次匹配究竟依据哪份原文,后续解释和销售阅读才有一致的材料可以依赖。
销售接手时,仍要读最新原话
版本筛选修正了顺序问题,关键词筛选仍有自己的边界。假如最新原文写着“办公室网络已解决,不再找人”,它还包含两个关键词。没有相应排除条件时,字符串匹配仍可能命中,后续就需要根据最新原话继续评估需求状态。
因此,销售接手一条线索时,先看当前原文,再看它与自己业务的关系。对仍在寻找服务商的搬迁需求,可以准备布线安排、设备沿用和实施时间的问题;原文已经写明暂停,就不继续使用昨天的开场草稿。
意客AI线索库承担的是寻找和整理需求材料的工作,让销售从具体问题开始开发客户。原文复用减少已经取得材料的重复整理,版本与业务范围保留判断依据,新的研究继续寻找与这项业务有关的需求。销售拿到的材料应该能解释“为什么这一条值得继续了解”,而不是只展示又多了多少条记录。
关于按周期继续寻找需求,可接着阅读:AI获客如何持续监控销售线索?意客AI的周期任务设计。
意客AI产品团队/北京星河卓越科技有限公司