Spring AI + RAG 从 0 到 1 落地:本地知识库 + 联网搜索,一套代码直接跑通
一、先搞懂RAG 到底是什么不用啃复杂理论一句话说清RAG 本地知识库检索 AI 生成核心流程把本地文档PDF/Word转成「向量」存到向量库比如 Redis用户提问时先把问题转成向量去向量库找最相关的内容把找到的内容 用户问题一起传给大模型大模型基于“本地知识 自身能力”生成答案优势解决大模型“知识过期”问题保证答案和你的业务文档一致不用训练大模型成本低、落地快二、环境准备Docker 装 Redis 向量库RAG 核心是向量存储我们用 Redis带 Redis Stack 插件支持向量检索Docker 一键部署1. 拉取redis-stack镜像docker pull redis/redis-stack:latest2. 启动 Redis 容器以Docker方式启动docker run -d \ --name redis-stack \ -p 9379:6379 \ -e REDIS_ARGS--requirepass 123456 \ redis/redis-stack-server:latest  ### 2. 验证安装 用 Redis CLI 连接执行 INFO modules能看到 RedisSearch 和 RedisJSON 模块说明安装成功。  三、核心实战Spring Boot 搭建 RAG 本地知识库 ------------------------------- 全程基于 Spring Boot 3.x代码可直接复制运行。 ### 1. 引入核心依赖 plaintext dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-advisors-vector-store/artifactId/dependencydependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-redis/artifactId/dependencydependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-transformers/artifactId/dependency!--解析文档--dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-tika-document-reader/artifactId/dependency2. 配置文件application.ymlspring: data: redis: host:127.0.0.1 port:8379 password:123456# Spring AI 配置ai: openai: base-url:https://api.deepseek.com api-key:sk-xxxxxxxxxxxxxxx# 替换成你的 DeepSeek Key chat: options: model:deepseek-chat # 向量配置 vectorstore: redis: initialize-schema:true # 是否初始化所需的模式 index-name:rag-knowledge # 用于存储向量的索引名称 prefix:rag:doc: # Redis 键的前缀3. 核心代码PDF 解析 文本切分 向量存储3.1 PDF 解析工具类import org.springframework.ai.document.Document;import org.springframework.ai.reader.tika.TikaDocumentReader;import org.springframework.core.io.InputStreamResource;import org.springframework.stereotype.Component;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.util.List;Componentpublicclass DocumentParserUtil { /** * 基于 Spring AI Tika 解析文档支持PDF/Word/TXT等多格式 */ public ListDocument parseDocument(MultipartFile file) throws IOException { // 将MultipartFile转为InputStreamResource适配TikaDocumentReader InputStreamResource resource new InputStreamResource(file.getInputStream()); // 创建Tika解析器自动识别文档格式并解析 TikaDocumentReader reader new TikaDocumentReader(resource); // 解析文档并返回Document列表Tika会自动按文档结构拆分基础片段 return reader.read(); }}3.2 自定义文本切分器通过换行符切分Componentpublic class CustomTextSplitter extends TextSplitter { Override protected ListString splitText(String text) { return List.of(split(text)); } public String[] split(String text) { return text.split(\\s*\\R\\s*\\R\\s*); }}3.3 文档上传 向量存储接口import cn.pottercoding.config.CustomTextSplitter;import cn.pottercoding.utils.DocumentParserUtil;import lombok.RequiredArgsConstructor;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.redis.RedisVectorStore;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import java.util.List;RestControllerRequestMapping(/rag)RequiredArgsConstructorpublicclass RagController { privatefinal DocumentParserUtil documentParserUtil; privatefinal CustomTextSplitter customTextSplitter; privatefinal RedisVectorStore redisVectorStore; /** * 上传文档PDF/Word/TXT等并存储到Redis向量库 */ PostMapping(/upload-doc) public String uploadDoc(RequestParam(file) MultipartFile file) { try { ListDocument rawDocs documentParserUtil.parseDocument(file); if (rawDocs.isEmpty()) { return文档解析失败无有效内容; } ListDocument chunks customTextSplitter.split(rawDocs); // 向量存储 redisVectorStore.add(chunks); return file.getOriginalFilename() 解析完成共生成 chunks.size() 个文本块已存入向量库; } catch (Exception e) { return上传失败 e.getMessage(); } }}4. 核心代码基于知识库的问答接口/** * 基于本地知识库问答 */ GetMapping(/qa) public FluxString ragQa(RequestParam String question) { ListDocument similarDocs redisVectorStore.similaritySearch(question); String context ; if (CollectionUtil.isNotEmpty(similarDocs)) { // 拼接检索到的上下文内容 context similarDocs.stream() .map(Document::getText) .collect(Collectors.joining(\n)); } // 构造提示词关键限定大模型仅基于本地知识回答 String prompt 请严格基于以下上下文回答问题不要使用上下文外的信息语言简洁准确 上下文%s 问题%s .formatted(context, question); // 调用DeepSeek大模型生成答案 return chatClient.prompt(prompt).stream().content(); }}5. 测试本地知识库启动项目上传 PDF 文件plaintextPOST http://localhost:8080/rag/upload-pdf参数file选一个本地PDF文件上传成功后可以在redis管理工具中看到我们存储的数据结构提问测试plaintextGET http://localhost:8080/rag/qa?questionPDF里讲了什么内容四、进阶集成 SearXNG 实现联网搜索本地知识库解决了“私有知识”问题但还有“实时信息”需求比如查最新API、最新政策我们集成 SearXNG 实现联网搜索。1. 先搞懂SearXNG 是什么有什么用1SearXNG 是什么SearXNG 是一款 开源、无广告、去中心化的元搜索引擎不是传统搜索引擎而是 “搜索引擎的聚合器”。简单说它不自己爬取数据而是同时调用 Google、Bing、百度、必应等数十个搜索引擎的接口把结果去重、排序后返回给你。2为什么用 SearXNG 而不是直接调百度 / Google API无 API_KEY 限制百度 / Google 等商用搜索 API 需要申请密钥、按调用量收费SearXNG 无需密钥去中心化避免依赖单一搜索引擎某一个源挂了不影响整体隐私保护不会把你的搜索关键词传给第三方适合企业内部使用格式统一把不同搜索引擎的返回结果标准化为 JSON开发更简单可私有化部署Docker 一键部署数据不泄露符合企业合规要求。3在 RAG 场景中SearXNG 的核心作用解决本地知识库 “知识过期” 和 “无实时信息” 的问题 本地知识库解决私有 / 历史知识问答比如公司内部文档、产品手册SearXNG 联网搜索解决实时 / 最新知识问答比如 2026 年 Spring AI 新版本、最新政策。2. Docker 安装 SearXNG先拉取searXNG镜像docker pull searxng/searxng:latest镜像拉取成功后然后启动容器启动docker命令如下docker run -p 8081:8080 \ --name searxng \ -d --restartalways \ -v /Users/luckysun/docker/SearXNG:/etc/searxng \ -e BASE_URLhttp://localhost:$PORT/ \ -e INSTANCE_NAMEpotter-instance \ searxng/searxng  访问 http://localhost:8081能看到 SearXNG 界面说明安装成功。  ### 3. OkHttp 实现联网搜索工具类 在pom.xml文件中引入okhttp工具包 plaintext !-- OkHttp 联网搜索 -- dependency groupIdcom.squareup.okhttp3/groupId artifactIdokhttp/artifactId version4.12.0/version /dependency编写联网搜索工具类import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import org.json.JSONArray;import org.json.JSONObject;import org.springframework.stereotype.Component;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit;Componentpublicclass SearchUtil { privatefinal OkHttpClient okHttpClient new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .build(); /** * 联网搜索限制返回Top5结果 */ public ListString search(String query) { ListString results new ArrayList(); // SearXNG API地址 String url http://localhost:8081/search?q query formatjsoncount5; Request request new Request.Builder() .url(url) .header(User-Agent, Mozilla/5.0) .build(); try (Response response okHttpClient.newCall(request).execute()) { if (response.isSuccessful() response.body() ! null) { String json response.body().string(); JSONObject jsonObject new JSONObject(json); JSONArray resultsArray jsonObject.getJSONArray(results); // 解析前5条结果 for (int i 0; i Math.min(resultsArray.length(), 5); i) { JSONObject result resultsArray.getJSONObject(i); String title result.getString(title); String content result.getString(content); results.add(标题 title \n内容 content); } } } catch (IOException e) { e.printStackTrace(); } return results; }}4. 集成联网搜索的问答接口import org.springframework.ai.chat.ChatClient;import org.springframework.ai.chat.prompt.Prompt;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;import java.util.stream.Collectors;RestControllerRequestMapping(/rag)RequiredArgsConstructorpublicclass RagSearchController { privatefinal SearchUtil searchUtil; privatefinal ChatClient chatClient; /** * 基于联网搜索的智能问答 */ GetMapping(/qa-search) public String ragSearchQa(RequestParam String question) { // 1. 联网搜索取Top5结果 ListString searchResults searchUtil.search(question); if (searchResults.isEmpty()) { return未检索到相关信息; } // 2. 拼接搜索结果 String searchContext searchResults.stream() .collect(Collectors.joining(\n\n)); // 3. 构造提示词 String prompt 请基于以下实时搜索结果回答问题语言简洁、准确 搜索结果%s 问题%s .formatted(searchContext, question); // 4. 调用大模型 return chatClient.prompt(new Prompt(prompt)).call().content(); }}5. 测试联网搜索GET http://localhost:8080/rag/qa-search?question2026年SpringAI最新版本是什么此时返回的答案会基于实时联网结果解决了大模型“知识过期”问题写在最后LLM Agent 的诞生为我们提供了一个极具想象空间的技术路线它将传统模型的强大语言理解能力与外部工具的实际动手能力相结合创造出无限可能的应用空间。希望这篇文章能够启发你进一步探索和创新用有限的代码创造出更加强大、高效且安全的智能体推动人工智能真正落地到更多场景惠及更多人群。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】