news 2026/9/25 3:51:48

用 txtai-xberg 把 Xberg 多格式文档提取接入 txtai 语义搜索:安装、索引与源码级拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 txtai-xberg 把 Xberg 多格式文档提取接入 txtai 语义搜索:安装、索引与源码级拆解
  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

txtai-xberg是 Xberg 官方提供的 txtai 集成包:它把 Xberg 的文档提取能力(107 种格式、按需 OCR、原生分块)包装成一个可调用管道XbergPipeline,输出(id, text, tags)三元组直接喂给txtai.Embeddings.index,从而让 PDF、DOCX、HTML 等异构文档在数行代码内完成"提取 → 分块 → 向量化 → 语义检索"全链路。读完本文,你将掌握该集成的安装、两种调用模式(仅提取 / 直接建索引)、配置项语义、错误处理约定,以及extract_batch批量提取在 Rust 核心与 Python 绑定层之间的真实调用链。

集成定位与工作流

txtai-xberg的职责非常聚焦:不做检索,只负责把文档变成 txtai 能直接消费的语料。它站在 Xberg 的 Python 绑定之上(依赖xberg>=1.2.8),把 Xberg 的异步提取 API 封装为符合 txtai pipeline 习惯的可调用对象。整体数据流如下:

  1. Extract(提取)— Xberg 解析源文档,并在必要时运行 OCR(如扫描版 PDF 或图片型文档)。
  2. Chunk(分块)— 当传入的ExtractionConfig启用 chunking 时,Xberg 把每篇文档切分为语义分片,并在分片中保留标题路径(heading_path)与页码上下文。
  3. Flatten(展平)—to_documents把提取结果展平为(id, text, tags)元组:启用分块时每个 chunk 一条,未启用时每个文件一条。
  4. Index(索引)— 把元组直接交给txtai.Embeddings.index,即可获得关键词、向量或混合检索能力。

安装

pip install txtai-xberg

包要求 Python 3.10+(pyproject.toml中requires-python = ">=3.10",classifiers 覆盖 3.10~3.14)。如果环境中还没有 txtai,可通过 extra 一并安装:

pip install "txtai-xberg[txtai]"

该 extra 声明了txtai>=9.7,<10的版本区间;基础依赖xberg>=1.2.8,<2会自动带入 Xberg 的 Python 绑定(见 pyproject.toml)。包内部结构极简:src/txtai_xberg/下只有pipeline.py(核心实现)、__init__.py与py.typed,并以py.typed提供类型标注支持。

快速开始:提取并索引分块文档

from txtai import Embeddings from txtai_xberg import XbergPipeline from xberg import ChunkingConfig, ExtractionConfig pipeline = XbergPipeline( config=ExtractionConfig(chunking=ChunkingConfig(max_characters=1000, overlap=200)), ) documents = pipeline.to_documents(["report.pdf", "notes.docx"]) embeddings = Embeddings(path="sentence-transformers/all-MiniLM-L6-v2", content=True) embeddings.index(documents) for result in embeddings.search("quarterly revenue", 3): print(result["id"], result["text"])

要点:

  • 分块 ID 约定:分块文档的id形如"<source>#<chunk_index>",例如report.pdf#0、report.pdf#1。这一格式由 pipeline.py 中的_chunk_to_index_document生成,测试test_to_documents_chunk_ids_are_unique也验证了 ID 的唯一性。
  • 不分块的默认行为:如果不传chunking配置,to_documents每文件只产出一条文档,id即源路径本身。
  • content=True的意义:txtai 在保存向量时会同时存储原始文本,检索结果因此能直接返回命中的段落文本。

仅提取模式:不建索引,直接读内容

XbergPipeline本身是可调用对象,适合只想拿提取结果、不进入索引环节的场景。按 txtai pipeline 惯例,传入单个字符串返回单个文档,传入列表按输入顺序返回文档列表:

from txtai_xberg import XbergPipeline pipeline = XbergPipeline() doc = pipeline("report.pdf") print(doc["content"]) # 提取出的 markdown 文本 print(doc["metadata"]["title"]) # 见下方 metadata 字段说明 docs = pipeline(["report.pdf", "notes.docx"]) # 列表输入 → 列表输出

每个返回的文档是包含content与metadata两个键的字典(ExtractionDocumentTypedDict)。metadata的结构由 pipeline.py 中的DocumentMetadata定义,字段如下:

字段类型含义
sourcestr输入路径,原样回传
mime_typestr检测到的 MIME 类型(如application/pdf、text/plain)
titlestr \| None文档标题(无标题时可能为None)
authorslist[str] \| None作者列表
languageslist[str] \| None检测到的语言列表
page_countint页数(无分页概念的格式为 0)

测试 test_pipeline.py 断言了这六个键是稳定存在的元数据契约:即使值可能为None,键也始终出现。

两个方法族怎么选

