- 后端
- 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.
批量文档提取是生产环境中最常见的高频操作之一:把一批文件路径或 URL 交给提取引擎,一次调用拿到全部结构化结果。当其中某个 URI 指向不存在的文件时,正确的做法不是让整个批次崩溃,而是把失败折叠进结果统计里。本文以 xberg 仓库中自动生成的 Go 代码片段 extract_batch_uri_not_found.md 为骨架,讲解xberg.ExtractBatch在 Go 绑定中的调用方式、per-input 错误语义,以及如何通过Summary统计批量提取的健康状况。
场景与核心结论:URI 不存在 ≠ 调用失败
先看结论:在 xberg 的 Go 绑定中,向ExtractBatch传入一个指向不存在文件的 URI,顶层调用不会返回 Go error,而是返回一个完整的ExtractionResult,其中:
Summary.Results == 0:本次没有任何成功产出的文档;Summary.Errors == 1:有 1 个 per-input 错误被记录;- 具体错误详情进入
result.Errors列表。
这一行为不是猜测,而是由仓库中的 fixture 断言明确锁定的。extract_batch_uri_not_found.json 中定义了三条断言:
"assertions": [ { "type": "not_error" }, { "type": "equals", "field": "summary.results", "value": 0 }, { "type": "equals", "field": "summary.errors", "value": 1 } ]也就是说:单条 URI 失败是"非致命"(non-fatal)的,它被当作数据面的统计项处理,而不是控制面的异常。这种设计让批量任务天然具备容错能力——一批 100 个 URL 里坏掉几个,其余照常出结果。
完整示例:传入一个不存在的 URI
原文档给出的 Go 代码是自包含、可直接编译运行的,完整继承如下:
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(`[{"kind":"uri","uri":"/nonexistent/a.pdf"}]`), &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.Summary.Results) fmt.Printf("%+v\n", result.Summary.Errors) }关键点拆解:
- 输入构造:通过 JSON 反序列化构造
[]xberg.ExtractInput。kind: "uri"表示这是一个 URI 输入,uri字段是目标地址。注意示例中用的是本地文件系统路径/nonexistent/a.pdf——按照 binding.go 中ExtractInput的字段注释,uri可以承载三类地址:本地路径、file://URI 或 HTTP(S) URL。 - 配置留空:
xberg.ExtractionConfig{}使用全默认配置,适合快速验证。 - 错误处理分层:
err != nil只对应顶层调用失败(如 FFI 异常、配置解析失败);单个 URI 不存在不会走到这里,而是体现在result.Summary的计数里。 - 只关心统计:示例只打印
Summary.Results与Summary.Errors两个计数,这是批量任务的典型观察点。
底层原理:Go 绑定如何把批次送到 Rust 核心
xberg 的 Go 绑定是 Rust 核心之上的 FFI 封装,ExtractBatch的实现位于 packages/go/binding.go,调用链非常清晰:
json.Marshal(inputs)把[]ExtractInput序列化为 JSON;- 通过
C.CString与C.xberg_extract_batch(cInputs, cConfig)跨 ABI 调用 Rust 侧的批量提取; - Rust 侧返回的
ExtractionResult再以 JSON 形式传回,经json.Unmarshal还原成 Go 结构体。
其中有几个值得注意的实现细节:
- 空切片归一化:Go 的 nil 切片序列化为
null,而空切片序列化为[]。绑定层会在调用前把null替换成[],确保两种"空"以同一种形式穿过 ABI(见 binding.go 的注释)。 - 配置默认值:若
config序列化为null,会被替换为{},语义上等价于 Rust 侧的全默认配置实例。 - 线程锁定:函数首尾调用
runtime.LockOSThread()/runtime.UnlockOSThread(),保证 FFI 调用期间 Go 线程不被调度器迁移,这是 cgo 绑定访问不可重入 C 状态时的标准做法。
结果模型:Summary 是批量任务的状态面板
要正确解读示例输出,需要理解返回值的结构。ExtractionResult定义于 binding.go,包含:
Results:成功提取出的文档列表([]ExtractedDocument),按发现顺序排列;Errors:per-input 的非致命错误列表([]ExtractionErrorItem);Summary:本次操作的聚合统计;CrawlFinalUrls/CrawlRedirectCount/CrawlUniqueNormalizedUrls:URL 抓取与爬取相关的追踪信息。
ExtractionSummary(binding.go)则提供了六个计数:
| 字段 | 含义 |
|---|---|
Inputs | 调用方提交的输入总数 |
Results | 成功产出的提取结果数 |
Errors | per-input 错误数 |
RemoteUrls | 解析为远程 HTTP(S) 的 URI 数 |
PagesCrawled | 被抓取/爬取的 HTML 页面数 |
DocumentsDownloaded | 从 URL 下载并提取的非 HTML 文档数 |
对照本文示例:Inputs == 1(提交了 1 个输入)、Results == 0(没有成功)、Errors == 1(1 个失败)。三条断言恰好验证了Results与Errors的互补关系:失败的输入既不计入Results,也不会让调用本身报错,而是进入Errors明细与计数。
错误语义对照:单失败、全失败与部分失败
把本文场景放进批量错误谱系中观察会更清楚。仓库里同目录下的其他自动生成片段展示了相邻场景:
- extract_batch_uri_all_missing.md:所有 URI 都不存在,
Summary.Errors与输入数相同,调用依然成功返回; - extract_batch_uri_partial_failure.md:一个有效 URI 加一个"下载到无法解析的文档"的 URI,属于部分成功——成功项照常产出,失败项进入
Errors; - extract_batch_uri_basic.md:所有 URI 有效时,
Results与输入数一致,Errors为 0。
由此可以归纳出 xberg 批量提取的错误处理哲学:
- per-input 错误永不升级为顶层 error:只要批次本身能被引擎受理(输入可解析、配置合法、运行期资源正常),无论内部失败多少,
ExtractBatch都会正常返回; - 错误与成功分离统计:
Summary.Results + Summary.Errors == Summary.Inputs(未考虑爬取展开等复杂场景时成立),两个计数即可快速判断批次健康状况; - 顶层 error 保留给真正的异常:配置解析失败、FFI 层错误等,才通过 Go 的
error返回值暴露,示例代码用panic(err)处理这种情况,便于在测试与脚本中第一时间暴露问题。
实战建议
结合上述语义,在生产 Go 服务中使用ExtractBatch时建议:
- 不要用
err != nil判断单条失败:先看Summary.Errors,再看result.Errors明细定位具体失败原因; - 用
Summary.Results / Summary.Inputs计算批次成功率,配合Errors明细做告警与重试决策; - 对关键文档的 URI 做好前置校验:本地路径场景先
os.Stat确认存在,URL 场景注意重定向与下载超时,避免把可预期的失败大量堆进Errors; - 逐条排查
Errors时要区分错误类型:URI 不存在、MIME 不支持、文档损坏等属于不同维度的失败,可结合 fixtures/batch 目录下的其他 fixture(如extract_batch_uri_partial_failure、extract_batch_bytes_invalid_mime)设计对应的测试矩阵。
小结
通过这份自动生成的 Go 片段,可以看到 xberg 批量提取 API 在错误处理上的设计取舍:URI 不存在是数据面问题,不是控制面异常。ExtractBatch会把单个输入的失败折叠进Summary.Errors与Errors明细,同时保持调用本身成功返回,让上层业务可以用简单的统计模型承载复杂的批处理容错逻辑。理解这一语义,是在 Go 中正确使用 xberg 批量能力的第一步。
- 后端
- 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 批量 URI 提取失败处理:ExtractBatch 全缺失输入的错误语义与实战
xberg Go 批量 URI 提取失败处理:ExtractBatch 全缺失输入的错误语义与实战 本文聚焦 xberg 项目 Go 绑定中 ExtractBa
后端AI 应用NLPxberg C FFI 批量 URI 提取错误处理实战:extract_batch 对不存在 URI 的容错语义
xberg C FFI 批量 URI 提取错误处理实战:extract_batch 对不存在 URI 的容错语义 本篇技术指南聚焦 xberg 的 C FFI
后端AI 应用NLPXberg Dart 绑定 extractBatch 实战:unsupported bytes MIME 输入的容错处理与批量提取原理
Xberg Dart 绑定 extractBatch 实战:unsupported bytes MIME 输入的容错处理与批量提取原理 本篇指南聚焦 Xberg
后端AI 应用NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考