news 2026/10/26 13:31:51

Spring AI 2.0 ETL:把 PDF、Word 接入知识库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI 2.0 ETL:把 PDF、Word 接入知识库

大家好,我是一言,继续更新 Spring AI 2.0 系列。

前面几篇,我们一直在聊资料入库后怎么检索。这次往前走一步:售后规则放在 PDF、Word 里,怎样让 RAG 用上它们?

Spring AI 的 ETL 管道负责这段准备工作:读出文件内容、整理成片段,再写入向量存储。今天接入两份售后文档,最后用 Postman 提问,核对回答来自哪个文件、哪一页。

ETL 这三个字母,分别做什么

ETL 是 Extract、Transform、Load,也就是提取、转换、加载。Spring AI 官方把它分成三个接口:

接口这篇让它做什么
DocumentReader从 PDF、Word 提取文字
DocumentTransformer把长文切成适合检索的片段
DocumentWriter将片段写入向量存储

三段之间传递的都是List<Document>。这里的Document可以理解成一个 Java 数据对象,里面装着文本和元数据,例如文件名、页码。

这些接口在 Spring AI 1.x 已经存在。下面用Spring AI 2.0.1跑通整条链路。

先看准备入库的资料

我编了两份商城售后演示文档,规则只用于这个示例:

文件内容
returns.pdf,2 页第 1 页普通退货;第 2 页定制商品退货
refunds.docx银行卡到账时间、银行卡注销、余额退款

PDF 第二页专门写了一个例外:刻字、改尺寸的定制商品不支持无理由退货;出现质量问题,可以提交凭证申请审核。

整个示例分两段:先把文件准备成知识库,提问时再检索其中的片段。

两种文件,读成同一种对象

PDF 使用PagePdfDocumentReader,Word 使用基于 Apache Tika 的TikaDocumentReader。对应依赖是spring-ai-pdf-document-reader和spring-ai-tika-document-reader,版本由 Spring AI BOM 统一管理。

varpdfReader=newPagePdfDocumentReader(newClassPathResource("docs/returns.pdf"),PdfDocumentReaderConfig.builder().withPagesPerDocument(1).withPageBottomMargin(65).build());varwordReader=newTikaDocumentReader(newClassPathResource("docs/refunds.docx"));vardocuments=newArrayList<Document>();documents.addAll(pdfReader.read());documents.addAll(wordReader.read());

withPagesPerDocument(1)表示每页生成一个Document。底部留白配置用于跳过这份 PDF 的页脚,换文件时要按实际版式调整。

这两份文件读出来,一共是3 个 Document:PDF 每页一个,Word 全文一个。

PDF Reader 带有page_number元数据;这里的 Tika Reader 没有提供 Word 页码。后续统一给文档补上source文件名,方便查询时回溯。

document.getMetadata().put("source","returns.pdf");

读取阶段先检查文字是否完整。带文字层的 PDF 可以直接走这条流程;扫描件需要先做 OCR,复杂表格也要单独检查提取效果。

切成片段,再交给向量存储

varsplitter=TokenTextSplitter.builder().withChunkSize(180).withMinChunkSizeChars(60).withMinChunkLengthToEmbed(5).withPunctuationMarks(List.of('。','?','!',';','\n')).build();varchunks=splitter.apply(documents);varstore=SimpleVectorStore.builder(embeddingModel).build();store.add(chunks);

分块会保留原有元数据。调用add时,向量存储通过 Embedding 模型计算向量,同时保存片段文本与元数据。

这里使用本地Qwen3-Embedding 0.6B,回答模型是Qwen2.5 3B。SimpleVectorStore用于内存演示,正式知识库可以换成 PgVector 等持久化实现。

在 Postman 中发送POST /api/etl/import,读取项目里的这两份文件:

结果是2 个文件 → 3 份文档 → 4 个片段,每个片段对应一个 1024 维向量。图中的毫秒数是这次本地运行的阶段耗时,文件量和模型环境变化后也会变化。

问一道需要区分规则的问题

向POST /api/etl/ask发送:

{"question":"刻字的定制商品收到三天,不喜欢了,可以无理由退货吗?"}

