前阵在帮一个内部团队调知识库问答的时候,我遇到了一个很典型的场景:资料已经整整齐齐传到了文档平台,也能用关键词搜到标题,但员工真正问题抛过来时就傻眼了。比如有人问“报销卡在审批流程了怎么办”,文档里写的是“财务审批长期未处理”,关键词完全不重合,传统搜索引擎就是找不出来。后来我们把方案改成Spring AI + 向量数据库做搜索扩展,按RAG的链路口径重做了一版检索服务,问题才真正解决。
这次实操涉及的东西很多:向量化、切片、存储、相似度召回、prompt组装。考虑到内容较多,我把它拆成上、下两篇来写。上篇主线是把“搜索扩展”这件事讲透——为什么传统检索失效、向量数据库怎么选、RAG检索链路里的细节怎么调,再顺手给出一个Spring Boot + PGVector的最小可运行工程。适合给那些想在现有Spring体系里引入AI能力,但又不是从零做大模型平台的后端团队参考。
1. 搜索扩展本质上要解决什么问题
1.1 传统关键词搜索的“天花板”
传统搜索看着成熟,但它的核心假设是:用户输入的关键词、文档里出现的词、以及语义背后的概念,三者必须能对上。倒排索引和BM25这类算法再强,也只是在“字面重合度”上做文章。你搜“工资发放延迟”,文档里写的是“薪酬到账时间超过约定日”,字面几乎不重合,经典检索基本无能为力。这不是引擎的问题,而是查的词与存的词不是同一套表达体系。
在实际的业务系统里,这种“字面不匹配”比我们想象中普遍得多。用户会口语化提问、会打错字、会用岗位术语或行业黑话,文档作者又习惯用书面语境来写。两边没有共享同一词表,传统检索召回效果自然差。还有一个更隐蔽的问题:传统检索只能告诉你“哪些文档命中关键词”,不能告诉你“哪一段话确实回答了这个问题”。它返回的是文档列表,需要用户自己再打开、翻阅、判断。放在知识库问答场景里,这个体验其实是非常原始的。
1.2 RAG:给大模型再接一块“外接记忆”
RAG的全称是Retrieval-Augmented Generation,翻译过来就是“检索增强生成”。思路可以理解成开卷考试:大模型本身像是一个已经接受过通识训练的学生,知识面广但不够新、不够细,也没法记住你公司内部成百上千份制度文档。开卷考试的核心动作是允许带资料,而RAG要解决的问题就是:在它作答之前,先帮它找到与当前题目最相关的几页参考资料,再让它结合这些资料回答。
这里的关键点是,找参考资料不能再靠关键词了,而要语义相似。用户的句子和文档里的段落虽然用词不同,但意思相近,我们希望系统能感知到这种“近义”。实现方式是先把文档切成小块,用Embedding模型把每一小块转成一个高维向量,存入向量数据库。查询问题时,也把问题转成向量,然后在数据库里找出与这个提问向量最接近的若干个文档块。在大模型生成答案之前,把检索出来的文档块拼接在prompt中作为上下文,这样模型就有了可参考的事实依据。
这套流程可以拆成两个阶段:离线阶段负责文档解析、切片、向量化、写库;在线阶段负责问题向量化、相似度检索、拼接上下文、调用大模型。多数Spring项目改造的着力点其实就在这两个阶段上,业务代码不需要大动,新增一套检索服务即可。
1.3 什么业务场景才值得上这套方案
项目聊到一定阶段,我一般会让团队先停下来,认真做一个“值不值得上”的判断。如果你的搜索场景只要求精确匹配,比如查订单号、查身份证、查商品ID,用传统数据库查询就行,别引入向量化和RAG,那是给系统平白增加复杂度。
真正适合搜索扩展的场景有这些共性:业务需要理解自然语言;知识内容是长期累积的、非结构化的文档;答案需要引用具体来源;文档更新频率较高,不适合每次重训模型。典型落地包括企业制度问答、售后知识库、研发Wiki检索、客服话术推荐、法规和合规文件问答等。
不适合的情况也有:纯结构化数据查询,比如“本月销
