从文档加载到向量检索,搭建一个完整的RAG知识库问答系统
01 引子
在之前的七篇文章中,我们完成了Spring AI核心功能的闭环:多轮对话、流式输出、Function Calling、Output Parser。但有一个问题始终没解决:
大模型不知道我们私有的知识。
问它公司内部文档、项目技术方案、产品手册,它一概不知,要么说"我不知道",要么"一本正经地胡说八道"。
RAG(检索增强生成)正是为此而生。
RAG的核心思想:先检索相关资料,再基于资料回答问题。
就像人类遇到不懂的问题会先去翻资料一样,RAG让AI在回答之前先"查资料",然后基于资料生成回答。
02 RAG 完整链路概览

离线阶段(文档预处理):
- 加载文档(PDF、Word、TXT等)
- 文本分割(切成适合Embedding的小块)
- 向量化(调用Embedding模型生成向量)
- 存入向量数据库(pgvector)
在线阶段(问答检索):
- 用户提问 → 向量化
- 在向量数据库中检索相似内容
- 将检索结果 + 用户问题 一起发给大模型
- 大模型基于资料生成回答
03 代码实现
3.1 文档加载与文本分割
DocumentLoadingService.java

3.2 向量化服务(使用 DashScope 原生 SDK)
DashScopeEmbeddingService.java

3.3 向量存储与检索服务
VectorStoreService.java

3.4 Controller 接口
DocumentController.java

3.5 配置文件
application.yml

PostgreSQL 表结构(pgvector)

04 测试验证
4.1 准备测试文档
在 src/main/resources/documents/test.txt 中放入测试内容:
text
RAG(检索增强生成)是一种AI技术,它通过检索外部知识库来增强大模型的回答能力。
RAG的核心思想是:先检索相关资料,再基于资料回答问题。
RAG可以解决大模型的知识陈旧和幻觉问题。
Spring AI 提供了完整的RAG开发支持,包括文档加载、文本分割、向量存储等。
4.2 存储文档
请求:

4.3 检索文档
请求:

验证结论: ✅ 完整 RAG 链路已跑通
05 踩坑记录
坑一:spring-ai-model 与 jsonschema 依赖版本冲突
在使用 defaultTools() 注册 Tool 时,Spring AI 需要 jsonschema-generator 来生成 Tool 的 JSON Schema。如果依赖版本不一致,启动时会报 NoClassDefFoundError。
解决方案: 在 pom.xml 中统一 jsonschema-generator 和 jsonschema-module-jackson 的版本:

注意: 两个依赖的版本必须一致,否则会出现类加载冲突。
坑二:Embedding 模型维度不匹配
表定义为 1536 维,但默认的 text-embedding-v1 输出 1024 维。
解决: 使用 DashScope 原生 SDK,显式指定 text-embedding-v2 模型。
坑三:application.yml 中 embedding.model 配置不生效
Spring AI Alibaba 1.1.2.2 版本中,spring.ai.dashscope.embedding.model 配置不会被自动加载。
解决: 放弃配置方式,在代码中直接用 DashScope SDK 指定模型。
坑四:PGobject 的 setType 需要 compile scope
postgresql 依赖的 scope 若为 runtime,编译时找不到 org.postgresql.util.PGobject。
解决: 将 postgresql 的 scope 改为 compile。
06 下期预告
RAG 已经跑通了,但目前还有很多可以优化的空间:
- 检索质量优化:重排序(Rerank)、混合检索(关键词 + 向量)
- 文档处理增强:支持 PDF、Word、Excel 等多种格式
- 流式 RAG:检索 + 流式生成
- 对话式 RAG:结合多轮对话记忆
下一篇,我们探索 RAG 的进阶优化------如何让检索更精准、回答更智能。
📌 我是超超不吵吵,10年Java全栈,正在转型AI应用开发。
每周一篇实战笔记,不贩卖焦虑,只分享能落地的技术。
掘金/CSDN同名,欢迎关注。