前面几篇文章分别介绍了 Spring AI 和 LangChain4j 在 RAG 文档处理各环节的支持——文档读取、解析、分段、清洗、元数据加工。本文将这些知识点汇总到一个完整的对比框架中,以《仙逆》知识库构建为参考场景,帮助你在项目起始阶段快速判断哪个框架更适合团队的技术栈和需求。
一、对比总览
| 阶段 | Spring AI(+Alibaba 社区) | LangChain4j |
|---|---|---|
| 文档读取 | 本地文件 + 多种云服务/数据库 + 在线平台(Alibaba 社区提供) | 本地文件 + 云存储 + URL + Selenium |
| 文档解析 | PDF / Markdown / JSON / Tika / Jsoup HTML | Text / Tika / POI / PDFBox / Markdown / YAML |
| 文本分段 | TokenTextSplitter / SentenceSplitter(Alibaba 递归分段) | 段落/行/句子/单词/字符/正则/递归(7+ 种) |
| 文档清洗 | 暂无内置实现 | HtmlToTextDocumentTransformer |
| 元数据加工 | ContentFormatTransformer / KeywordMetadataEnricher / SummaryMetadataEnricher | DocumentTransformer + TextSegmentTransformer(自定义钩子) |
二、文档读取(Extract)
文档读取解决的是"数据从哪里来"——本地磁盘、云存储、数据库、在线平台等。两框架在数据源覆盖面上各有侧重。
2.1 Spring AI(+Alibaba 社区)
| 类别 | 读取器 | Maven Artifact | 数据源示例 |
|---|---|---|---|
| 本地文件 | JsonReader/TextReader | 内置(spring-ai-commons) | .txt,.json |
| 本地文件 | PagePdfDocumentReader | spring-ai-pdf-document-reader | PDF 逐页读取 |
| 本地文件 | ParagraphPdfDocumentReader | spring-ai-pdf-document-reader | PDF 段落读取 |
| 本地文件 | MarkdownDocumentReader | spring-ai-markdown-document-reader | .md按标题/HR 分段 |
| 通用格式 | TikaDocumentReader | spring-ai-tika-document-reader | PDF/DOCX/PPTX/HTML/XML/RTF/EPUB |
| HTML | JsoupDocumentReader | spring-ai-jsoup-document-reader | CSS 选择器提取网页内容 |
| 云存储(Alibaba 社区) | 阿里云 OSS / 腾讯云 COS | Alibaba Starter | 对象存储文件 |
| 数据库(Alibaba 社区) | MySQL / MongoDB / Elasticsearch / SQLite | Alibaba Starter | 数据库查询结果 |
| 在线平台(Alibaba 社区) | GitHub / GitLab / Notion / 语雀 / 飞书 / B站 / YouTube / Obsidian | Alibaba Starter | 在线知识库或视频字幕 |
2.2 LangChain4j
| 类别 | 加载器 | Maven Artifact | 数据源示例 |
|---|---|---|---|
| 本地文件 | FileSystemDocumentLoader | 内置(langchain4j核心) | 本地路径 + glob 匹配 + 递归遍历 |
| 本地文件 | ClassPathDocumentLoader | 内置(langchain4j核心) | resources/目录 |
| URL | UrlDocumentLoader | 内置(langchain4j核心) | HTTP/HTTPS URL |
| 云存储 | AmazonS3DocumentLoader | langchain4j-document-loader-amazon-s3 | AWS S3 |
| 云存储 | AzureBlobStorageDocumentLoader | langchain4j-document-loader-azure-storage-blob | Azure Blob |
| 云存储 | GoogleCloudStorageDocumentLoader | langchain4j-document-loader-google-cloud-storage | GCS |
| 云存储 | TencentCosDocumentLoader | langchain4j-document-loader-tencent-cos | 腾讯云 COS |
| 在线平台 | GitHubDocumentLoader | langchain4j-document-loader-github | GitHub 仓库 |
| 动态网页 | SeleniumDocumentLoader | langchain4j-document-loader-selenium | 需 JS 渲染的网页 |
2.3 读取覆盖面对比
| 数据源类型 | Spring AI 原生 | Spring AI Alibaba | LangChain4j |
|---|---|---|---|
| 本地文本/JSON | ✔️ | ✔️ | ✔️ |
| ✔️ | ✔️ | ✔️ | |
| Markdown | ✔️ | ✔️ | ✔️ |
| Office 文档(DOCX/PPTX/XLS) | ✔️(Tika) | ✔️ | ✔️(POI/Tika) |
| HTML | ✔️(Jsoup) | ✔️ | ✔️(Selenium 含动态) |
| Amazon S3 | ✖️ | ✖️ | ✔️ |
| Azure Blob | ✖️ | ✖️ | ✔️ |
| Google Cloud Storage | ✖️ | ✖️ | ✔️ |
| 腾讯云 COS | ✖️ | ✔️ | ✔️ |
| 阿里云 OSS | ✖️ | ✔️ | ✖️ |
| MySQL/MongoDB | ✖️ | ✔️ | ✖️ |
| GitHub | ✖️ | ✔️ | ✔️ |
| Notion / 语雀 / 飞书 | ✖️ | ✔️ | ✖️ |
| B站 / YouTube | ✖️ | ✔️ | ✖️ |
小结:Spring AI Alibaba 在中国本土生态(OSS/语雀/B站/飞书等)覆盖面最全;LangChain4j 在海外云存储(S3/Azure/GCS)和动态网页方面更强;Spring AI 原生较轻量,专注基础格式。
2.4 读取《仙逆》资料的代码对比
假设《仙逆》资料存储在三种位置:本地 Markdown、GitHub 仓库、腾讯云 COS。
Spring AI Alibaba 方案:
// 读取本地 MarkdownMarkdownDocumentReader mdReader = new MarkdownDocumentReader( "classpath:仙逆/全文.md", MarkdownDocumentReaderConfig.builder() .withAdditionalMetadata("source", "本地归档") .build());// 读取 GitHub 仓库中的仙逆百科(Alibaba 社区插件)// GitHubDocumentReader githubReader = new GitHubDocumentReader(// "github.com/xianni-fans/wiki", "main", "docs/");// -> 自动获取仓库文件转为 Document 列表// 读取腾讯云 COS 中的仙逆音频字幕// TencentCosDocumentReader cosReader = ... // Alibaba 社区插件LangChain4j 方案:
// 读取本地 MarkdownDocument mdDoc= FileSystemDocumentLoader.loadDocument( Path.of("D:/仙逆/全文.md"), new MarkdownDocumentParser());// 读取 GitHub 仓库GitHubDocumentLoader ghLoader= GitHubDocumentLoader.builder() .gitHubToken(System.getenv("GITHUB_TOKEN")) .owner("xianni-fans") .repository("wiki") .branch("main") .build();List<Document> ghDocs = ghLoader.loadDocuments("docs/", new TextDocumentParser());// 读取腾讯云 COSTencentCosDocumentLoader cosLoader= TencentCosDocumentLoader.builder() .secretId(System.getenv("COS_SECRET_ID")) .secretKey(System.getenv("COS_SECRET_KEY")) .region("ap-beijing") .bucketName("xianni-rag") .build();List<Document> cosDocs = cosLoader.loadDocuments("novels/");三、文档解析(Parse → Document 对象)
读取文件后,需要将原始字节/文本解析为统一的Document对象(包含 content + metadata)。
3.1 Spring AI
| 解析器/Reader | 支持格式 | 核心特性 |
|---|---|---|
MarkdownDocumentReader | Markdown | HorizontalRuleCreateDocument按分割线分段;可配置是否包含代码块/引用 |
PagePdfDocumentReader | pagesPerDocument控制每 N 页生成一个 Document | |
ParagraphPdfDocumentReader | 基于 PDF 目录(TOC)智能分段落 | |
TikaDocumentReader | PDF/DOCX/PPTX/HTML 等 | 自动检测格式,自动提取元数据 |
JsonReader | JSON | jsonKeysToUse指定使用哪些 key 作为内容 |
JsoupDocumentReader | HTML | CSS 选择器提取内容块,可选提取链接 URL |
3.2 LangChain4j
| 解析器 | 支持格式 | 核心特性 |
|---|---|---|
TextDocumentParser | 纯文本 | 按字面内容解析 |
ApacheTikaDocumentParser | PDF/DOCX/PPTX/HTML/XML 等 | 与 Spring AI 的 TikaReader 功能一致 |
ApachePoiDocumentParser | DOCX/XLSX/PPTX | 精确解析 Office 文档,返回每段或每幻灯片为 Document |
ApachePdfBoxDocumentParser | 按页解析,可选 includePageNumberInText | |
MarkdownDocumentParser | Markdown | 清理 Markdown 标记后提取纯文本 |
YamlDocumentParser | YAML | 解析 YAML 文件 |
3.3 《仙逆》场景对比
| 源资料 | Spring AI 解析方式 | LangChain4j 解析方式 |
|---|---|---|
仙逆_二次化凡.md | MarkdownDocumentReader→ 按标题层级分段 | FileSystemDocumentLoader+MarkdownDocumentParser→ 整篇读入后由 Splitter 切分 |
修行体系.pdf | PagePdfDocumentReader→ 每页一个 Document | ApachePdfBoxDocumentParser→ 每页一个 Document |
人物卡片.docx | TikaDocumentReader→ 自动检测 | ApachePoiDocumentParser→ 专门处理 DOCX |
四、文本分段(Transform)
这是两框架差异最大的环节。
4.1 Spring AI
| 分段器 | 原理 | 关键参数 |
|---|---|---|
TokenTextSplitter | 按 Token 固定长度切分,通过边界搜索找最优断点 | defaultChunkSize/minChunkSizeChars/minChunkLengthToEmbed/maxNumChunks/keepSeparator |
SentenceSplitter(Alibaba) | 按句子语义切分 | sentenceSplitLength/minSentenceLength/maxSentenceLength |
RecursiveCharacterTextSplitter(Alibaba) | 递归尝试多个分隔符找最优断点 | chunkSize/chunkOverlap/ 自定义分隔符列表 |
4.2 LangChain4j
| 分段器 | 原理 | 关键参数 |
|---|---|---|
DocumentByParagraphSplitter | 按连续换行符(空行)切分 | maxSegmentSize/maxOverlapSize |
DocumentBySentenceSplitter | 按句子语义切分(OpenNLP 英文) | maxSegmentSize/maxOverlapSize |
DocumentByLineSplitter | 按换行切分 | maxSegmentSize/maxOverlapSize |
DocumentByWordSplitter | 按空格/单词切分 | maxSegmentSize/maxOverlapSize |
DocumentByCharacterSplitter | 按字符数切分 | maxSegmentSize/maxOverlapSize |
DocumentByRegexSplitter | 按正则表达式切分 | 自定义 regex |
DocumentSplitters.recursive() | 递归尝试段落→行→句子→单词→字符 | maxSegmentSizeInTokens/maxOverlapSizeInTokens |
4.3 分段策略对比
| 对比维度 | Spring AI | LangChain4j |
|---|---|---|
| 分段粒度 | Token 级 + 句子级 + 递归 | 段落/行/句子/单词/字符/正则/递归(7 种) |
| 英文语义分段 | SentenceSplitter(Alibaba 提供) | DocumentBySentenceSplitter(OpenNLP 英文模型) |
| 中文语义分段 | RecursiveCharacterTextSplitter+ 中文分隔符["。","!","?",";"] | 无专用中文句子模型(需自定义 Regex) |
| 重叠控制 | chunkOverlap(字符数) | maxOverlapSize(字符数或 Token 数) |
| 递归分段 | AlibabaRecursiveCharacterTextSplitter | DocumentSplitters.recursive() |
4.4 《仙逆》分段效果对比
对以下《仙逆》原文分别用两框架分段:
王林自封修为,在落月村化身木匠陪伴儿子王平七十二年。这七十二年里,王平三次问父亲能不能修道,次次被拒绝。化神先化凡,这是化神期的关键一步。雷道子看穿王平怨婴体质,要拿他炼器。王林解开封印,以问鼎中期修为越级斩杀阴虚强者。
Spring AI TokenTextSplitter(chunkSize=30 tokens):
块 1: "王林自封修为,在落月村化身木匠陪伴儿子王平七十二年。"块 2: "这七十二年里,王平三次问父亲能不能修道,次次被拒绝。"块 3: "化神先化凡,这是化神期的关键一步。"块 4: "雷道子看穿王平怨婴体质,要拿他炼器。王林解开封印,以问鼎中期修为越级斩杀阴虚强者。"LangChain4j recursive(maxSegmentSizeInTokens=30):
块 1: "王林自封修为,在落月村化身木匠陪伴儿子王平七十二年。"块 2: "这七十二年里,王平三次问父亲能不能修道,次次被拒绝。"块 3: "化神先化凡,这是化神期的关键一步。雷道子看穿王平怨婴体质,要拿他炼器。"块 4: "王林解开封印,以问鼎中期修为越级斩杀阴虚强者。"LangChain4j 递归分段在句号处更灵活——块 3/4 的切分位置因剩 7 个 token 而选择合并到前一句,避免了孤立碎片。
五、文档清洗(Transform)
5.1 Spring AI
Spring AI暂无内置的文档清洗 Transformer。如果 PDF 含页眉页脚或噪声文本,需自行实现DocumentTransformer接口或在上游用 Tika 做预处理。
5.2 LangChain4j
LangChain4j 提供了HtmlToTextDocumentTransformer——将 HTML 内容转为纯文本,去除 HTML 标签和格式噪音:
// 清洗《仙逆》百科的 HTML 页面DocumentTransformer cleaner = new HtmlToTextDocumentTransformer();List<Document> rawDocs = UrlDocumentLoader.loadDocuments( "https://xianni.fandom.com/wiki/王林", new TextDocumentParser());List<Document> cleanDocs = cleaner.apply(rawDocs);// 转换前:<div class="infobox">王林,主角...<br/><b>修为</b>:踏天境</div>// 转换后:王林,主角...修为:踏天境| 清洗能力 | Spring AI | LangChain4j |
|---|---|---|
| HTML → 纯文本 | ✖️(需自行实现) | ✔️(HtmlToTextDocumentTransformer) |
| 去噪声/去重 | ✖️ | 自定义DocumentTransformer钩子 |
| 格式预处理 | Tika 间接处理 | Parser 层处理 |
六、元数据加工(Transform)
6.1 Spring AI
Spring AI 在这一环节提供了最完整的内置支持——三个专用 Enricher:
| Enricher | 作用 | 使用 LLM | key 字段 |
|---|---|---|---|
ContentFormatTransformer | 统一多来源文档的键值对格式 | ✖️ | 统一格式 |
KeywordMetadataEnricher | 自动提取文档关键词 | ✔️ | excerpt_keywords |
SummaryMetadataEnricher | 对前/当前/后段落生成摘要 | ✔️ | section_summary/prev_section_summary/next_section_summary |
6.2 LangChain4j
LangChain4j 不提供现成的 Enricher 类,但通过DocumentTransformer和TextSegmentTransformer两个函数式接口,可以完全自由地实现自定义逻辑:
// 用 LangChain4j 实现等效的《仙逆》关键词提取EmbeddingStoreIngestor ingestor= EmbeddingStoreIngestor.builder() .documentTransformer(document -> { // 自定义:为仙逆人物档案补充元数据 String content= document.text(); if (content.contains("王林")) { document.metadata().put("character", "王林"); } if (content.contains("落月村") || content.contains("化凡")) { document.metadata().put("topic", "化凡"); } return document; }) .textSegmentTransformer(textSegment -> { // 自定义:检索时将文件名注入文本段,提升检索质量 String fileName= textSegment.metadata().getString("file_name"); return TextSegment.from(fileName + "\n" + textSegment.text(), textSegment.metadata()); }) .embeddingModel(embeddingModel) .embeddingStore(embeddingStore) .build();6.3 元数据加工对比
| 能力 | Spring AI | LangChain4j |
|---|---|---|
| 元数据格式统一 | ✔️ContentFormatTransformer | 自行实现DocumentTransformer |
| AI 关键词提取 | ✔️KeywordMetadataEnricher | 自行调用 LLM + 写入 metadata |
| AI 摘要生成 | ✔️SummaryMetadataEnricher | 自行调用 LLM + 写入 metadata |
| 自定义元数据注入 | 实现DocumentTransformer | DocumentTransformer+TextSegmentTransformer双钩子 |
| 开箱即用程度 | 高——三个 Enricher 可直接声明 | 低——全部自行实现,但自由度更高 |
七、完整功能矩阵
| 能力维度 | Spring AI(+Alibaba) | LangChain4j |
|---|---|---|
| 数据源数量 | 10+(含 Alibaba 社区 20+) | 9(核心 3 + 扩展 6) |
| 国内平台覆盖 | ✔️ 语雀/飞书/B站/OSS(Alibaba) | 仅腾讯 COS |
| 海外云存储 | ✖️ | ✔️ S3 / Azure / GCS |
| 解析格式 | PDF/MD/JSON/Tika/Jsoup HTML | Text/Tika/POI/PDFBox/MD/YAML |
| 分段策略数量 | 3 种 | 7+ 种 |
| 中文分隔符支持 | ✔️(Alibaba 递归分段) | 需自定义 Regex |
| HTML 清洗 | ✖️ | ✔️HtmlToTextDocumentTransformer |
| 元数据 Enricher | ✔️ 3 种内置 | ✖️ 自行实现 |
| 管道串联 | 手动组合reader.get() → splitter.apply() → store.accept() | EmbeddingStoreIngestor一键串联 |
八、《仙逆》场景的技术选型
| 场景 | 推荐框架 | 理由 |
|---|---|---|
| 仙逆全文 + 中文书评 + 百科,多格式混合 | Spring AI Alibaba | 国内平台覆盖全(B站/语雀/飞书),中文分隔符支持好,内置元数据 Enricher 可直接增强人物卡片 |
| 海外团队,仙逆英文翻译版 + 英文 Wiki | LangChain4j | S3/GitHub 原生支持,7 种分段策略灵活组合,英文句子分割成熟 |
| 已有 Spring Boot,快速搭建仙逆问答 | Spring AI Alibaba | 与 Spring 自动配置深度集成,Embedding 模型和 VectorStore 一键注入 |
| 需要动态网页抓取仙逆讨论帖 | LangChain4j | SeleniumDocumentLoader是唯一支持动态 JS 网页的读取器 |
| 已有 PostgreSQL,需 SQL + 向量混合查询 | 两框架均可 | pgvector 在两边都有 Starter,改配置切换,业务代码不变 |
九、总结
核心结论只有几条:
- •数据源选 Spring AI Alibaba——如果你需要接语雀/飞书/B站/MySQL 等国内平台,LangChain4j 完全覆盖不到。
- •分段策略选 LangChain4j——7 种分段器 + 递归策略,比 Spring AI 的选择更多更细。
- •元数据加工选 Spring AI——三个 Enricher 开箱即用,LangChain4j 需全部手动实现。
- •管道串联选 LangChain4j——
EmbeddingStoreIngestor声明式构建,代码量更少。 - •不要为某单一能力强行迁就框架——两框架的
Document和VectorStore抽象高度相似,可以在读取阶段用 Spring AI Alibaba 的 Reader,在分段阶段用 LangChain4j 的 Splitter,最终都用 pgvector 存储——关键在于Document对象本身可以互相转换(都是 content + metadata 的键值对)。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~