保姆级RAG实战教程!从0到1让AI“吃透”你的文档,看这篇就够了!

开发过程中遇见不会的怎么办?

👉『开发喵AI』👈

已集成 GPT-5、Claude3.7、Gemini 御三家

致力于解决用户魔法上网、答案高要求、内容高标准

已内置 100余种命令与角色

解决问题的方式有很多种,请试试开发喵AI给你的答案🙇🙇‍♀️

🎯 目标:构建一个真正可用、具备上下文感知能力的知识库问答系统,让大模型基于你提供的私有文档生成准确、可靠的回答。

本章核心——RAG(Retrieval-Augmented Generation,检索增强生成) 的基石。

通用大模型虽然强大,但其知识是“静态”且“通用”的。它无法回答诸如“我们公司2025年差旅报销标准是多少?”这类依赖私有、动态知识的问题。而 RAG 正是解决这一痛点的关键技术。

通过本章,你将掌握如何将文档知识注入大模型的推理过程,构建一个真正可用的企业级智能问答系统

8.1 RAG 原理详解:检索 + 增强 + 生成

RAG 的核心思想是:将大模型的生成能力与外部知识库的检索能力相结合,形成“先查资料,再作答”的智能行为。

整个流程分为三步:

8.1.1 检索(Retrieval)

当用户提出问题时,系统使用上一章学习的 Embedding 模型 将问题转化为向量,然后在 VectorStore 中进行相似度搜索,找出与问题最相关的文档片段。

