- 后端
- 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.
本篇指南围绕 xberg 开源仓库中 Go 语言 contract 片段
api_extract_batch_bytes_with_config(源文件见 docs-site/src/snippets-generated/go/contract/api_extract_batch_bytes_with_config.md)展开,讲解如何用 Go 绑定一次性批量提取多份二进制文档,并针对其中某一输入单独指定提取配置(per-input config)。读完本文,你将掌握xberg.ExtractBatch的完整调用方式、ExtractInput/FileExtractionConfig的字段语义、输出结果的读取方法,以及它在 FFI 层的真实调用链与对应的合约断言,可直接复用到你自己的批量文档处理管线中。
一、场景定位:什么时候使用批量字节提取
xberg 是一个以 Rust 为核心的 polyglot 文档智能提取引擎(README.md 描述其可处理 106 种格式、140 种扩展名)。在实际业务中,文档很少单份出现——无论是归档导入、定时任务还是数据管道,一次性送入多份 PDF、DOCX、HTML 是常态。
extract_batch接口正是为此设计:它接受多个输入(每个输入可以是一段原始字节bytes,也可以是一个本地路径 /file://URI / HTTP(S) URL),返回统一的结果信封。而本篇重点的 contract 场景api_extract_batch_bytes_with_config则进一步演示了一个关键能力:
批量提取时,每个输入可以携带自己独立的
config,用于覆盖全局提取配置中的对应项。
典型用途包括:同一批文档中,A 文件希望输出 Markdown、B 文件希望输出纯文本,或者某份扫描件需要单独开启 OCR,其余文件保持默认——不需要拆成多次调用,一次ExtractBatch即可完成差异化处理。
二、核心 API 一览:三个关键类型
2.1 ExtractInput:一条输入描述一份文档
ExtractInput在 Go 绑定中定义于 packages/go/binding.go:
| 字段 | JSON 字段名 | 类型 | 语义 |
|---|---|---|---|
Kind | kind | *ExtractInputKind | 输入来源类型:bytes时要求提供Bytes;uri时要求提供URI |
Bytes | bytes | []byte | kind = "bytes"时的原始字节内容 |
URI | uri | *string | kind = "uri"时的本地路径、file://URI 或 HTTP(S) URL |
MimeType | mime_type | *string | MIME 类型提示,辅助识别 |
Filename | filename | *string | 文件名提示,用于 MIME 推断与元数据 |
Config | config | *FileExtractionConfig | 该输入的独立提取配置覆盖(per-input config) |
注意源码注释中的约束:bytes与uri二选一,Kind决定哪个字段生效。
2.2 FileExtractionConfig:per-input 覆盖项
FileExtractionConfig(packages/go/binding.go)不是一份全新的配置,而是一组覆盖项(override):字段为nil时沿用批量全局配置,设置后仅对该文件生效。字段覆盖面很广,包括:
- 输出相关:
ResultFormat、OutputFormat、IncludeDocumentStructure - OCR 相关:
Ocr、ForceOcr、OcrStrategy、ForceOcrPages、DisableOcr - 内容相关:
Chunking、ContentFilter、Images、Keywords、Layout - 增强能力:
StructuredExtraction、Summarization、Translation、Ner、Redaction、Captioning、QrCodes - 资源控制:
TimeoutSecs(该文件超时秒数,超时的文件产生错误结果但不影响批内其他文件)
本合约示例使用的正是其中最常见的一个:output_format: "markdown"。
2.3 ExtractBatch 的返回值:ExtractionResult
ExtractBatch返回*ExtractionResult(packages/go/binding.go),其核心字段:
Results []ExtractedDocument:按输入顺序排列的提取结果;- 非致命错误(per-input errors)也随信封返回,单个失败不会使整批失败。
每份ExtractedDocument(packages/go/binding.go)包含:Content(提取文本)、MimeType(源文档 MIME,如application/pdf)、Metadata(作者、标题、日期及格式相关字段)、Counts(页数/表格数/图片数等结构计数)、DetectedLanguages(ISO 639-1 语言码)等。
三、带 per-input 配置的完整 Go 示例
以下代码来自 contract 片段文档本身(api_extract_batch_bytes_with_config.md),它演示:把一段 PDF 字节送入批量提取,在该输入的config中指定output_format: "markdown",全局配置保持默认空值,最后打印结果信封中的 MIME、内容与元数据中的输出格式。
package main import ( "encoding/json" "fmt" xberg "github.com/xberg-io/xberg/packages/go" ) func main() { var inputs []xberg.ExtractInput if err := json.Unmarshal([]byte(`[{"bytes":"pdf/fake_memo.pdf","config":{"output_format":"markdown"},"filename":"fake_memo.pdf","kind":"bytes"}]`), &inputs); err != nil { panic(fmt.Sprintf("config parse failed: %v", err)) } config := xberg.ExtractionConfig{} result, err := xberg.ExtractBatch(inputs, config) if err != nil { panic(err) } fmt.Printf("%+v\n", result.Results[0].MimeType) fmt.Printf("%+v\n", result.Results[0].Content) fmt.Printf("%+v\n", result.Results[0].Metadata.OutputFormat) }四、逐行拆解:这段代码做了什么
- 构造输入切片:通过
json.Unmarshal把内联 JSON 反序列化为[]xberg.ExtractInput。这里的 JSON 对象含四个键:"kind":"bytes":声明这是一段原始字节输入;"bytes":...:实际字节内容(片段中为可读性以路径字符串pdf/fake_memo.pdf占位,真实合约 fixture 中是一组整数数组,见下文第六节);"filename":"fake_memo.pdf":文件名提示,供 MIME 推断与结果元数据使用;"config":{"output_format":"markdown"}:per-input 配置——仅对这一个输入生效的FileExtractionConfig,这里覆盖输出格式为 Markdown。
- 全局配置留空:
config := xberg.ExtractionConfig{}表示不设置任何全局选项,全部使用默认值;per-input 的output_format依然独立生效。 - 调用批量提取:
xberg.ExtractBatch(inputs, config),一次调用处理整批输入。 - 读取结果:
result.Results[0]是第一个(也是唯一一个)输入的提取结果:MimeType应识别为application/pdf;Content为该 PDF 提取出的正文文本;Metadata.OutputFormat反映本次生效的输出格式markdown。
错误处理上,json.Unmarshal失败(JSON 解析)与ExtractBatch失败(调用级错误)都通过 panic 暴露,便于在 contract 环境中快速暴露问题;生产代码建议改为返回 error。
五、从 fixture 合约看断言与验收标准
同一个场景在合约 fixture 中有机器可读的定义:fixtures/contract/api_extract_batch_bytes_with_config.json。它声明了call: "extract_batch"、标签["contract", "api", "batch", "input_config"],并以三条断言约束了正确行为:
| 断言类型 | 字段路径 | 期望值 | 含义 |
|---|---|---|---|
equals | results[0].mime_type | application/pdf | 输入被正确识别为 PDF |
min_length | results[0].content | 10 | 提取出的文本内容非空且有一定长度 |
equals | results[0].metadata.output_format | markdown | per-input config 的output_format确实生效并被记录进元数据 |
第三条断言正是本合约的灵魂:它验证了 per-input 配置不仅影响输出内容,还会在结果元数据中留下可追踪的痕迹——这对后续按文件核对"实际用了什么配置"非常有用。fixture 同时以presentation.files指明pdf/fake_memo.pdf对应输入字节,说明该测试依赖仓库中真实的 PDF 测试样本。
六、底层实现:ExtractBatch 的 FFI 调用链
ExtractBatch的 Go 实现位于 packages/go/binding.go。从源码看,调用过程如下:
- 锁定线程:
runtime.LockOSThread()确保后续 CGO 调用始终在同一 OS 线程上执行,defer runtime.UnlockOSThread()在返回时解锁; - 序列化输入:
json.Marshal(inputs)把[]ExtractInput编码为 Rustserde_json可接受的 JSON; - 构造 C 配置对象:
json.Marshal(config)后调用C.xberg_extraction_config_from_json把 JSON 转为 FFI 层配置指针(失败时通过C.xberg_last_error_context取错误上下文); - 执行提取:调用
C.xberg_extract_batch(cInputs, cConfig),若lastError()非空则释放指针并返回错误; - 取回结果:
C.xberg_extraction_result_to_json把 Rust 侧结果转回 JSON,再由json.Unmarshal填充ExtractionResult并返回。
整个 Go 侧只是"编解码壳",真正的解析、MIME 识别、格式转换与元数据生成都在 Rust 核心完成,这保证了各语言绑定行为一致。
6.1 bytes 字段的 JSON 序列化细节
源码中ExtractInput自定义了MarshalJSON(packages/go/binding.go),把[]byte字段渲染为整数数组([]int)而非 Go 默认的 base64 字符串——注释明确指出这是为了匹配 Rust serdeVec<u8>反序列化器期望的格式。这也解释了为什么合约 fixture 中bytes是一长串形如37, 80, 68, 70, 45, ...的整数:37,80,68,70,45正是 ASCII 码%PDF-(PDF 文件头)。
6.2 空输入与空配置的归一化
两个边界情况在实现中被显式处理(packages/go/binding.go):
- nil 输入切片:Go 的 nil 切片
json.Marshal后是"null",而 Rust 侧from_str只接受"[]",因此代码把"null"归一化为"[]",让"空批量"(空结果)与"空输入"语义一致; - 零值配置:空
ExtractionConfig{}序列化为"{}"已是合法形式;若出现"null"则替换为"{}",Rust 侧构造默认实例——所有字段均可选且带默认值,这与"未设置项使用默认"的语义等价。
这两处细节解释了为什么示例中config := xberg.ExtractionConfig{}可以直接使用:空配置会被安全地构造为默认实例,per-input 覆盖照常生效。
七、OutputFormat 枚举与元数据中的 output_format
示例中output_format的取值来自OutputFormat枚举(packages/go/binding.go):
| Go 常量 | 序列化值 | 含义 |
|---|---|---|
OutputFormatPlain | plain | 纯文本内容(默认) |
OutputFormatMarkdown | markdown | Markdown 格式 |
OutputFormatDjot | djot | djot 标记格式 |
OutputFormatHTML | html | HTML 格式 |
OutputFormatJSON | json | 以标题驱动的 JSON 树结构 |
OutputFormatDocTags | doctags | Docling DocTags 格式(表格渲染为 OTSL) |
在批量提取中,全局ExtractionConfig.OutputFormat与 per-inputFileExtractionConfig.OutputFormat是两条独立的设置路径(packages/go/binding.go 与 packages/go/binding.go):per-input 设置优先覆盖全局。fixture 的第三条断言确认,该值最终会出现在results[0].metadata.output_format中,便于结果消费方按文件回溯实际输出格式。
八、实践建议与验证路径
- 差异化配置的正确姿势:把"整批统一的设置"放进全局
ExtractionConfig,把"仅某文件需要的设置"放进该输入的config;FileExtractionConfig中留空(nil)的字段自动回落到全局默认。 - 批量容错:
ExtractionResult信封携带 per-input 错误,单个文件失败不会拖垮整批;如需严格超时控制,可设置全局ExtractionConfig的默认超时(源码注释说明默认 600 秒,见 packages/go/binding.go),或对个别文件使用FileExtractionConfig.TimeoutSecs覆盖。 - 如何验证自己的调用:仓库已提供同场景的 Go e2e 测试作为参照——e2e/go/batch_test.go 中覆盖了
Test_ExtractBatchBytesHappy(混合输入 happy path)、Test_ExtractBatchEmptyInputs(空批量返回空结果)、Test_ExtractBatchUriAllMissing(URI 全部缺失)等批量用例;更早的契约级验证可运行合约 fixture api_extract_batch_bytes_with_config.json 对应的断言。整个 snippet 目录由 alef 自动生成(alef e2e generate),合约与语言片段保持同步,可作为各绑定行为一致性的权威参照。
小结
批量字节提取 + per-input 配置是 xberg 处理异构文档批量导入时的核心组合拳:一次ExtractBatch调用即可混合处理字节与 URI 输入,并通过ExtractInput.Config对单个文件做输出格式、OCR、分块等差异化覆盖,结果以统一信封返回且错误隔离。理解ExtractInput/FileExtractionConfig/ExtractionResult三者关系,并借助 fixture 断言与 e2e 测试验证行为,就能在 Go 服务中稳定落地多格式、多策略的文档提取管线。
- 后端
- 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.
相关推荐
xberg Dart 绑定批量字节提取实战:使用 extractBatch 与 per-input 配置提取多格式文档
xberg Dart 绑定批量字节提取实战:使用 extractBatch 与 per input 配置提取多格式文档 导读 xberg 的 Dart 绑定将
后端AI 应用NLPXberg C FFI 批量 URI 提取实战:extract_batch 与 per-input 配置详解
Xberg C FFI 批量 URI 提取实战:extract_batch 与 per input 配置详解 本文围绕 Xberg C FFI 契约测试片段 a
后端AI 应用NLPxberg Dart 绑定批量 URI 提取实战:基于 extract_batch 与 per-input 配置逐文件控制输出格式
xberg Dart 绑定批量 URI 提取实战:基于 extract_batch 与 per input 配置逐文件控制输出格式 本篇指南讲解如何在 xber
后端AI 应用NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考