dev.langchain4j.data.document.parser.apache.tika.ApacheTikaDocumentParser。按官方文档,它属于langchain4j-document-parser-apache-tika模块,是DocumentParser的一个实现,基于 Apache Tika,负责自动识别文件格式并抽取文本内容;官方 RAG 教程明确把它定位为“几乎可自动解析现有大多数文件格式”的解析器。(GitHub)
1. 这个类是什么
从 LangChain4j 官方 RAG 教程看,Document可以来自 PDF、DOC、TXT 等不同格式,因此框架抽象了DocumentParser接口;其中:
TextDocumentParser适合纯文本ApachePdfBoxDocumentParser适合 PDFApachePoiDocumentParser适合 OfficeApacheTikaDocumentParser适合“自动识别并解析几乎所有现有文件格式” (GitHub)
因此它的核心定位不是“专精某一种格式”,而是:
给通用文档接入/RAG 导入链路提供一个统一解析入口。(GitHub)
2. 关键参数
ApacheTikaDocumentParser常见有两类使用方式。
2.1 无参构造
官方示例最常见的是直接:
newApacheTikaDocumentParser()然后交给FileSystemDocumentLoader.loadDocument(...)或loadDocuments(...)使用。官方 examples 就是这么写的。(GitHub)
2.2 高级构造参数
从官方测试代码可以看到,这个类支持一个更细粒度的构造方式,形态大致是:
newApacheTikaDocumentParser(AutoDetectParser::new,null,null,null,true)从这个测试可以确认它至少支持这几类可配置项:
parserSuppliercontentHandlerSuppliermetadataSupplierparseContextSupplierincludeMetadata布尔开关 (GitHub)
结合 Apache Tika 官方Parser.parse(...)方法签名可以进一步理解这些参数的职责:Tika 的核心解析过程本身就是围绕Parser、ContentHandler、Metadata、ParseContext这四个对象展开的。parse会消费输入流,把文本以 SAX/XHTML 事件方式写给ContentHandler,并把文档元数据填充到Metadata中。(Apache Tika)
3. 关键参数分别是什么意思
parserSupplier
控制底层用哪个 Apache TikaParser。
官方测试里用了AutoDetectParser::new,这说明默认思路就是自动探测格式。(GitHub)
contentHandlerSupplier
控制文本抽取如何承接。
因为 Tika 的parse(...)结果首先写给ContentHandler,所以这个 supplier 决定你最终拿到的文本抽取方式。(Apache Tika)
metadataSupplier
控制解析时使用的 TikaMetadata容器。
Tika 官方明确说parse(...)会把相关文档 metadata 填充到传入的Metadata对象里。(Apache Tika)
parseContextSupplier
控制ParseContext。
Apache Tika 官方说明ParseContext用来传递与当前解析相关的上下文信息。(Apache Tika)
includeMetadata
这是 LangChain4j 这一层很关键的开关。
官方测试显示:当includeMetadata = true时,解析出的Document.metadata()非空,并且能看到诸如X-TIKA:Parsed-By之类字段;而默认/关闭时,Document.metadata().toMap()为空。(GitHub)
4. 方法接口
这个类对外最核心的方法其实非常聚焦:parse(InputStream)。
从官方测试和 issue 里的代码片段都能看到,最常见调用是:
Documentdocument=parser.parse(inputStream);而这个parse(InputStream)内部会:
- 获取
Parser - 获取
ContentHandler - 获取
Metadata - 获取
ParseContext - 调用 Tika 的
parser.parse(inputStream, contentHandler, metadata, parseContext) - 把抽取出来的文本包装成 LangChain4j 的
Document返回 (GitHub)
另外,官方测试还表明这个方法有两类重要行为:
- 如果解析后文本为空,会抛
BlankDocumentException - 其它底层异常会被包装成
RuntimeException抛出 (GitHub)
5. 核心方法的具体使用
5.1 最基础用法:解析单个文件
官方 example:
Documentdocument=loadDocument(documentPath,newApacheTikaDocumentParser());这里ApacheTikaDocumentParser作为DocumentParser传给FileSystemDocumentLoader,最终返回的是 LangChain4j 的Document。(GitHub)
如果你手里已经有输入流,也可以直接:
ApacheTikaDocumentParserparser=newApacheTikaDocumentParser();Documentdocument=parser.parse(inputStream);这类调用方式来自官方测试。(GitHub)
5.2 批量解析目录
官方 example 里给了三种典型批量方式:
List<Document>documents=loadDocuments(directoryPath,newApacheTikaDocumentParser());List<Document>documents=loadDocuments(directoryPath,pathMatcher,newApacheTikaDocumentParser());List<Document>documents=loadDocumentsRecursively(directoryPath,newApacheTikaDocumentParser());分别对应:
- 目录下全部文档
- 按 glob/pathMatcher 过滤
- 递归子目录加载 (GitHub)
5.3 通过 SPI 作为默认解析器
官方 RAG 教程明确说:如果你不显式指定DocumentParser,LangChain4j 会通过 SPI 寻找默认解析器;如果项目里引入了langchain4j-document-parser-apache-tika或langchain4j-easy-rag,就可能自动把它作为默认 parser;如果 SPI 没找到,才会退回TextDocumentParser。(GitHub)
这意味着下面这种代码在某些依赖组合下,也可能实际上走的是 Tika:
Documentdocument=loadDocument(documentPath);官方 example 里专门演示了这一点。(GitHub)
5.4 打开 metadata 返回
如果你想把 Tika 识别出的元数据也带回 LangChain4jDocument,官方测试显示可以用高级构造,并把最后一个参数设为true:
DocumentParserparser=newApacheTikaDocumentParser(AutoDetectParser::new,null,null,null,true);Documentdocument=parser.parse(inputStream);Map<String,Object>metadata=document.metadata().toMap();测试里可见返回 metadata 中包含X-TIKA:Parsed-By、X-TIKA:Parsed-By-Full-Set。(GitHub)
6. 典型调用链
这个类在正式项目里,通常不单独使用,而是在 RAG 导入链路里出现。
调用链 1:文件系统导入
最标准的一条链:
FileSystemDocumentLoader.loadDocument/loadDocuments
→ApacheTikaDocumentParser.parse(...)
→ 返回Document
→ 后续再做DocumentTransformer、splitter、embedding、retriever。(GitHub)
调用链 2:RAG 导入通用链
结合官方 RAG 教程,可概括为:
原始文件
→DocumentLoader
→ApacheTikaDocumentParser自动识别格式并抽文本
→Document
→DocumentTransformer清洗/补 metadata
→DocumentSplitter切分
→EmbeddingStore入库
→ContentRetriever检索。(GitHub)
调用链 3:手动 InputStream 场景
在 Web 上传、对象存储下载、数据库 BLOB 场景里,常见链路是:
MultipartFile / S3 object / URL stream
→InputStream
→new ApacheTikaDocumentParser().parse(inputStream)
→Document
→ splitter / embedding。
这条链路虽然官方没有单独画图,但parse(InputStream)的测试和 RAG 教程足以支持这个调用模式。(GitHub)
7. 适用边界
7.1 适合的场景
多格式统一接入
这是它最强的场景。
当你的知识库来源混杂,既有 PDF、Word、PPT,也有 Excel、文本文件时,Tika parser 省去了你手工判断 MIME/type 再切换 parser 的工作。官方 RAG 教程直接把它描述为能自动检测并解析几乎所有现有格式。(GitHub)
RAG 文档导入前处理
如果你的目标是“先把各种文档粗暴统一抽成文本,再进入 split + embed”,它非常合适。官方 examples 和教程都把它放在 document loading 阶段使用。(GitHub)
输入格式不稳定的企业内部知识库
比如一个目录里混着 docx、pptx、pdf、xlsx、txt,这种情况下它比单一 parser 更省事。这个判断是基于官方对其“自动识别格式”的定位。(GitHub)
7.2 不太适合的场景
你只处理单一格式,且对抽取质量有更强要求
如果你明确只处理 PDF,官方已经提供ApachePdfBoxDocumentParser;只处理 Office,已有ApachePoiDocumentParser。这类专用 parser 在可控性和预期一致性上通常更清晰。官方文档本身就是按“专用 parser / 通用 parser”来分类的。(GitHub)
你要精细保留版式、表格结构、页码语义
ApacheTikaDocumentParser的核心是“抽文本”,不是“高保真文档结构重建”。从 Tikaparse(...)的接口设计看,它最终输出的是 SAX/XHTML 事件和 metadata,而不是你业务可直接消费的 rich layout model。(Apache Tika)
你希望默认就返回丰富 metadata
不是默认如此。官方测试和 issue 都表明,metadata 返回受includeMetadata影响;默认场景下,document.metadata()可能是空的。(GitHub)
空白文档 / 零字节文件
官方测试显示这类输入会抛BlankDocumentException,因此导入链路上要显式兜底。(GitHub)
8. 中文场景优化
官方没有单独写“中文优化”章节,但基于它的接口设计和 RAG 链路,中文项目里建议这样用。
8.1 解析后一定补一层DocumentTransformer
官方 RAG 教程明确建议DocumentTransformer用于 cleaning、enriching、summarizing,也可以增删 metadata;而且官方直说“没有 one-size-fits-all,建议按你的数据自己实现 transformer”。这对中文文档尤其重要,因为很多中文 PDF / Office 导出文本会有:
- 多余换行
- 页眉页脚重复
- 目录噪音
- 全角/半角混杂
- OCR 后断句异常 (GitHub)
所以在中文场景里,ApacheTikaDocumentParser更适合做“第一阶段抽取”,不要直接把原始抽取文本送去 embedding。
8.2 对中文知识库补标准 metadata
如果要做企业 RAG,建议在 parse 后补这些字段:
file_namesourcelang = zh-CNdoc_typebiz_uniteffective_dateversion
官方 example 里已经展示了file_name会在 loader/parser 链路里使用,且 RAG 教程强调 metadata 可用于 enrich、filter、inject。(GitHub)
8.3 中文长文档不要直接整篇入向量库
这不是ApacheTikaDocumentParser的问题,而是它的典型后续处理要求。解析出来的Document往往要继续 split。官方 RAG 教程把 splitter 放在 document parser 之后,这说明 parser 只负责“抽文本”,不负责“适合检索的切片”。(GitHub)
对于中文场景,尤其要注意:
- 章节标题要保留
- 不要按过大的字符块硬切
- 表格文本要额外清洗
- OCR 文本要先做去噪
这些属于对官方链路的工程化优化。(GitHub)
8.4 Excel / PPT 中文资料要做额外验证
官方测试显示它能解析 xls/xlsx,也能解析 doc/docx/ppt/pptx/pdf,但“能解析”不等于“业务语义完整”。例如测试里 xls 返回文本是按工作表名和文本顺序拼接的。对于中文报表、双层表头、单元格合并场景,这种文本化结果往往还需要业务清洗。(GitHub)
9. 一个比较稳的项目写法
9.1 基础版:通用文档导入
importdev.langchain4j.data.document.Document;importdev.langchain4j.data.document.loader.FileSystemDocumentLoader;importdev.langchain4j.data.document.parser.apache.tika.ApacheTikaDocumentParser;importjava.nio.file.Path;Documentdocument=FileSystemDocumentLoader.loadDocument(Path.of("/data/policies/employee-handbook.pdf"),newApacheTikaDocumentParser());这和官方 example 是同类写法。(GitHub)
9.2 高级版:保留 Tika metadata
importdev.langchain4j.data.document.Document;importdev.langchain4j.data.document.DocumentParser;importdev.langchain4j.data.document.parser.apache.tika.ApacheTikaDocumentParser;importorg.apache.tika.parser.AutoDetectParser;DocumentParserparser=newApacheTikaDocumentParser(AutoDetectParser::new,null,null,null,true);Documentdocument=parser.parse(inputStream);// 这里可以读取 Tika 返回的 metadatavarmetadataMap=document.metadata().toMap();这个用法来自官方测试。(GitHub)
9.3 中文企业 RAG 推荐链路
Documentdoc=newApacheTikaDocumentParser().parse(inputStream);// 1) 自定义 transformer:清洗页眉页脚、规范换行、补 lang/source/doc_type// 2) splitter:按更适合中文的规则切分// 3) embedding + store这里的“transformer → splitter → embedding”顺序与官方 RAG 教程一致。(GitHub)
LangChain4j 在文档导入阶段的“通用格式解析器”,适合把多种文件统一抽成Document文本,但它主要负责抽取,不负责高质量中文清洗、结构恢复和最终检索切片。(GitHub)