三月某个周二早上,一位CEO问了一个本应三十秒就能回答的问题——我们有没有签过低于一百万美元的责任上限?答案确实存在。它被写下来、签了字、存了档,自始至终就躺在共享盘里。可找到它花了整整三天,没及时找到这件事,让公司付出了四万美元的代价。
每个组织都有着类似的周二。知识是真实的,它被保留下来,分散在成千上万个文件、上百种格式当中,由那天离文件柜最近的人随手组织。一家公司知道的东西,比其中任何一个人都多。真正的难题在于:怎么把它取出来。
理所当然的第一步,是给每个词建索引然后搜索。打出“责任上限”,找出所有包含“责任”和“上限”的文件。这个办法会失败,而且失败的方式值得精确说出,因为每一种失败,都指向真正的问题必须怎么做。
合同里写的并不是“责任上限”,而是“责任限制”。两个短语,同一个意思,零个共享关键词。搜索返回空结果,你就得出结论——这份文件不存在。搜索栏分辨不出“没有这份合同”和“我们有,只是归档时用了不同的措辞”。
匹配词语不是匹配语义。在一本员工手册和一份供应商协议里搜索“终止”,你会得到解雇、合同到期,可能还有一段关于停止软件授权的段落,只靠词频这样毫无意义的标准来排序。人提的是问题,不是关键词。没人会按照搜索词来思考。他们想的是:“我们签过低于一百万美元的责任上限吗?”关键词引擎压根不知道这是一个问句,更不知其中哪个词要紧。
真正能弥合差距的办法,是停止比较字词,开始比较含义。这就得把文本变成那种可以在其中测量距离的东西。一个嵌入模型读入一段文字,输出一串数字——几百个——把这段文字放在一个空间里,在那个空间中,距离意味着含义上的相似。关于年假的段落会彼此靠近。关于责任上限的段落则会落在完全不同的地方。模型是根据语言实际被使用的方式把它们放到那些位置上的,而不是根据它们共享哪些字符。
from sentence_transformers import SentenceTransformermodel = SentenceTransformer("all-MiniLM-L6-v2")texts = ["4.2 年假 \n 全职员工每年累积十五天...","远程办公政策 > 排班 \n 每周最多三天...","附录 B\n 住宿:每晚180美元,通过差旅平台预订。",vectors = model.encode(texts)print(vectors.shape) # (3, 384):三段文本,一张地图,每段384个坐标现在到了有趣的部分。把“员工第一年有多少天休假?”这个问题映射到同一个空间里,它会落在离年假段落最近的地方。那段文字里一个“假期”的词都没有,一次也没有。关键词搜索找不到的答案,语义搜索找到了。
热门跟贴