面试必看:打破TOPK限制解决跨向量聚合 #Java #Java程序员 #编程 #AI大模型 #RAG
✅ 已完成任务ID: 1522
30秒速读
核心摘要
本视频讲解RAG跨向量聚合痛点,结合Spring AI给出对应落地解决方案。
可执行建议
- 开发企业级RAG系统时可优先落地知识库隔离方案,降低检索噪音,提升聚合类问题的准确率
- 若要解决单文件内多分片的跨向量聚合问题,可跟进视频后续介绍的剩余两种解决方案
高价值评论洞察
- 有实际开发经验的受众明确指出视频当前介绍的知识库隔离方案存在未覆盖缺陷,LLM幻觉、同名等极端场景下仍会出现结果失准问题,受众更倾向选择视频后续推出的第二种解决方案
- 目标受众并非仅满足于基础方案科普,对方案落地的边界场景适配性有很高要求
用户关注点
- RAG各类解决方案在极端场景下的实际运行可靠性
- 不同方案对LLM幻觉、结果准确率问题的规避效果
可复用选题/回应建议
- 后续更新剩余两种解决方案内容时,可专门补充不同方案应对同名、信息遗漏等极端场景的实测效果对比
- 可新增衍生内容,讲解如何在现有方案基础上叠加校验逻辑,进一步降低LLM幻觉带来的结果偏差
代表性评论
- 用户认可视频内容质量,但明确表示会选用视频后续介绍的第二种方案,认为其余方案都无法规避LLM幻觉,在同名等极端场景下会出现最终名单不准的问题,价值是直接点出当前已讲方案的未覆盖痛点,为后续内容优化提供了明确的用户需求方向
标签与备注
标签
备注
暂无备注
转录文本
你在简历当中写了AI相关的技术,面试官问你RAG下如何解决跨向量的聚合问题?什么是RAG的噪音问题以及视野受限的问题?我来通过Spring AI的实战给你讲清楚。 在之前,我们已经在这个知识库资料当中上传了某学校的一年级花名册。那现在如果我通过RAG问答的方式问他“姓张的有哪些人”,这个时候他就会去我们的向量数据库中进行检索。那这种类似统计、或者我们叫做聚合的问题,就会出现局限性的问题。 第一个问题,由于我们在代码中设置了top k,我们进入向量数据库检索的时候设置top k为5,对吧?这会找到含张姓字段最多的那五个片段。所以我们即使对这一份一年级花名册做到了合理的分片,比如说我们按照每一个班级来进行分片,这里有十六个班级,哪怕我们按照最合理的分片方式分成了十六个片段,假设姓张的在这十六个班级都有,但是我们设置的top k是5,是不是就导致了视野的受限?这是第一个问题。 那另外一个问题,我们现在的知识库资料当中只上传了一年级的花名册,那以后如果上传的资料越来越多,比如说还有二年级、三年级、四年级等等,甚至还有我们这个通用知识库的其他资料,比如说还有员工信息等等。那我们要去向量数据库当中进行检索的话,无疑是大海捞针,它的噪音是非常大的,难以统计。 所以针对于这种基于top k的跨段落聚合检索,我给大家提供三种解决方案。那在这个企业级知识库系统当中,我除了会带着大家去实现最核心的基于RAG的问答以外,我还会带着大家去实现最佳的分块策略,包括跨向量的聚合检索,以及如果资料过期了怎么去更新,怎么在检索的时候提升召回率,怎么解决RAG问答的胡编乱造问题,怎么解决我们在进行RAG问答的时候获取资料的来源、怎么去控制访问的权限和安全。想要学习的同学可以联系我。 那第一种解决方案是知识库隔离。我们在一个大的知识库里面去找到所有姓张的人,会有很多的噪音,比如说一年级姓张的、二年级姓张的、初中姓张的,还有姓张的老师、姓张的员工可能都会被找到,有很多的噪音,犹如大海捞针。那我们为何不创建一个一个的小的知识库呢?比如说我们以文件的资料作为知识库的维度去进行创建,比如说一个知识库里面我们就放一年级的花名册,对吧?另外一个知识库里面,我们就放二年级的,以文件作为维度去创建知识库。那么这样通过缩小检索范围来实现精准聚合。其实我们可以参考Dify这种通用知识库系统,它也是这么做的,它也有一个创建知识库的功能,也就是你要用知识库,你要先创建一个用来放资料的知识库,并且这个知识库里面只能上传一个文件。文件上传完之后,在这里进行分片,我们可以看一下它的整个流程,然后进行分块,对吧?我们上一节课讲的最佳分块策略,也就是让用户去选择对应的分块策略,然后保存即可。那么这样我们就相当于创建了一个小的知识库,然后就可以在对话的时候,让用户去选择到底要用哪一个知识文件,对吧?我作为用户,我只要查一年级里面所有姓张的,那我就选择这个来进行对话嘛。那这样的话肯定就减少了噪音,检索的精度和质量也就更高了。 关键是我们在Spring AI当中、在代码当中怎么去实现?那么首先我们在UI层面,肯定也像我们刚刚看到的一样,先创建知识库,创建了知识库之后才能上传资料,并且资料只允许上传一个,对不对?完了之后,我们在这里进行对话的时候,当然我这个头像可能挡住了,比如说在RAG回答的时候,我提供一个选择,把所有的知识库列出来,让用户去选,你要对哪一个知识库进行RAG就选哪一个,并且支持多选。因为你选择了多个,那么就代表你要从多个文件里面去检索,那这个时候出现了噪音就不怪我了,这是用户自己的行为,对不对?好吧,这是我们从UI层面可以这么来做。 那在代码里面我们再来说一下应该怎么去做,其实也非常简单。我们在上传资料的时候,通过解析器来读取文件,读取成Document的时候,其实内部就有所属文件信息。你可以看到我们去到这个Milvus向量数据库里面,它有一个metadata,里面就有一个source字段,记录它来自于哪一个文件,对不对?当然如果有一些读取器,它读取成Document的时候没有这个字段,那你可以自己去设置。好吧,你可以写一个伪代码,比如说你通过for each然后一个一个的去处理Document,给它添加metadata,比如说你可以自己添加source字段,记录它来自于哪一个文件,对吧?你看我们这里截取了这个文件名,你就把这个文件名设置为source就行了。假如说读取器它没有给你设置的情况下,你就自己去设置,好吧,这是第一步。 那关键是我们保存完了之后,比如说用户他在RAG对话的时候,他选择了某一个文件来进行RAG回答,怎么做呢?我们来到RAG回答的这个请求接口,那么这个时候我们就会有一个参数来去接收我们对应的这个source,对不对?也就是这个文件它的来源是哪一个。那么我们拿到从前端传过来的这个知识库文件名之后,我们就可以直接在这里进行元数据过滤了。好吧,在这里通过filter expression去输入元数据的表达式。我们直接在这里给它过滤,匹配指定的文件名,我这里就不根据这个参数来写死检索逻辑了,你们到时候可以自己实现一下。就像我刚刚说的,在检索按钮的位置,可以给用户提供选择对应知识库的功能,然后再把选择的知识库传进来再进行检索。那么这个表达式如果你不清楚的话,它其实跟我们SQL的表达式非常的像。如果你不清楚,你可以来到Spring AI的官网,它这里其实提供了很多的示例,比如说你要查找范围,它可以通过in的方式,如果你要做相等匹配,值就用==,逻辑且也可以用&&,当然它还提供Milvus内置的表达式,这就需要你学习一些Milvus原生的表达式规则了。其实我们可以用基于Spring AI上层的这种通用的表达式,理解起来也非常的简单,我就不一一去细讲了。我们这样就相当于针对用户选择的知识库来进行过滤,也就是通过知识库隔离的方式来实现精准聚合。 那知识库隔离的这种方案,它其实并不能解决跨向量聚合的问题,它只能通过缩小检索范围来实现精准检索,减少我们刚刚说的噪音。就拿我们刚刚的那个场景来说,这个一年级的花名册里面,有十六个班级,那我们合理的按照班级来进行分片的话,就会有十六个片段,对吧?比如说我们要找到一年级里面所有姓张的同学,张姓是一个非常大的姓,基本上每一个班都会有,所以此时就会有十六个片段里面都会有姓张的同学。但是我们在代码里面设置的top k是5,所以你只能找到五个包含姓张的同学的班级,那么此时这个答案肯定是不精准的。那怎么做呢?