一条需求写着“11月15日提交响应文件”,销售觉得还有时间。读到后半段才发现,采购文件领取截至11月8日,报名又是另一个期限。业务很匹配,准备材料的顺序却可能错了。
AI获客产品把需求找回来之后,还要帮销售更快读懂:这是什么阶段的需求,参与前要完成什么,原文中的联系方式用于哪件事。只摘一处“截止时间”,很容易漏掉决定下一步的条件。
星河卓越的意客AI围绕业务描述寻找匹配的公开需求,再把原文和匹配理由留在线索库里。本文拆开其中一个具体阅读环节:candidateActionChecklist.ts如何为不同来源组织行动检查项、保留多个时间阶段的原文,并把每一处提示指回它的出处。
先认出材料类型,才知道该读哪一组条件
对一个知识库软件团队来说,“采购公告”“项目成交结果”和“采购经验分享”可能同时命中搜索词。它们值得读的内容不同,下一步也不同。
代码没有看见“采购”两个字就选公告清单。公告分支同时要求来源是PAGE,再检查标题结尾的公告措辞,或正文中的采购主体与参与程序组合:
consttitle=source.kind==="COMMENT"?null:source.title;constprocurement=source.kind==="PAGE"&&(noticeTitle.test(title??"")||procurementSubject.test(source.body)&&procurementProcedure.test(source.body));noticeTitle覆盖采购、询价、供应商征集、成交结果、终止等公告名称。命中之后,组件给出的阅读顺序是核对阶段、检查文件领取与报名响应、查看资格和联系入口。即使标题是“成交结果公告”,清单也会先要求确认阶段,不会直接给出“仍可参与”的结论。
社交内容清单先让销售看发布者自己的意思:是在寻找交付方,还是介绍自己承接的服务。普通页面走通用清单,关注需求主体、业务范围和实际联系路径。来源类型决定问题怎么问,关键词只帮助找到该读的段落。
这个取舍让产品的帮助更具体:同样找到一条“知识库系统”材料,销售不必每次从头想阅读顺序;但是否接得了这个项目,仍要结合原文和自己的交付能力判断。
一条需求有三个时间阶段,不能挤在一个槽位里
例如,一条知识库系统询价公告里有这些材料:
| 必经步骤 | 正文写法 | 错读后的问题 |
|---|---|---|
| 获取文件 | 11月4日至11月8日 | 只记响应日,忽略取得文件的期限 |
| 报名 | 11月10日截止 | 文件拿到了,却没有完成报名 |
| 提交响应 | 11月15日截止 | 把它误当成所有步骤的最后机会 |
把三个期限合成一个“项目截止日”,会丢掉流程关系。当前实现为获取文件、报名、提交响应分别保留词法位置;正文与已保存的作者补充又分成两组。重复出现的响应时间因此不会占掉文件领取的全部位置。
方法图解:文件领取、报名、响应分别保留原文位置;补充内容单独呈现。
代码中的关键分组如下,阶段匹配表达式由timingStages定义:
constgroups=[fields.filter(item=>!item.field.startsWith("author_updates.")),fields.filter(item=>item.field.startsWith("author_updates.")),];for(constgroupofgroups){for(conststageoftimingStages){// 在这一组里寻找本阶段对应的原文位置// 命中后用 excerpt(...) 保存上下文}}这里按阶段寻找的是文字位置,还没有把日期解析为统一时间。正文只写“11月8日”,输出就保留这个写法;不能擅自补成某年的午夜,也不能仅凭补充数组的位置决定哪条更正最新。
组件保留的上下文最多约320个UTF-16代码单元。文件获取通常向前留80个;报名阶段向前留160个,考虑到日期可能写在“参加报名”之前。这样,销售看到的不是孤立的“报名”二字,而是附近的期限、动作和条件。
三份输入,直接看真实函数返回什么
我们为本地函数调用准备了三份简短输入。第一份在文件、报名和响应段落之间插入较长的项目介绍,避免它们刚好全落在同一截取窗口里;再补一条“文件获取截至11月9日”的作者说明。第二份是成交结果公告,第三份是采购主帖下面的“学习了,谢谢”。
调用当前源码中的buildCandidateActionChecklist():
constresult=buildCandidateActionChecklist(source);constexactReferences=result.references.every(ref=>actionReferenceMatchesSource(source,ref));前两份输入进入公告清单,评论进入社交内容清单。本次返回的原文位置如下:
| 输入 | 原文位置 | 读者应看见的区别 |
|---|---|---|
| 询价公告及一条补充 | 6处 | 文件、报名、响应及作者补充分别留下位置 |
| 成交结果公告 | 1处 | 同一片段带状态与联系标签,仍需核对项目阶段 |
| 主帖下的感谢评论 | 0处 | 不借用主帖的采购标题给评论作者制造需求 |
第一份返回的时间片段保留了正文中的11月8日、11月10日、11月15日,也保留了补充中的11月9日。六处位置不等于六条销售线索,更不等于六个新客户;它们是同一份材料中可供阅读的出处。这能省掉重复翻找段落的工作。
评论这个例子尤其容易被忽略。COMMENT.title往往来自主帖或页面容器。如果直接拿它当评论作者的证据,一个只说“学习了”的人,也可能被包装成“正在采购知识库系统”。实现把评论标题排除,采购线索就不会从父级标题中凭空继承。
每条提示都能回到原文,而不是只剩一句结论
片段保存的不只有quote,还有field、start、end。例如,作者补充独立保存在author_updates.0,不会被塞回正文后失去归属。页面组件用这些位置显示引用,并提供“在原文中定位”按钮。
本次返回的六处引用,逐一通过了源码里的actionReferenceMatchesSource():从对应字段按起止位置截取,得到的文本与保存引用完全相同。
定位使用UTF-16偏移,与JavaScript的String.slice()一致。截取边缘遇到emoji等代理对时,代码会调整边界,避免把一个字符切成两半。复核函数还会拒绝越界、空引用和切断代理对的位置。
这套设计的价值不在于让一段摘要显得更肯定。它把阅读提示与原文绑在一起:销售可以从“报名可能有期限”直接跳到那段文字,再确认条件,而不是凭摘要去准备材料或找错联系人。
实际使用时,建议先读状态,再看自己尚未完成的必经步骤,接着确认资格和联系路径。公告里的代理机构电话可能用于咨询流程,文件领取地址也不等于销售开发入口;这些差别要在上下文里读出来。当前片段定位不会自动认定联系人是决策人,也不会完成报名或发送消息。
对AI获客产品而言,搜索负责带回可能相关的材料,线索库负责保留依据,阅读组件负责让依据更容易使用。这个环节做扎实,销售拿到的就不只是一个搜索链接,而是一条能继续判断、安排动作的客户开发线索。
延伸阅读:AI获客怎样减少重复线索?意客AI的原文复用与版本筛选
意客AI产品团队 · 北京星河卓越科技有限公司