SpringAi-RAG知识库【来源追溯】实现完整方案+代码

当RAG对话时, 用户想知道信息来源哪个文件, 这样可信度更高, 可以确定不是大模型胡编乱造,我们就需要告诉用户信息的来源:

实现步骤:

第一步:给片段加入文件信息

在文档切片入库时,千万别只存文本。一定要利用向量数据库的 <font style="color:rgb(0, 0, 0);">Metadata</font> 字段,把文件名(source)“焊死”在每一个切片上。

**✅******实际在我们利用TikaDocumentReader 进行读取文档的时候, 就会自动写入文件名(source)到Metadata

TikaDocumentReader reader = new TikaDocumentReader(resource);List<Document> documents = reader.read();

及时你用别的XXXReader没有写入文件名, 你也可以自己维护

documents.forEach(document -> {document.getMetadata().put("source",originalFilename)});

第二步:检索时的“显性组装”

LLM 是“盲”的,它看不到 Metadata。所以检索回来后,我们需要用 Java 代码把 Metadata 里的文件名取出来,拼接到文本内容的前面。

**✅**** **这里我建议采用advisor的方式实现, 更加优雅:

  1. 定义advisor
public class MetadataAwareQuestionAnswerAdvisor implements BaseAdvisor {    privatestaticfinal PromptTemplate DEFAULT_PROMPT_TEMPLATE = new PromptTemplate("""   {query}   Context information is below, surrounded by ---------------------   ---------------------   {question_answer_context}   ---------------------   Given the context and provided history information and not prior knowledge,   reply to the user comment. If the answer is not in the context, inform   the user that you can't answer the question.   """);    @Override    public ChatClientRequest before(ChatClientRequest baseRequest, AdvisorChain advisorChain) {        // 获取检索到的文档          List<Document> documents = (List<Document>) baseRequest.context().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS);        String userMessage = (String) baseRequest.context().get("userMessage");        if(!CollectionUtils.isEmpty(documents)) {            String documentContext = documents == null ? ""                    : documents.stream().map(doc -> doc.getText()+"\n来源文件:"+doc.getMetadata().getOrDefault("source", "unknown").toString()).collect(Collectors.joining(System.lineSeparator()));            // 重新构建prompt,在末尾添加source信息            String augmentedUserText = DEFAULT_PROMPT_TEMPLATE                    .render(Map.of("query", userMessage, "question_answer_context", documentContext));            return baseRequest.mutate()                    .prompt(baseRequest.prompt().augmentUserMessage(augmentedUserText))                    .build();        }        else {            return baseRequest;        }    }    @Override    public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {        return chatClientResponse;    }    @Override    public int getOrder() {        // 优先级最低、因为要保证负责RAG的questionAnswerAdvisor执行完.才能拿到文档信息        // 为什么不直接设置MAX_VALUE, 因为ChatModelCallAdvisor(负责实际调用AI模型的advisor)也使用了Integer.MAX_VALUE,  如果在他之后,AI对话完成不会执行        return Integer.MAX_VALUE-1;    }}

2.使用:

this.chatClient = ChatClient.builder(chatModel)                // 隐式                .defaultSystem("""                        你是"XS"知识库系统的对话助手,请以乐于助人的方式进行对话,                        如果涉及RAG,请提供文件来源,我会通过source提供给你文件来源,                        今天的日期:{current_data}                        """)                .defaultAdvisors(                        PromptChatMemoryAdvisor.builder(chatMemory).build(),                        SimpleLoggerAdvisor.builder().build(),                        new MetadataAwareQuestionAnswerAdvisor()                )                .defaultTools(ragTool)                .build();        this.vectorStore=vectorStore;    }
``````plaintext
private Flux<String> processNormalRagQuery(List<String> sources, String message) {        Long userId = BaseContext.getCurrentId();        ChatClient.ChatClientRequestSpec clientRequestSpec = chatClient.prompt()                .user(message)                .advisors(a -> a.param("current_data", LocalDate.now().toString()))                // 为什么要存userMessage  为了MetadataAwareQuestionAnswerAdvisor中获取                .advisors(a -> a.param("userMessage", message))                .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, userId));        // 如果提供了sources参数,使用向量数据库查询        if (sources != null && !sources.isEmpty()) {            SearchRequest.Builder searchRequestBuilder = SearchRequest.builder()                    .query(message)                    .similarityThreshold(0.2d).topK(5)                    // source in ['xxx.pdf','xxxx']                    .filterExpression("source in "+JSON.toJSONString(sources));            clientRequestSpec=clientRequestSpec.advisors(QuestionAnswerAdvisor.builder(vectorStore)                    .searchRequest(searchRequestBuilder.build())                    .build());        }        Flux<String> content = clientRequestSpec                .stream()// 流式方式                .content();        return  content;    }

第三步:引导大模型提供文件来源

最后,在 System Prompt 中给大模型下达“死命令”,如果不设置大模型可能不会告诉用户。

this.chatClient = ChatClient.builder(chatModel)                // 隐式                .defaultSystem("""                        你是"XS"知识库系统的对话助手,请以乐于助人的方式进行对话,                        如果涉及RAG,请提供文件来源,我会通过source提供给你文件来源,                        今天的日期:{current_data}                        """)                .defaultAdvisors(                        PromptChatMemoryAdvisor.builder(chatMemory).build(),                        SimpleLoggerAdvisor.builder().build(),                        new MetadataAwareQuestionAnswerAdvisor()                )                .defaultTools(ragTool)                .build();

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套 AI 大模型突围资料包

  • ✅ 从零到一的 AI 学习路径图
  • ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
  • ✅ 百度/阿里专家闭门录播课
  • ✅ 大模型当下最新行业报告
  • ✅ 真实大厂面试真题
  • ✅ 2025 最新岗位需求图谱

所有资料 ⚡️ ,朋友们如果有需要 《AI大模型入门+进阶学习资源包》下方扫码获取~
在这里插入图片描述

① 全套AI大模型应用开发视频教程

(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
在这里插入图片描述

② 大模型系统化学习路线

作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
在这里插入图片描述

③ 大模型学习书籍&文档

学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
在这里插入图片描述

④ AI大模型最新行业报告

2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
在这里插入图片描述

⑤ 大模型项目实战&配套源码

学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
在这里插入图片描述

⑥ 大模型大厂面试真题

面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余

图片

以上资料如何领取?

在这里插入图片描述

为什么大家都在学大模型?

最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!

图片

不出1年,“有AI项目经验”将成为投递简历的门槛。

风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!
在这里插入图片描述
在这里插入图片描述

这些资料真的有用吗?

这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。
在这里插入图片描述
在这里插入图片描述

以上全套大模型资料如何领取?

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值