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. MarkdownDocumentReaderConfig 和 TikaDocumentParser 提供了丰富的配置选项
  3. RAG集成 需要结合文档加载、解析、文本分割和向量化 【接下去会完善😊】
相关推荐
付威202315 小时前
如果你想拥有自己的 Agent,为什么值得从 rpi 开始
后端
木头科技15 小时前
【AI 工程化第十五篇】Spring AI 流式输出高并发性能优化实战:SSE、背压、限流、缓存与灰度发布
人工智能·spring·性能优化
2302_8057710716 小时前
Day23:POM设计模式(封装)
java·开发语言·设计模式
十年Java程序媛16 小时前
Java String、StringBuilder、StringBuffer 底层原理|字符串拼接性能与线程安全
java·开发语言·spring boot·安全·面试
可乐ea16 小时前
2000 个智能体把 Agent 重写成 Rust:编排流水线拆解
开发语言·后端·rust·多智能体协作·ai编程助手·智能体编排·rust重写
用户727574831965016 小时前
02-变量、常量和字符串:len("Hello, 世界") 为什么不是 9?
后端
SamDeepThinking16 小时前
CyclicBarrier的底层实现
java·后端·面试
god_cvz16 小时前
第二章:6、对话记忆与引用标注
后端·ai编程
拖孩16 小时前
全程 AI 写的小程序,刚接上会员虚拟支付,上线第二天就有人真金白银买单了|双签名、定价、iOS 的坑我全踩了一遍
前端·后端·微信小程序
我是人✓16 小时前
SpringMVC异常处理与拦截器实战揭秘
java·开发语言·后端