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集成 需要结合文档加载、解析、文本分割和向量化 【接下去会完善😊】
相关推荐
漂洋过海的鱼儿6 分钟前
设计模式——EIT构型(三)
java·网络·设计模式
曹轲恒8 分钟前
@PropertySource、@ImportResource、@Bean
java·spring boot·mybatis
_OP_CHEN1 小时前
【Linux系统编程】(二十)揭秘 Linux 文件描述符:从底层原理到实战应用,一篇吃透 fd 本质!
linux·后端·操作系统·c/c++·重定向·文件描述符·linux文件
Anastasiozzzz1 小时前
Redis的键过期是如何删除的?【面试高频】
java·数据库·redis·缓存·面试
老神在在0011 小时前
Token身份验证完整流程
java·前端·后端·学习·java-ee
王九思1 小时前
Java 内存分析工具 MAT
java·开发语言·安全
浅水壁虎2 小时前
任务调度——XXLJOB2(调度中心)
java·spring boot·spring
青火coding2 小时前
SOFAServerless架构的意义
java·运维·中间件·架构·serverless
夕除2 小时前
java--2
java·开发语言
源码获取_wx:Fegn08952 小时前
计算机毕业设计|基于springboot + vue景区管理系统(源码+数据库+文档)
java·vue.js·spring boot·后端·课程设计