to_documents/ato_documents__call__/acall
返回(id, text, tags)元组{content, metadata}字典
粒度每 chunk 一条(或每文件一条)每文件一条
适用场景直接喂给Embeddings.index直接读取提取后的文本

一句话总结:要建索引用to_documents,要读文本用__call__。两者内部共享同一条提取路径,只是对结果的展平方式不同。

深入:to_documents的数据契约

to_documents返回IndexDocument,即tuple[str, str, dict[str, Any]],对应 txtaiEmbeddings.index接收的(id, text, tags)格式。tags是元数据映射,txtai 会将其存储,并在content=True时暴露为可过滤的列。

未启用分块时,每条文档的tags包含四个键(见 pipeline.py):

  • source:源路径
  • mime_type:MIME 类型
  • title:标题
  • page_count:页数

启用分块时,每个 chunk 的tags扩展到九个键(见 pipeline.py),这是做切片级过滤检索的关键:

  • source、mime_type、title:文档级信息透传
  • chunk_index:该 chunk 在文档内的序号(从 0 开始)
  • total_chunks:文档总分块数
  • heading_path:标题路径(如Introduction > Methods),保留文档层级上下文
  • first_page/last_page:chunk 覆盖的页码范围
  • token_count:chunk 的 token 数

这些键的完整性由测试 test_to_documents_with_chunking_splits_into_multiple_segments 直接断言。有了source + chunk_index + first_page/last_page,你在检索命中后可以精确回溯到原文位置,这对 RAG 场景的引用溯源非常实用。

深入:用 ExtractionConfig 控制提取行为

XbergPipeline(config=...)接受任意 Xberg 的ExtractionConfig,这是打通提取行为的统一入口。ExtractionConfig定义于 packages/python/xberg/options.py,字段众多,与本文场景最相关的几组:

OCR 控制

