Spring AI RAG 系统文档加载

一、引言:为什么需要文档加载与解析

在构建现代RAG(Retrieval-Augmented Generation)系统时,文档加载与解析是整个流程的基石。RAG系统的核心目标是什么呢?将外部知识源与大语言模型(LLM)结合,提供更准确、更相关的回答。而文档加载与解析正是将原始数据转化为LLM可理解的结构化文本的关键步骤。

Spring AI Alibaba 提供了一套完整的文档加载与解析解决方案,它不仅支持常见的文档格式(PDF、Word、Markdown等),还集成了云存储、数据库和在线平台等数据源,为RAG系统提供了强大的数据摄取能力。


二、核心概念解析

2.1 Document Reader 与 Document Parser 的区别与关系

|------------|---------------------------|
| 特性 | Document Reader |
| 核心职责 | 从数据源读取文档内容(文件系统、数据库、云存储等) |
| 输入 | 文件路径、数据库查询、API端点等 |
| 输出 | List<Document> |
| 典型使用场景 | 从GitHub仓库获取Markdown文件 |
| 依赖关系 | 通常与Document Parser配合使用 |

大家快来看啊 👀**-这个关系**👀

复制代码
数据源(oss、本地文件等) 
    ↓
Document Reader(获取原始内容)
    ↓
Document Parser(解析内容格式)
    ↓
List<Document>(结构化文档)
    ↓
文本分割、向量化、存储到向量数据库

2.2 Spring AI Alibaba 的文档加载与解析架构

Spring AI Alibaba 采用模块化设计,提供了丰富的扩展实现:

  1. Document Reader:负责数据源的接入

    • 本地文件:doc、Markdown等
    • 云存储:OSS
    • 数据库:MySQL、MongoDB、SQLite
    • 在线平台:GitHub、GitLab、语雀
  2. Document Parser:负责内容解析

    • 格式解析:Tika、PDFBox、BibTeX
    • 多模态:图像OCR、语音转文字
    • 特定格式:Markdown、YAML、HTML

三、详细指南

3.1 文档加载器(Document Reader)详解

3.1.1 POI Document Reader( Office 文档)

使用场景:处理Word、Excel、PowerPoint文档

XML 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-document-reader-poi</artifactId>
</dependency>

详细使用示例

java 复制代码
import com.alibaba.cloud.ai.reader.poi.PoiDocumentReader;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.util.List;

/*
author: atg
*/
@Component
public class OfficeDocumentReader {

    /**
     * 从本地文件系统读取Word文档
     */
    public List<Document> readWordDocument(String filePath) {
        DocumentReader reader = new PoiDocumentReader(filePath);
        // 读取文档内容
        return reader.get();

    }

    /**
     * 从类路径资源读取Excel文件
     */
    public List<Document> readExcelFromClasspath() {
        Resource resource = new ClassPathResource("documents/sales_report.xlsx");
        DocumentReader reader = new PoiDocumentReader(resource);
        return reader.get();
    }

    /**
     * 读取Excel文件并按工作表组织
     */
    public void readExcelWithSheets(String excelPath) {
        PoiDocumentReader reader = new PoiDocumentReader(excelPath);
        List<Document> documents = reader.get();

        // Excel文件会按工作表组织内容
        for (Document doc : documents) {
            System.out.println("工作表名称: " + doc.getMetadata().get("sheetName"));
            System.out.println("内容: " + doc.getText().substring(0, 100) + "...");
        }
    }
}

元数据说明

  • source: 文档的源路径或URI
  • sheetName: Excel工作表名称(仅适用于Excel文件)
  • fileName: 文件名(从路径中提取)

注意事项

  1. 文件格式支持:确保文件格式在Apache POI的支持范围内
  2. 内存使用:处理大型Office文档时注意内存使用情况
  3. 异常处理:建议在生产环境中添加适当的异常处理
  4. 编码问题:某些旧格式的Office文档可能存在编码问题
3.1.2 Markdown Document Reader

使用场景:处理Markdown格式文档

XML 复制代码
<dependency>
     <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-markdown-document-reader</artifactId>
</dependency>

详细使用示例

java 复制代码
package com.atg.airag.rag.loader;

import org.springframework.ai.document.Document;
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.util.List;

/*
author: atg
*/

/**
 * markdown 文档读取器
 */
@Component
public class MarkdownDocumentReaderLoader{

    @Value("classpath:document/psychology.md")
    private Resource resource;

    public List<Document> loadMarkdown() {
        // 创建配置
        MarkdownDocumentReaderConfig config = MarkdownDocumentReaderConfig.builder()
                .withHorizontalRuleCreateDocument(true)
                .withIncludeCodeBlock(false)
                .withIncludeBlockquote(false)
                .withAdditionalMetadata("filename", "psychology.md")
                .build();

        // 使用配置和资源创建 MarkdownDocumentReader
        MarkdownDocumentReader reader = new MarkdownDocumentReader(this.resource, config);

        // 读取文档并返回
        return reader.get();
    }
}

RAG系统完整集成案例

java 复制代码
import com.atg.airag.rag.loader.MarkdownDocumentReaderLoader;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 在RAG系统中使用Markdown文档
 */
@Service
public class RAGMarkdownProcessor {

    private final VectorStore vectorStore;
    private final TokenTextSplitter textSplitter;
    private final MarkdownDocumentReaderLoader markdownDocumentReader;

    @Autowired
    public RAGMarkdownProcessor(VectorStore vectorStore, TokenTextSplitter textSplitter, MarkdownDocumentReader markdownDocumentReader, MarkdownDocumentReaderLoader DocumentReader) {
        this.vectorStore = vectorStore;
        this.textSplitter = textSplitter;

        this.markdownDocumentReader = DocumentReader;
    }
    public void processMarkdownForRAG(String markdownPath) {
        // 1. 读取Markdown文档
        List<Document> documents = markdownDocumentReader.loadMarkdown();

        // 2. 文本分割
        List<Document> splitDocuments = textSplitter.transform(documents);

        // 3. 存储到向量数据库
        vectorStore.write(splitDocuments);

        System.out.println("成功加载 " + splitDocuments.size() + " 个Markdown文档块");
    }
    public List<Document> searchSimilarDocuments(String query) {
        // 从向量数据库检索相似文档
        return vectorStore.similaritySearch(query);
    }
}

MarkdownDocumentReaderConfig 配置详解

配置项 说明 默认值 适用场景
horizontalRuleCreateDocument 是否将Markdown中的水平规则(---)视为新文档的分隔符 false 需要按章节分割文档
includeCodeBlock 是否将代码块包含在与周围文本相同的文档中 true 需要保留代码块的上下文
includeBlockquote 是否将引用块包含在与周围文本相同的文档中 true 需要保留引用内容的上下文
additionalMetadata 添加自定义元数据到所有文档 为文档添加来源、作者等信息

四、总结

在RAG系统中,文档加载与解析是至关重要的环节。Spring AI Alibaba 提供了全面的解决方案,支持从各种数据源读取文档,并将文档内容转换为结构化的Document对象。

关键要点回顾

  1. Document Reader 负责从数据源获取原始内容
  2. MarkdownDocumentReaderConfigTikaDocumentParser 提供了丰富的配置选项
  3. RAG集成 需要结合文档加载、解析、文本分割和向量化 【接下去会完善😊】
相关推荐
涡能增压发动积20 小时前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
云烟成雨TD20 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
Wenweno0o20 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨20 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
swg32132120 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
tyung20 小时前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald20 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川20 小时前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java
一轮弯弯的明月20 小时前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
chenjingming66620 小时前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter