一、RAG大模型的外置知识库1.1 场景假设你正在开发一款公司内部智能客服系统。用户问“我们公司今年新入职员工的社保缴纳流程是怎样的”你兴冲冲地调用 GPT-5 的 API结果它一本正经地回答“根据 2023 年颁布的《社会保险法》新员工入职后 30 日内用人单位需向社保经办机构办理登记……”答对了但也没完全对。因为它回答的是通用流程而你公司的内部流程是先走 OA 系统发起入职申请然后由 HR 专员在内部 HRM 系统录入再同步给第三方社保代缴机构——这个信息模型根本不知道。这暴露了大模型的一个本质问题它只见过公开的训练数据没见公司的私有文档。1.2 RAG 到底是什么RAG 的全称是 Retrieval-Augmented Generation中文叫“检索增强生成”拆开来看就很好理解检索先在你自己的知识库比如内部文档、数据库里搜一圈找到相关的信息增强把这些信息“塞”给大模型作为它回答问题的上下文生成模型基于这些真实信息生成答案用个不太严谨但很直观的类比大模型就像一个“知识储备很广但记忆力很差”的专家。训练数据是他的大学教材但你们公司内部的事教材上没写。RAG 就是先帮他翻翻公司的文件柜检索找到相关的备忘录再让他看备忘录回答问题。1.3 RAG 在大模型应用链路中的位置一个典型的 RAG 应用流程大概是这样的text1.用户提问 ↓ 2.[查询改写] ← 可选优化用户问题 ↓ 3.[向量检索] ← 去向量数据库里找最相似的文档片段切片后召回 ↓ 4.[上下文增强] ← 把检索结果和原问题拼装成 Prompt ↓ 5.[模型调用] ← 发给大模型 ↓ 6.[答案生成] ← 返回给用户RAG 占据了从用户输入到模型调用之间的“中间地带”(核心2-3-4)。它不是替代大模型而是给大模型装上一个“可实时更新的外部知识库”。1.4 RAG 解决了哪几个核心问题问题没有 RAG有 RAG知识滞后模型训练数据截止 2023 年问 2024 年的事就瞎编只要最新文档入库就能回答私有数据公司内部文档、业务数据模型一概不知把内部文档喂给 RAG模型“学会”了幻觉问题对不熟悉的问题模型会编造看似合理但错误的答案答案有检索结果作为依据大大降低幻觉成本控制把全部上下文塞进 PromptToken 消耗巨大只检索相关片段Token 量可控二、为什么选择 Spring AIJava 生态里做 RAG 的工具不少LangChain4j 也是一个优秀的选择。但我最终选择 Spring AI 作为这篇文章的主角原因很简单因为大多数 Java 后端项目本来就在用 Spring BootSpring生态的支持可以低学习成本融入项目Spring AI 的理念是“AI 领域的 Spring Data”——它不搞一套新东西而是把 AI 能力封装成 Spring 开发者熟悉的模式用Service注入ChatClient用Bean配置模型和向量库用application.yml管理配置可以把它理解成Spring 团队帮你把 OpenAI、Ollama、智谱这些模型的调用包装成了熟悉的 Bean。Vector Store向量数据库也是一样PGVector、Milvus、Elasticsearch 都有一致的使用方式。这种“一致性”对于工程落地很重要。不会因为引入了 AI 能力就让整个项目的代码风格变得面目全非。三、动手实战一个完整的 RAG 应用3.1 我们要做什么目标是构建一个“个人知识库助手”——一个简单的问答应用允许用户上传自己的文档比如公司制度、技术笔记、会议纪要然后基于这些文档进行问答。为了兼顾实用性和可跑通性技术栈如下Spring Boot 3.2Java 17Spring AI 1.0.0-M3最新里程碑版OpenAI作为大模型可用国内模型替代如智谱等PGVector作为向量数据库PostgreSQL 扩展本地开发很方便Markdown 文档作为知识源3.2 项目初始化先创建一个 Spring Boot 项目pom.xml中添加 Spring AI 的 BOM 和核心依赖xml3.3 配置文件application.yml中配置 OpenAI你需要换成自己的 API Key和 PGVectoryaml一个小提示initialize-schema: true这个配置很贴心首次启动时 Spring AI 会自动创建vector_store表不用手动写 SQL。生产环境建议关掉用 Flyway 管理。3.4 核心代码3.4.1 文档加载与向量化这是 RAG 的“入库”环节。我们提供一个接口接收 Markdown 文本分块后存入向量库。java解释一下TokenTextSplitter按 Token 数切分保证每个片段不超过 500 Token约 350~400 个汉字。200是重叠长度避免关键信息被截断在片段边界上。3.4.2 问答接口——RAG 的核心这是整个应用最核心的部分只有几行代码但已经把“检索 增强 生成”都串起来了。java来拆解一下这段代码similaritySearch(query, topK)把用户的问题向量化去 PGVector 里找余弦距离最近的前 4 个片段。这 4 个片段就是和问题最相关的知识。context拼接把检索到的片段用分隔符拼成一个字符串。这里用---隔开是为了让模型能区分不同来源。chatClient.prompt().system(...)替换 System Prompt 里的占位符。Spring AI 的ChatClient和 Spring 的RestClient设计风格很像链式调用很顺滑。.stream().content()用流式返回用户能实时看到模型一个字一个字往外蹦体验比等半天一次性返回好得多。3.4.3 一个更优雅的写法使用 Advisors上面手动拼接context的方式已经能跑通但 Spring AI 还提供了一种更“声明式”的写法——用QuestionAnswerAdvisorjavaQuestionAnswerAdvisor会在背后帮你做三件事用用户问题去检索把检索结果自动拼接到 System Prompt处理一些边界情况比如检索结果为空时的降级这也是 Spring AI 的“RAG 原生”设计——它把 RAG 这个流程做成了一个可以“插拔”的切面。3.5 一个完整的调用流程写一个简单的测试脚本看看效果bash# 先入库一份文档 curl -X POST http://localhost:8080/api/documents \ -H Content-Type: application/json \ -d { fileName: 员工手册.md, content: # 新员工社保流程\n\n新员工入职后请在 3 个工作日内完成以下操作\n1. 在 OA 系统发起入职申请\n2. HR 在 HRM 系统录入员工信息\n3. 系统自动同步给第三方代缴机构「易社保」\n\n注意每月 15 日前入职的当月开始缴纳社保。 } # 提问 curl -X POST http://localhost:8080/api/chat/ask \ -H Content-Type: application/json \ -d {question: 新员工的社保什么时候开始交}返回结果大致是根据公司规定每月 15 日前入职的员工当月开始缴纳社保。具体流程可参考 OA 系统的入职申请模块。如果问一个知识库里没有的内容比如“年假有多少天”模型会老实回答找不到相关信息。请查阅公司 HR 系统或联系人力资源部门。3.6 几个提升检索质量的最佳实践在实际项目中上面这个“Hello World”版 RAG 可能不够用。结合我踩过的坑有几点优化建议3.6.1 文档切分策略不同文档类型切分方式应该不同Markdown/技术文档按标题切分保证每个片段是语义完整的章节会议纪要按段落切分因为会议纪要的段落本身就是独立信息点代码用代码专用的分割器按函数/类切分Spring AI 提供了多种TextSplitter你也可以自己实现一个按---或#切分。3.6.2 元数据过滤检索时可以加上过滤条件比如只查某个目录下的文档java这个功能在有多租户、多知识库的场景下非常重要。3.6.3 检索结果重排序向量检索出来的 topK 结果不一定完全符合“相关性”预期。可以加一层重排序Re-ranking比如用 Cross-Encoder 模型对结果重新打分。Spring AI 目前不内置重排序但你可以自己实现一个RetrievalAugmentor。四、踩坑与避坑指南4.1 向量维数不匹配这是最常见的问题。text-embedding-3-small是 1536 维text-embedding-ada-002也是 1536 维但有些国产模型可能是 1024 维或 768 维。配置中的dimensions必须和模型输出的维度一致否则插入时报错。4.2 上下文太长导致 Token 超限如果检索出来的 4 个片段每个都有 500 Token加上 System Prompt 和用户问题轻松超过 8K 甚至 128K 模型的上限虽然上限高但费用也高。可以调小topK调小每个片段的长度在拼接到 Prompt 之前对检索结果做一次“压缩”比如提取摘要4.3 流式返回的异常处理流式接口返回FluxString如果中间模型调用失败异常不会在 HTTP 响应里体现而是让连接断开。建议用onErrorResume做兜底java五、小结RAG 的本质并不是什么高深的技术而是让大模型学会找私有数据。Spring AI 的价值在于它把这个过程封装成了 Java 开发者熟悉的方式用VectorStore管理私有数据用ChatClient和Advisor完成问答。提供快速构建一个可用的 RAG 应用的能力。当然一个生产级的 RAG 系统还有很多细节要打磨文档更新怎么办怎么做权限控制检索质量怎么评估这些是后续优化的方向但第一步——跑通一个完整的流程——我们今天已经完成了。