from xberg import ExtractionConfig, OcrConfig pipeline = XbergPipeline( config=ExtractionConfig( output_format="markdown", # 输出文本格式:plain / markdown 等 ocr=OcrConfig(language="eng"), # OCR 语言设置 force_ocr=True, # 即使是可搜索 PDF 也强制走 OCR max_concurrent_extractions=8, # 批量提取的并发上限 ), )

相关字段:

  • output_format(默认"plain"):控制内容文本格式,设为"markdown"时可保留标题、列表、表格等结构;测试 test_config_drives_extraction_output_format 验证了 plain 与 markdown 两种输出内容确实不同。
  • force_ocr(默认False):强制对所有页面 OCR;另有force_ocr_pages(按 1 起始页码指定特定页)、ocr_strategy(默认auto)、disable_ocr等更细粒度开关。
  • max_concurrent_extractions:批量提取时 Xberg 内部 worker 池的并发上限,默认由 Xberg 决定。
  • extraction_timeout_secs(默认 600):批量提取中每个文件的超时时间。

原生分块(ChunkingConfig)

from xberg import ChunkingConfig ChunkingConfig( max_characters=1000, # 每个 chunk 的最大尺寸(单位随 sizing 而定) overlap=200, # chunk 间重叠量 trim=True, # 是否裁剪 chunk 边界空白 chunker_type="text", # 分块器类型:text / markdown sizing="characters", # 尺寸度量方式(如 characters / tokens) table_chunking="split" # 超过尺寸上限的 markdown 表格如何处理 )

ChunkingConfig的完整定义在 packages/python/xberg/options.py,max_characters与overlap的默认值分别为 1000 与 200。从源码结构看,它还支持embedding/sparse_embedding/late_interaction等可选配置用于生成 chunk 级向量,以及preset预设与topic_threshold语义主题边界检测,说明 Xberg 的 chunking 不止于字符切分,还具备语义与结构感知能力。

测试中用ChunkingConfig(max_characters=200, overlap=20)处理三页 PDF fixture,得到多个 chunk 并逐项校验了chunk_index、total_chunks、heading_path、first_page、last_page、token_count等标签字段。

同步与异步:两种 API 形态

XbergPipeline的方法都成对出现:

同步异步说明
__call__(docs)acall(docs)返回提取文档(字典/字典列表)
to_documents(docs)ato_documents(docs)返回(id, text, tags)列表

同步版本通过asyncio.run桥接 Xberg 的异步 API(见 pipeline.py),因此不能在已运行的事件循环内调用同步方法——在 async 代码中请改用acall/ato_documents。测试 test_ato_documents_matches_sync 验证了同步与异步版本产出完全一致的结果。

错误处理:ExtractionFailedError

批量提取时若部分输入失败,管道不会静默跳过,而是抛出ExtractionFailedError。该异常对象的errors属性持有 Xberg 的ExtractionErrorItem列表,每个错误项包含:

  • index:失败输入在输入列表中的位置(便于定位是第几个文件)
  • source:失败的源路径
  • code:数值错误码
  • message:错误描述

异常信息会把所有失败项汇总为可读的明细(见 pipeline.py)。设计上有一个值得注意的细节:由于 Xberg 的result.results只包含成功项,若直接按输入顺序 zip 会产生错位,因此实现选择"任何失败立即抛错"而非部分成功(pipeline.py 的注释说明了这一点)。测试 test_missing_file_raises_with_error_index 验证了缺失文件场景下index与source的正确性。

底层原理:一次原生批量调用

管道性能的关键在于_extract(pipeline.py):它把每个路径包装为ExtractInput(uri=path),然后一次调用extract_batch,而不是逐个文件循环调用。extract_batch定义于 Python 绑定层 packages/python/xberg/api.py,签名如下:

async def extract_batch( inputs: list[ExtractInput], config: ExtractionConfig | None = None, ) -> ExtractionResult:

它会把 Python 侧的ExtractInput/ExtractionConfig转换为 Rust 绑定类型,再进入 Rust 核心的批处理器(对应 crates/xberg/src/api/handlers.rs)。ExtractInput的定义在 packages/python/xberg/options.py:

  • kind(默认"uri"):输入类型,uri对应本地路径 /file:/// HTTP(S) URL,bytes对应原始字节
  • uri:路径或 URL
  • mime_type/filename:可选的 MIME 与文件名提示
  • config:per-input 提取覆盖

批量输入会被分发到 Xberg 内部 worker 池并发执行(并发上限由max_concurrent_extractions控制),这正是原文档强调"extract_batch比逐个循环更快"的实现基础——并发在 Rust 核心内完成,Python 侧只承担一次 FFI 编组开销。

测试覆盖:行为即契约

integrations/python/txtai/tests/test_pipeline.py的测试用例几乎逐条锁定了上文描述的行为,可作为集成用法的活文档:

  • 输入形态:单路径返回单个字典;列表返回按序列表;单元素列表仍返回列表;空列表返回空列表。
  • 元数据真实性:HTML fixture 的mime_type包含html、title为Sample HTML Document;PDF fixture 的page_count == 3、mime_type == "application/pdf"、title is None;DOCX fixture 的title == "DOCX Demo";TXT 的page_count == 0。
  • 配置透传:默认构造时_config为None,传入的ExtractionConfig原样存储——说明管道本身不修改配置,一切行为由 Xberg 核心解释。
  • 分块行为:分块 ID 唯一、首 chunk ID 为"<source>#0"、tags 键集合严格匹配。

这些 fixture(sample.pdf、sample.docx、sample.html、sample.txt)位于 integrations/python/txtai/tests/fixtures/,你可以在本地复现整套测试来验证集成行为。

小结

txtai-xberg的价值在于把两件事做薄而做透:提取交给 Xberg(107 种格式 + 按需 OCR + 原生分块),检索交给 txtai(关键词 / 向量 / 混合)。它的全部复杂性收敛在一个XbergPipeline类里——传入ExtractionConfig控制提取,to_documents产出索引就绪的(id, text, tags),ExtractionFailedError兜底批处理失败。若你的 RAG 管线需要处理多格式文档,这个集成提供了从文件到语义检索的最短路径。更多 Xberg 提取 API 与配置细节可查阅 packages/python/xberg/api.py 与 packages/python/xberg/options.py;txtai 本身的用法可参考其官方文档。

  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

相关推荐

上一篇:TypeGraphQL与Koa GraphQL性能对比:基准测试结果
下一篇:Vue CLI 模式(Modes)与环境变量(Environment Variables)完全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

AI小说生成:7分钟装好本地长篇写作工具

AI小说生成&#xff1a;7分钟装好本地长篇写作工具 【免费下载链接】AI_NovelGenerator 使用ai生成多章节的长篇小说&#xff0c;自动衔接上下文、伏笔 项目地址: https://gitcode.com/GitHub_Trending/ai/AI_NovelGenerator AI小说生成工具里&#xff0c;AI_NovelGener…

作者头像 李华
网站建设 2026/9/25 3:50:11

旧电脑也能跑NetSurveillance DVR:开源自建监控录像系统指南

简介&#xff1a;面向Windows平台IE浏览器的NetSurveillance DVR插件&#xff0c;是一套通过网络远程访问监控设备的轻量级解决方案&#xff0c;主要针对安防工程人员、运维人员和二次开发者。资源包共61个文件、约1.07MB&#xff0c;核心构成包括ActiveX控件、H.264解码播放库…

作者头像 李华
网站建设 2026/9/25 3:49:58

英文论文常见缩写全解析:w/、i.e.、s.t.、cf.用法与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 3:49:56

Java基础学习路线与核心知识点:从环境配置到面向对象实战

1. 别急着刷题&#xff1a;先把Java基础的学习路线走对我见过太多人学Java上来就搞反了&#xff1a;课还没听几节&#xff0c;先下了个面试八股文大全开始背&#xff1b;或者说语法刚看完循环和数组&#xff0c;就直接冲去学Spring Boot。结果呢&#xff1f;两个月后代码写不出…

作者头像 李华