后端先取两个相关片段,再把片段与问题一起交给ChatClient。提示词要求只依据资料回答,并保留适用条件和例外。

varhits=store.similaritySearch(SearchRequest.builder().query(question).topK(2).build());varanswer=client.prompt().system("只依据提供的资料回答,保留适用条件和例外。").user("资料:\n"+context+"\n问题:"+question).call().content();

context是命中片段的文本及来源拼接结果;上面省略了拼接代码和回答长度约束。

这次回答明确说了“不支持无理由退货”,没有套用普通商品的七天规则。展开sources,第一条就是returns.pdf的第 2 页。

再问银行卡注销,核对 Word 是否也能检索到:

回答保留了“提供销户证明、核验后转人工处理、不能承诺一至三个工作日到账”这几个条件。

sources由后端根据检索结果附上,方便对照原文;它并不代表每句话都已经完成事实校验。两个接口也是演示项目的入口,读取、分块和向量存储用的是 Spring AI 组件。

到这里,PDF、Word 已经走完了读取 → 分块 → 向量化 → 检索问答。后面换成更多业务文档,可以沿用这套结构,先把解析内容和来源信息核对清楚,再扩大入库量。


作者:一言。持续分享 Spring AI 与 Java AI 应用实战。系列文章首发于微信公众号「雷一言说」。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 13:03:58

力扣49题字母异位词分组:哈希表键设计的两种解法与优化

最近刷力扣刷到第49题"字母异位词分组"&#xff0c;这道题在面试里出现频率相当高&#xff0c;而且它考察的点非常典型——哈希表的灵活运用。很多人在初次接触这道题时&#xff0c;容易被"异位词"这个概念绕晕&#xff0c;其实把它翻译成大白话就是&#…

作者头像 李华
网站建设 2026/10/25 9:08:54

AI Agent本地部署与远程接管实战指南:从模型选型到安全暴露

1. 想清楚再动手&#xff1a;AI Agent 本地养成的全景思路 我最近一直在折腾一件事&#xff1a;把 AI Agent 真正养在自己的电脑上&#xff0c;而不是每次想用都去网页端排队。所谓“养”&#xff0c;不是下载一个聊天软件那么简单&#xff0c;而是让模型权重、工具调用、记忆存…

作者头像 李华
网站建设 2026/10/26 4:46:35

Bash解析CSV的完整指南:从IFS原理到引号状态机实战

CSV解析在Bash里是个看似简单、做起来全是坑的活儿。很多人第一次写Shell脚本处理CSV文件&#xff0c;上来就是一句 cut -d , -f 2 或 while IFS, read &#xff0c;结果遇到引号内的逗号、Windows换行符、空字段之类的状况&#xff0c;脚本瞬间翻车。我这几年在运维和数据…

作者头像 李华
网站建设 2026/10/25 19:53:14

企业级Ansible架构设计:分层管理与标准化实践

1. 项目概述 在IT基础设施管理领域&#xff0c;Ansible已经成为自动化配置和部署的事实标准工具。但很多团队在将Ansible应用于大型工业级项目时&#xff0c;常常面临架构混乱、角色定义不清、变量管理失控等问题。这份指南正是为了解决这些痛点而生&#xff0c;它基于我在金融…

作者头像 李华
网站建设 2026/10/19 11:35:39

Node.js核心技术解析与应用实践指南

1. Node.js 的现状与市场定位 Node.js 自2009年诞生以来&#xff0c;经历了从新兴技术到主流工具的转变。尽管近年来不断有"Node.js 已死"的论调出现&#xff0c;但根据2023年 Stack Overflow 开发者调查报告&#xff0c;Node.js 仍然占据后端框架使用率第一的位置&a…

作者头像 李华
网站建设 2026/10/26 11:28:02

ARM嵌入式SD卡驱动实战:从协议机制到文件系统移植

搞过ARM嵌入式开发的朋友&#xff0c;十有八九都会跟SD卡打交道。这玩意儿看着不起眼&#xff0c;插上就能存数据&#xff0c;但真要在嵌入式项目里把它跑稳、跑快、跑可靠&#xff0c;里面门道其实不少。网上关于SD卡的资料很杂&#xff0c;要么是纯理论协议分析&#xff0c;要…

作者头像 李华