本文介绍了RAG(检索增强生成)技术,它通过外部知识库动态补充信息,提升大语言模型回答的准确性和时效性。文章详细讲解了使用Spring AI框架实现基于本地知识库的AI问答系统,包括环境准备、依赖引入、文档处理、向量转换存储、查询增强等关键步骤。通过具体的代码示例,展示了如何构建和测试一个能够基于特定文档回答问题的AI助手系统,有效解决了传统LLM可能产生的"幻觉"或过时回答问题。

1、RAG概念

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索与文本生成的技术,旨在提升大语言模型(LLM)生成内容的准确性和时效性。其核心思想是通过外部知识库动态补充生成所需的信息,从而弥补传统LLM仅依赖训练数据、可能产生“幻觉”或过时回答的缺陷。

简单来说,RA؜G 就像给 AI 配了一个‎知识库,让 AI 回答问题前先查一查特定的知识‍库来获取知识,确保回答是基⁠于真实资料而不是凭空想象。

通过 RAG 技术改造后,AI 就能:

  • 准确回答关于特定内容的问题。
  • 在合适的时机推荐相关课程和服务。
  • 用特定的语气和用户交流。
  • 提供更新、更准确的建议。

Spring AI 为我们实现RAG提供了全流程的支持,接下来就用 Spring AI 实现一个基于本地知识库的 AI 问答。

1、 准备环境

开发工具:IDEA

构建工具:Gradle

开发环境:JDK21(17+即可)

技术框架:SpringBoot3.3.0 + Spring AI Alibaba 1.0.0-M6.1

2、 引入Gradle依赖

这里我只引入核心依赖,其他的SpringBoot等基础依赖就不做展示了。

implementation 'com.alibaba.cloud.ai:spring-ai-alibaba-starter:1.0.0-M6.1'
implementation 'org.springframework.ai:spring-ai-markdown-document-reader:1.0.0-M6'
3、 准备知识库文档

文档可以是Text、PDF或Markdown文件等,这里我们就以Markdown文件为例。

将文档放在resources的document目录里下:

4、 文档读取

对自己准备好的知识库文档进行处理,然后保存到向量数据库中。这个过程俗称 ETL(抽取、转换、加载),Spring AI 提供了对 ETL 的支持。

ETL 的 3 大核心组件,按照顺序执行:

  • DocumentReader:读取文档,得到文档列表。
  • DocumentTransformer:转换文档,得到处理后的文档列表。
  • DocumentWriter:将文档列表保存到存储中(可以是向量数据库,也可以是其他存储)

通过 DocumentLoader 文‎档加载配置指定读取文档的细节,比如是否读取代码块、引用块等。还指定了额外的元信息配置‍,提取文档的文件名(fileName)作为文档的元信息⁠,可以便于后续知识库实现更精确的检索。

@Component
@Slf4j
public class DocumentLoader {
private final ResourcePatternResolver resourcePatternResolver;
public DocumentLoader(ResourcePatternResolver resourcePatternResolver) {
this.resourcePatternResolver = resourcePatternResolver;
}
/**
* 加载多篇Markdown文档
* @param
* @return java.util.List<org.springframework.ai.document.Document>
*/
public List<Document> loadMarkDownList() {
List<Document> documentList = new ArrayList<>();
// 加载Markdown文档列表
try {
Resource[] markDownList = resourcePatternResolver.getResources("classpath*:document/*.md");
for (Resource markDown : markDownList) {
String filename = markDown.getFilename();
// 加载markdown文档构造器
MarkdownDocumentReaderConfig documentReaderConfig = MarkdownDocumentReaderConfig.builder()
// 有分隔符就创建新文档
.withHorizontalRuleCreateDocument(true)
// 是否包含代码块
.withIncludeCodeBlock(true)
// 是否包含引用格式
.withIncludeBlockquote(true)
// 添加额外信息
.withAdditionalMetadata("filename", filename)
.build();
MarkdownDocumentReader markdownDocumentReader = new MarkdownDocumentReader(markDown, documentReaderConfig);
documentList.addAll(markdownDocumentReader.read());
}
} catch (IOException e) {
BizException.of("加载Markdown文档列表失败:", e);
}
return documentList;
}
}
5、 向量转换和存储

为了实现方便؜,我们使用 Spri‎ng AI 内置的、基于内存读写的向量数据库‍ SimpleVect⁠orStore 来保存文档。

SimpleVe؜ctorStore 实现了 Ve‎ctorStore 接口,而 VectorStore 接口集成了‍ DocumentWriter,⁠所以具备文档写入能力。