8.1.2 增强(Augmentation

将检索到的相关文档内容(原文)作为上下文,拼接到 Prompt 中,形成一个“增强版”的输入。这相当于告诉模型:“请参考以下信息来回答问题。”

8.1.3 生成(Generation

大模型基于增强后的 Prompt(包含问题 + 上下文)生成最终回答。由于模型有了明确的信息依据,生成的答案更准确、更可信,大幅降低“幻觉”风险。

✅ RAG 的本质:
它不是让模型“记住”所有知识,而是让它“会查资料”。这正是人类专家的工作方式。

8.2 ETL 管道(Pipeline):数据处理的核心流程

从文档到向量数据库是RAG的前置条件,而文档到数据库有几个步骤非常重要:

  1. 文档读取:文档可能包括pdf、Excel、图片等等各种各样的内容,而这些内容中包括很多不同的格式,比如pdf中可能还包括表格和图片,因此选择哪些文档读取的工具非常重要
  2. 文档分块:由于大模型有token长度限制同时过长的token其实对于大模型的理解和推理会变慢或者不准确,因此需要将文档分块。对于如何分块,如何不会将原本有关联的语句分隔开也是文档向量化的重要步骤。
  3. 文档embedding:对于不同语言,不同的embedding模型有着不同效果.根据实际使用场景,选择适合自己的embedding模型
  4. 终的结果。

那么在这一套流程中,Spring AI称为ETL(Extract-Transform-Load) Pipeline,流程如下图(官方提供):

ETL 管道协调了从原始数据源到结构化向量存储的完整流程,确保数据最终转换为 AI 模型检索所需的最优格式。其三大核心阶段为:

  1. 提取(Extract):从 PDF、TXT、Word、HTML 等多种源中读取原始内容。
  2. 转换(Transform):对提取的文本进行清洗、分割、元数据增强等操作。
  3. 加载(Load):将处理后的文档写入向量数据库(VectorStore)或其他存储。

Spring AI 为 ETL 流程定义了三个核心接口,体现了清晰的职责分离:

接口功能对应阶段
DocumentReader实现 Supplier<List<Document>> ,负责从数据源读取内容并构建 Document对象。Extract
DocumentTransformer实现 Function<List<Document>, List<Document>> ,负责对文档进行转换处理(如分割、增强)。Transform
DocumentWriter实现 Consumer<List<Document>> ,负责将最终文档写入目标存储(如 VectorStore)。Load

下面是三个接口的定义:

public interface DocumentReader extends Supplier<List<Document>> {    default List<Document> read() {        return (List)this.get();    }}public interface DocumentTransformer extends Function<List<Document>, List<Document>> {    default List<Document> transform(List<Document> transform) {        return (List)this.apply(transform);    }}public interface DocumentWriter extends Consumer<List<Document>> {    default void write(List<Document> documents) {        this.accept(documents);    }}

关于Document,在上一章中已经学习过了。

8.3 Document Reader接口

Spring AI,也集成了很多不同文档解析工具,以下是已经支持的文档读取器:

DocumentReaders描述需要引入依赖
JsonReader用于读取Json格式的数据,并将其转换为一系列Document对象。内置
TextReader处理纯文本文档,并将其转换为一系列Document对象。内置
JsoupDocumentReader用于处理 HTML 文档,并利用 JSoup 库将这些文档转换为一系列的 Document 对象。spring-ai-jsoup-document-reader
MarkdownDocumentReader会处理 Markdown格式文档,并将其转换为一系列的 Document 对象。spring-ai-markdown-document-reader
PagePdfDocumentReader使用 Apache PdfBox 库来解析 PDF 文档。spring-ai-pdf-document-reader
ParagraphPdfDocumentReader同样也是基于 Apache PdfBox 库,但是不同的是ParagraphPdfDocumentReader 会利用 PDF 目录(例如目录)中的信息将输入的 PDF 文件拆分成文本段落,并为每个段落生成一个单独的文档(注意:并非所有 PDF 文件都包含 PDF 目录)。spring-ai-pdf-document-reader
TikaDocumentReader通过使用 Apache Tika 技术从各种文档格式(如 PDF、DOC/DOCX、PPT/PPTX 和 HTML)中提取文本。spring-ai-tika-document-reader

8.4 DocumentTransformer接口

DocumentTransformer 可以对一批文档进行转换处理,它是一个接口,主要实现其transform方法,将一组Document转换为另外一组Document。其实现类有:

  • TextSplitter:是一个抽象基类,它有助于将文档进行分割,以适应人工智能模型的上下文窗口。
  • TokenTextSplitter:是“TextSplitter”的一种实现方式,它根据词的数量将文本分割成多个部分,并使用“CL100K_BASE”编码进行处理。
  • ContentFormatTransformer:可以将文档中的元数据内容变成键值对字符串,从而确保所有文档中的内容格式保持统一。
  • KeywordMetadataEnricher:它调用大模型从文档内容中提取关键词,并向Metadata中添加一个keywords字段,该字段包含了文档的关键词信息。
  • SummaryMetadataEnricher:它调用大模型为文档生成摘要,并将其作为Metadata添加到文档中。它能够为当前文档生成摘要,也能为相邻文档(即前文和后文的文档)生成摘要。

8.5 DocumentWriter接口

DocumentWriter Spring的Writers支持Flie以及向量数据库。其实现有:

可以看到 VectorStore实际上是 DocumentWriter的子接口。

8.6 实战:对PDF文件进行ETL处理

首先找一个样例 pdf文件,chapter08/src/main/resources/Embedding-Models.pdf

  1. 引入依赖
chapter08/pom.xml<dependency>    <groupId>org.springframework.ai</groupId>    <artifactId>spring-ai-pdf-document-reader</artifactId></dependency>
  1. 配置 Milvus VectorStore
// chapter08/src/main/java/com/kaifamiao/chapter08/configuration/VectorStoreConfig.java@Configurationpublic class VectorStoreConfig {    @Bean    public VectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingModel embeddingModel) {        return MilvusVectorStore.builder(milvusClient, embeddingModel)                .collectionName("default")                .databaseName("default")                .indexType(IndexType.IVF_FLAT)                .metricType(MetricType.COSINE)                .initializeSchema(true)                .build();    }    @Bean    public MilvusServiceClient milvusClient() {        return new MilvusServiceClient(ConnectParam.newBuilder()                .withHost("192.168.31.254")                .withPort(19530)                .build());    }}
  1. 编写一个Service类,这个类中一次完成 pdf文件读取, 文本分割,最后保存到 Milvus 向量数据库中。
//chapter08/src/main/java/com/kaifamiao/chapter08/service/PDFEmbeddingService.java@Service@Slf4jpublic class PDFEmbeddingService {    private final VectorStore vectorStore;    public PDFEmbeddingService(VectorStore vectorStore) {        this.vectorStore = vectorStore;    }    public void processPDFAndStoreToMilvus(Resource pdfResource) {        try {            // 1. 读取PDF文档            PdfDocumentReaderConfig config = PdfDocumentReaderConfig.builder()                    .withPageExtractedTextFormatter(ExtractedTextFormatter.builder().withNumberOfTopTextLinesToDelete(0)                            .build())                    .withPagesPerDocument(1)//如果设置为0,则表示所有页都变成一个文档                    .build();            PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(                    pdfResource, config);            List<Document> documents = pdfReader.get();            // 处理文档内容中的非UTF-8字符            List<Document> cleanedDocuments = documents.stream()                    .map(this::cleanNonUTF8Characters)                    .collect(Collectors.toList());            // 2. 文本分割            TextSplitter   textSplitter   = new TokenTextSplitter();            List<Document> splitDocuments = textSplitter.apply(cleanedDocuments);//            for(Document doc:splitDocuments){//                log.info("media:{}, metadata:{}  content:{}",doc.getMedia(),doc.getMetadata().keySet(),doc.getText());//            }            // 分批处理,每批不超过10个文档,避免超出嵌入模型的批量大小限制            int batchSize = 10;            for (int i = 0; i < splitDocuments.size(); i += batchSize) {                int endIndex = Math.min(i + batchSize, splitDocuments.size());                List<Document> batch = splitDocuments.subList(i, endIndex);                // 3. 存储到Milvus向量数据库(分批处理)                vectorStore.add(batch);                log.info("Processed batch {} to {}", i / batchSize + 1, (endIndex - 1) / batchSize + 1);            }        } catch (Exception e) {            throw new RuntimeException("Failed to process PDF and store to Milvus", e);        }    }    // 修改清理非UTF-8字符的方法以适应新的API    private Document cleanNonUTF8Characters(Document document) {        String text = document.getText();        // 清理非UTF-8字符        String cleanedText = text.replaceAll("[^\\p{Print}\\s]", "?");        // 创建新的Document对象        return new Document(cleanedText, document.getMetadata());    }}
  1. 测试用例
//chapter08/src/test/java/com/kaifamiao/chapter08/PDFEmbeddingServiceTest.java@SpringBootTest@Slf4jpublic class PDFEmbeddingServiceTest {    @Autowired    private PDFEmbeddingService pdfEmbeddingService;    @Test    public void testProcessPDFAndStoreToMilvus() {        Resource resource = new ClassPathResource("Embedding-Models.pdf");        pdfEmbeddingService.processPDFAndStoreToMilvus(resource);    }}

8.7 Advisor 机制与 QuestionAnswerAdvisor

在 Spring AI 中,Advisor 是一种强大的拦截器机制,用于在请求发送给 AI 模型之前或之后修改请求或响应。它在 RAG 场景中扮演着核心角色。

Advisor 允许你在不修改核心业务逻辑的情况下,动态地:

  • • 修改 Prompt
  • • 注入上下文
  • • 记录日志
  • • 添加安全检查
  • • 处理异常

QuestionAnswerAdvisor 是 Spring AI 提供的专门用于 RAG 的 Advisor。它自动完成了“检索 + 增强”的过程。使用它,必须要引入依赖:

<!-- chapter08/pom.xml --><!-- 引入向量数据库插件 --><dependency>    <groupId>org.springframework.ai</groupId>    <artifactId>spring-ai-advisors-vector-store</artifactId></dependency>

QuestionAnswerAdvisor类实现了BaseAdvisor接口,该BaseAdvisor接口主要有2个方法before和after,这个两个方法分别是调用Advisor的核心方法之前和之后执行的方法

// QuestionAnswerAdvisor 类部分源码@Override    public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {        // 1. Search for similar documents in the vector store.        // 组装查询条件,并从向量数据库查询文档        var searchRequestToUse = SearchRequest.from(this.searchRequest)            .query(chatClientRequest.prompt().getUserMessage().getText())            .filterExpression(doGetFilterExpression(chatClientRequest.context()))            .build();        List<Document> documents = this.vectorStore.similaritySearch(searchRequestToUse);        // 2. Create the context from the documents.        // 将文档作为上下文,传递到其它 advisor或者after 方法中使用        Map<String, Object> context = new HashMap<>(chatClientRequest.context());        context.put(RETRIEVED_DOCUMENTS, documents);        String documentContext = documents == null ? ""                : documents.stream().map(Document::getText).collect(Collectors.joining(System.lineSeparator()));        // 3. Augment the user prompt with the document context.        // 将文档使用promptTemplate组装为提示语        UserMessage userMessage = chatClientRequest.prompt().getUserMessage();        String augmentedUserText = this.promptTemplate            .render(Map.of("query", userMessage.getText(), "question_answer_context", documentContext));        // 4. Update ChatClientRequest with augmented prompt.        // 访问大模型        return chatClientRequest.mutate()            .prompt(chatClientRequest.prompt().augmentUserMessage(augmentedUserText))            .context(context)            .build();    }

8.7.1 QuestionAnswerAdvisor工作原理

  1. 拦截用户的提问。
  2. 使用配置的 RetrieverVectorStore 中检索相关文档。
  3. 将检索到的文档内容作为上下文,注入到原始 Prompt 中。
    1. 将增强后的 Prompt 发送给大模型。
  4. 返回生成的答案。

8.7.2 SearchRequest是一个封装的查询

public class SearchRequest {    /**     * Similarity threshold that accepts all search scores. A threshold value of 0.0 means     * any similarity is accepted or disable the similarity threshold filtering. A     * threshold value of 1.0 means an exact match is required.     */    public static final double SIMILARITY_THRESHOLD_ACCEPT_ALL = 0.0;    /**     * Default value for the top 'k' similar results to return.     */    public static final int DEFAULT_TOP_K = 4;    /**     * Default value is empty string.     */    private String query = "";    private int topK = DEFAULT_TOP_K;    private double similarityThreshold = SIMILARITY_THRESHOLD_ACCEPT_ALL;    @Nullable    private Filter.Expression filterExpression;...}
  1. query:查询的问题
  2. topK:返回前几个文档
  3. similarityThreshold:相似度,大于等于这个值之上的相似度才会匹配
  4. filterExpression:元数据的过滤条件,主要是过滤Document的metadata元数据属性

8.7.3 实战RAG

只需要为 ChatClient配置一个 QuestionAnswerAdvisor即可,而构建 QuestionAnswerAdvisor的时候,是需要和 VectorStore绑定的。

// chapter08/src/main/java/com/kaifamiao/chapter08/controller/RAGController.java@RestControllerpublic class RAGController {    private final ChatClient chatClient;    @Autowired    public RAGController(ChatClient.Builder chatClientBuilder,                         VectorStore vectorStore) {        //通过Advisors方式,对向量数据库进行封装        Advisor questionAdvisor =QuestionAnswerAdvisor                .builder(vectorStore)                .build();        this.chatClient = chatClientBuilder                .defaultAdvisors(questionAdvisor)                .build();    }    @GetMapping(value="/chat/rag"            , produces = "text/html;charset=UTF-8"    )    public String generate(@RequestParam(value = "question") String question) {        return this.chatClient.prompt()                .user(question)                .call()                .content();    }}

这样,当用户提问的时候,就会首先到 向量数据库中对问题进行相似度搜索,然后将搜索到的相关提示词再组装后发送给大模型,最终大模型生成答案。

上面只是简单使用了QuestionAnswerAdvisor实际上,还可以对 QuestionAnswerAdvisor进行更详细的配置,比如:

如何学习大模型 AI ?

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

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

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

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

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

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

在这里插入图片描述

2025最新大模型学习路线

明确的学习路线至关重要。它能指引新人起点、规划学习顺序、明确核心知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

对于从来没有接触过AI大模型的同学,我帮大家准备了从零基础到精通学习成长路线图以及学习规划。可以说是最科学最系统的学习路线。

在这里插入图片描述

针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

大模型经典PDF书籍

新手必备的大模型学习PDF书单来了!全是硬核知识,帮你少走弯路!

在这里插入图片描述

配套大模型项目实战

所有视频教程所涉及的实战项目和项目源码等
在这里插入图片描述

博主介绍+AI项目案例集锦

MoPaaS专注于Al技术能力建设与应用场景开发,与智学优课联合孵化,培养适合未来发展需求的技术性人才和应用型领袖。

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

为什么要学习大模型?

2025人工智能大模型的技术岗位与能力培养随着人工智能技术的迅速发展和应用 , 大模型作为其中的重要组成部分 , 正逐渐成为推动人工智能发展的重要引擎 。大模型以其强大的数据处理和模式识别能力, 广泛应用于自然语言处理 、计算机视觉 、 智能推荐等领域 ,为各行各业带来了革命性的改变和机遇 。

在这里插入图片描述

适合人群

  • 在校学生:包括专科、本科、硕士和博士研究生。学生应具备扎实的编程基础和一定的数学基础,有志于深入AGI大模型行业,希望开展相关的研究和开发工作。
  • IT行业从业人员:包括在职或失业者,涵盖开发、测试、运维、产品经理等职务。拥有一定的IT从业经验,至少1年以上的编程工作经验,对大模型技术感兴趣或有业务需求,希望通过课程提升自身在IT领域的竞争力。
  • IT管理及技术研究领域人员:包括技术经理、技术负责人、CTO、架构师、研究员等角色。这些人员需要跟随技术发展趋势,主导技术创新,推动大模型技术在企业业务中的应用与改造。
  • 传统AI从业人员:包括算法工程师、机器视觉工程师、深度学习工程师等。这些AI技术人才原先从事机器视觉、自然语言处理、推荐系统等领域工作,现需要快速补充大模型技术能力,获得大模型训练微调的实操技能,以适应新的技术发展趋势。
    在这里插入图片描述

课程精彩瞬间

大模型核心原理与Prompt:掌握大语言模型的核心知识,了解行业应用与趋势;熟练Python编程,提升提示工程技能,为Al应用开发打下坚实基础。

在这里插入图片描述

RAG应用开发工程:掌握RAG应用开发全流程,理解前沿技术,提升商业化分析与优化能力,通过实战项目加深理解与应用。 在这里插入图片描述

Agent应用架构进阶实践:掌握大模型Agent技术的核心原理与实践应用,能够独立完成Agent系统的设计与开发,提升多智能体协同与复杂任务处理的能力,为AI产品的创新与优化提供有力支持。
在这里插入图片描述

模型微调与私有化大模型:掌握大模型微调与私有化部署技能,提升模型优化与部署能力,为大模型项目落地打下坚实基础。 在这里插入图片描述

顶尖师资,深耕AI大模型前沿技术

实战专家亲授,让你少走弯路
在这里插入图片描述

一对一学习规划,职业生涯指导

  • 真实商业项目实训
  • 大厂绿色直通车

人才库优秀学员参与真实商业项目实训

以商业交付标准作为学习标准,具备真实大模型项目实践操作经验可写入简历,支持项目背调

在这里插入图片描述
大厂绿色直通车,冲击行业高薪岗位
在这里插入图片描述

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

在这里插入图片描述

以下是一个从 01 使用 LangChain 和 RAG(Retrieval Augmented Generation)构建全链路实战 AI 知识库的大致教程: ### 1. 环境准备 首先需要安装必要的库,主要是 LangChain 以及相关依赖,如向量数据库(以 Chroma 为例)等。可以使用以下命令进行安装: ```bash pip install langchain chromadb openai tiktoken ``` ### 2. 数据准备 将私域文档收集整理好,这些文档可以是文本文件、CSV 文件、PDF 等多种格式。以文本文件为例,假设存在一个文件夹 `data` 存放了所有的文本文件。 ### 3. 文档加载与分割 使用 LangChain 提供的文档加载器加载文档,并将文档分割成合适的片段。以下是示例代码: ```python from langchain.document_loaders import TextLoader from langchain.text_splitter import CharacterTextSplitter # 加载文档 loader = TextLoader('data/your_text_file.txt') documents = loader.load() # 分割文档 text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) docs = text_splitter.split_documents(documents) ``` ### 4. 生成 Embedding 使用合适的 Embedding 模型将文档片段转换为向量表示。这里以 OpenAI 的 Embedding 模型为例: ```python from langchain.embeddings import OpenAIEmbeddings embeddings = OpenAIEmbeddings() ``` ### 5. 向量存储 使用向量数据库(如 Chroma)存储生成的向量,并建立索引: ```python from langchain.vectorstores import Chroma # 创建向量数据库并存储文档 db = Chroma.from_documents(docs, embeddings) ``` ### 6. 检索器配置 配置检索器,用于根据用户查询从向量数据库中检索相关文档: ```python retriever = db.as_retriever() ``` ### 7. 集成大语言模型 使用 LangChain 集成大语言模型(如 OpenAI 的 GPT),并结合检索器实现 RAG 功能: ```python from langchain.chains import RetrievalQA from langchain.llms import OpenAI # 初始化大语言模型 llm = OpenAI() # 创建 RAG 链 qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever) ``` ### 8. 测试与部署 使用以下代码测试 RAG 系统: ```python query = "你的查询问题" result = qa.run(query) print(result) ``` 根据实际需求,可以将该系统部署到服务器上,以提供服务。 ### 总结 通过以上步骤,就可以从 01 使用 LangChain 和 RAG 构建一个全链路实战 AI 知识库。需要注意的是,在实际应用中,可能需要根据具体情况调整文档分割的参数、选择更合适的 Embedding 模型和大语言模型等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值