
“RAG 检索增强生成让大模型告别幻觉精准回答你的文档内容 什么是 RAG简单来说RAG 是一种在发送给大模型LLM之前从你的数据中找到并注入相关信息片段到提示中的方法。这样 LLM 将获得相关信息并能够使用这些信息回复——这应该会降低产生幻觉的概率。相关信息片段可以使用各种信息检索方法找到最流行的方法有三种1️⃣ 全文关键词搜索使用 TF-IDF 和 BM25 等技术通过匹配查询中的关键词与文档数据库进行搜索。 根据每个文档中这些关键词的频率和相关性对结果进行排名。2️⃣ 向量搜索语义搜索文本文档使用嵌入模型转换为数字向量。 然后根据查询向量和文档向量之间的余弦相似度或其他相似度度量找到并排序文档从而捕捉更深层次的语义含义。3️⃣ 混合搜索结合多种搜索方法例如全文 向量通常可以提高搜索的有效性。 RAG 的两个核心阶段RAG 过程分为两个不同的阶段索引和检索。 LangChain4j 为这两个阶段提供了完整的工具支持。 阶段一索引Indexing在索引阶段文档会被预处理以便在检索阶段进行高效搜索。对于向量搜索这通常涉及清理文档用额外数据和元数据丰富文档将文档分割成更小的片段也称为分块嵌入这些片段最后将它们存储在嵌入存储向量数据库中“提示索引阶段通常是离线进行的最终用户不需要等待其完成。 例如可以通过定时任务在周末每周重新索引一次公司内部文档。但在某些情况下最终用户可能希望上传自己的自定义文档使 LLM 能够访问这些文档。 在这种情况下索引应该在线进行并成为主应用程序的一部分。索引阶段流程图 阶段二检索Retrieval检索阶段通常在线进行当用户提交一个应该使用索引文档回答的问题时。对于向量搜索这通常涉及嵌入用户的查询问题在嵌入存储中执行相似度搜索将相关片段原始文档的片段注入到提示中发送给 LLM 生成回答检索阶段流程图 RAG 实战案例Java 8 文档问答 步骤一准备资料首先准备一份 PDF 文档作为知识来源——《Java 8 从入门到精通》。我们的目标是投喂这个 PDF让大模型回答文档中的问题。️ 步骤二创建项目结构创建标准的 Spring Boot 项目结构pom.xml 依赖配置核心依赖包括Spring Boot WebLangChain4j 核心库阿里百炼平台DashScope集成Qdrant 向量数据库Easy RAG 模式AllMiniLmL6V2 本地嵌入模型?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdcom.whc/groupId artifactIdlangChain4j-whc/artifactId version1.0-SNAPSHOT/version /parent artifactIdlangchain4j-whc-rag/artifactId properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- LangChain4j 核心 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-reactor/artifactId /dependency !-- 阿里百炼平台 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-community-dashscope-spring-boot-starter/artifactId /dependency !-- 工具库 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-boot-starter/artifactId /dependency !-- Qdrant 向量数据库 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-qdrant/artifactId version1.5.0-beta11/version /dependency !-- Easy RAG 模式 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-easy-rag/artifactId /dependency !-- AllMiniLmL6V2 本地嵌入模型 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-embeddings-all-minilm-l6-v2/artifactId version1.5.0-beta11/version /dependency /dependencies/project“注意将 PDF 文件放到resources/doc目录下。⚙️ 步骤三YAML 配置配置服务端口、DashScope API 和 Qdrant 连接信息server: port: 9009 servlet: encoding: enabled: true force: true charset: UTF-8spring: application: name: langchain_whc_ragai: dashScope: apiKey: ${AI_DASHSCOPE_API_KEY} modelName: ${AI_DASHSCOPE_MODEL_NAME} baseUrl: ${AI_DASHSCOPE_BASE_URL}qdrant: host: ${QDRANT_HOST} port: ${QDRANT_PORT} collectionName: ${QDRANT_COLLECTION_NAME} 步骤四大模型配置类这是最核心的配置部分需要配置三个关键 Bean向量存储实例Qdrant嵌入模型实例本地 AllMiniLmL6V2聊天模型实例DashScope内容检索器实例重点Slf4jGetterConfigurationpublic class LlmConfig { Value(${ai.dashScope.apiKey}) private String dashScopeApiKey; Value(${ai.dashScope.modelName}) private String dashScopeModelName; Value(${ai.dashScope.baseUrl}) private String dashScopeBaseUrl; Value(${qdrant.host}) private String qdrantHost; Value(${qdrant.port}) private int qdrantPort; Value(${qdrant.collectionName}) private String qdrantCollectionName; /** * 创建向量存储实例 * 使用 Qdrant 作为向量数据库 */ Bean public EmbeddingStoreTextSegment embeddingStore() { return QdrantEmbeddingStore.builder() .host(qdrantHost) .port(qdrantPort) .collectionName(qdrantCollectionName) .build(); } /** * 创建嵌入模型实例 * 使用本地的 AllMiniLmL6V2 嵌入模型避免 DashScope 兼容性问题 */ Bean public EmbeddingModel embeddingModel() { return new dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel(); } /** * 创建聊天模型实例 * 使用 OpenAI 兼容的聊天模型通过 DashScope 提供的 API 服务进行对话 */ Bean public ChatModel chatModel() { return OpenAiChatModel.builder() .apiKey(dashScopeApiKey) .modelName(dashScopeModelName) .baseUrl(dashScopeBaseUrl) .logRequests(true) .build(); } /** * 创建内容检索器实例 * ⚠️ 重点必须明确指定嵌入模型避免冲突 */ Bean public ContentRetriever contentRetriever(EmbeddingStoreTextSegment embeddingStore, EmbeddingModel embeddingModel) { return EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .build(); }} 步骤五定义 AI 服务接口使用AiService注解显式指定要使用的模型和检索器AiService(wiringMode AiServiceWiringMode.EXPLICIT, chatModel chatModel, contentRetriever contentRetriever)public interface RagAssist { /** * 聊天接口 * param message 用户问题 * return AI 回答 */ String chat(String message);} 步骤六Controller 实现实现 REST API完成文档解析、嵌入存储和问答的完整流程RestControllerRequiredArgsConstructorpublic class RagController { private final EmbeddingModel embeddingModel; private final EmbeddingStoreTextSegment embeddingStore; private final RagAssist ragAssist; GetMapping(value /rag/chat) public String java8(RequestParam String message) throws IOException { // 1. 读取并解析 PDF 文档 ClassPathResource resource new ClassPathResource(doc/java8从入门到精通.pdf); InputStream inputStream resource.getInputStream(); Document document new ApacheTikaDocumentParser().parse(inputStream); // 2. 创建文档嵌入存储处理器 EmbeddingStoreIngestor ingestor EmbeddingStoreIngestor.builder() .documentSplitter(DocumentSplitters.recursive(1000, 0)) .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .build(); // 3. 将文档处理并存储到向量数据库 ingestor.ingest(document); // 4. 使用 RAG 助手回答问题 String result ragAssist.chat(message); System.out.println(result); return result; }}✅ 测试效果验证测试一询问第九章内容文档第九章是关于「本地时间和时间戳」的内容接口调用GET http://localhost:9009/rag/chat?message第九章主要讲了啥  **AI 回答** “ 第九章主要讲述了本地时间和时间戳的相关概念。内容包括如何在程序中处理不同地区的本地时间时区的转换以及时间戳Timestamp的定义和使用方法。本章还介绍了如何将时间戳与本地时间进行相互转换帮助开发者更好地理解和操作时间数据确保在跨时区应用中的时间一致性与准确性。 **完美达到预期效果** --- ### 测试二询问 Stream 创建方法 **接口调用** plaintext GET http://localhost:9009/rag/chat?message如何创建Stream  **调用结果**  很显然AI 回答参考了文档中的内容并明确说明了对应的章节来源。 ✅ **再次验证成功** --- ### 向量数据库存储效果 文档被分割成了一个又一个的 text_segment 存储在 Qdrant 中  --- ⚠️ 踩坑记录与解决方案 ------------ ### 坑一多个嵌入模型冲突 **问题**配置内容检索器时如果不明确指定 model会报错 plaintext Conflict: multiple embedding models have been found in the classpath解决方案在EmbeddingStoreContentRetriever中必须显式指定要使用的嵌入模型Beanpublic ContentRetriever contentRetriever(EmbeddingStoreTextSegment embeddingStore, EmbeddingModel embeddingModel) { return EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) // ✅ 关键明确指定模型 .build();}坑二DashScope 兼容性问题**问题**尝试使用百炼平台的向量模型TEXT-EMBEDDING-V4时报 OpenAI 不兼容异常。**解决方案**改用本地的AllMiniLmL6V2EmbeddingModel嵌入模型完美避开兼容性问题Beanpublic EmbeddingModel embeddingModel() { // ✅ 使用本地嵌入模型避免兼容性问题 return new dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel();}学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%免费】