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集成 需要结合文档加载、解析、文本分割和向量化 【接下去会完善😊】
相关推荐
JavaGuide4 小时前
MiniMax M2.7 发布!Redis 故障排查 + 跨语言重构场景实测,表现如何?
redis·后端·ai·ai编程
重庆小透明4 小时前
【面试问题】java字节八股部分
java·面试·职场和发展
小王不爱笑1324 小时前
Java 对象拷贝(浅拷贝 / 深拷贝)
java·开发语言·python
架构师沉默4 小时前
程序员真的要失业了吗?
java·后端·架构
于先生吖4 小时前
SpringBoot+Vue 前后端分离短剧漫剧系统开发实战
vue.js·spring boot·后端
shengjk14 小时前
我用 EXISTS 把一条 SQL 从 18 秒优化到 6 秒,同事以为我改了索引
后端
小王不爱笑1324 小时前
SpringBoot 自动装配深度解析:从底层原理到自定义 starter 实战(含源码断点调试)
java·spring boot·mybatis
AskHarries4 小时前
openclaw对接企业微信
后端·ai编程
大傻^4 小时前
SpringAI2.0 Tool Calling 进阶:动态模式、ToolContext 与隐式解析
人工智能·springai