实现初始化向量数据库并且保存文档的方法。代码如下:

@Configuration
public class VectorStoreConfig {
@Resource
private DocumentLoader documentLoader;
@Bean
VectorStore vectorStore(EmbeddingModel dashscopeEmbeddingModel) {
SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(dashscopeEmbeddingModel)
.build();
// 加载文档
List<Document> documentList = documentLoader.loadMarkDownList();
simpleVectorStore.add(documentList);
return simpleVectorStore;
}
}
6、 查询增强

Spring AI 通过؜ Advisor 特性提供了开箱即用的 RAG 功‎能。主要是 QuestionAnswerAdvisor 问答拦截器和RetrievalAug‍mentationAdvisor 检索增强拦截器⁠。

查询增强的原理:向量数据库存储着 AI 模型本身不知道的数据,当用户问题‎发送给 AI 模型时,QuestionAnswerAdvisor 会查询向量数据库,获取与用户问题相关的文档‍。然后从向量数据库返回的响应会被附加到用户文本中,为 ⁠AI 模型提供上下文,帮助其生成回答。

@Slf4j
@Component
public class CodeAssistantApp {
private final ChatClient chatClient;
/**
* 系统提示词
*/
private static final String SYSTEM_PROMPT = "扮演资深的软件开发专家。开场向用户表明身份,告知用户可以提出难以解决的编程问题。\" +\n" +
"            \"引导用户详述问题需求,以便给出专属解决方案。";
/**
* 初始化ChatClient
* @param chatModel
*/
public CodeAssistantApp(ChatModel chatModel) {
ChatMemory chatMemory = new InMemoryChatMemory();
chatClient = ChatClient.builder(chatModel)
.defaultSystem(SYSTEM_PROMPT)
// 拦截器
.defaultAdvisors(
new MessageChatMemoryAdvisor(chatMemory),
// 自定义拦截器,按需开启
new CustomLoggerAdvisor()
// 自定义重读拦截器,增强推理能力,增加成本,按需开启
//new ReReadingAdvisor()
)
.build();
}
/**
* 基础对话(支持多轮对话记忆)
* @param message
* @param chatId
* @return java.lang.String
*/
public String doChat(String message, String chatId) {
ChatResponse response = chatClient
.prompt()
.user(message)
// 将当前对话的 ID(chatId)传入,AI 客户端会根据这个 ID 去查找该对话的历史记录
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
// 表示最多获取最近的 10 条历史消息作为上下文,供 AI 在生成回复时参考
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
.call()
.chatResponse();
String content = "";
if (Objects.nonNull(response)) {
content = response.getResult().getOutput().getText();
}
log.info("content: {}", content);
return content;
}
}
7、 与RAG知识库对话方法
/**
* RAG 知识库 对话
* @param message
* @param chatId
* @return java.lang.String
*/
public String doChatWithRag(String message, String chatId) {
ChatResponse chatResponse = chatClient
.prompt()
.user(message)
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
// 开启日志
.advisors(new CustomLoggerAdvisor())
// 应用知识库问答
.advisors(new QuestionAnswerAdvisor(vectorStore))
.call()
.chatResponse();
String content = chatResponse.getResult().getOutput().getText();
log.info("content: {}", content);
return content;
}
8、 单元测试

故意提问一个文档内有回答的问题。

文档部分内容:

@Test
void doChatWithRag() {
String chatId = UUID.randomUUID().toString();
String message = "进程和线程的区别";
String answer =  codeAssistantApp.doChatWithRag(message, chatId);
Assertions.assertNotNull(answer);
}

输出结果:

如何学习大模型 AI ?

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

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

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

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

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

https://img-blog.csdnimg.cn/img_convert/05840567e2912bcdcdda7b15cba33d93.jpeg

在这里插入图片描述

为什么要学习大模型?

我国在A大模型领域面临人才短缺,数量与质量均落后于发达国家。2023年,人才缺口已超百万,凸显培养不足。随着AI技术飞速发展,预计到2025年,这一缺口将急剧扩大至400万,严重制约我国AI产业的创新步伐。加强人才培养,优化教育体系,国际合作并进是破解困局、推动AI发展的关键。

在这里插入图片描述

在这里插入图片描述

大模型入门到实战全套学习大礼包

1、大模型系统化学习路线

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

img


2、大模型学习书籍&文档

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

在这里插入图片描述

3、AI大模型最新行业报告

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

img

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

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

img

5、大模型大厂面试真题

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

img

适用人群

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范
第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署
第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建
第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

https://img-blog.csdnimg.cn/img_convert/05840567e2912bcdcdda7b15cba33d93.jpeg

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