- 后端
- 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 的 C 绑定(xberg.h/ 生成的 ALEF 接口),讲解如何把“可复用结果缓存”(use_cache)与“质量后处理”(enable_quality_processing)放入同一次抽取配置中一并生效。读完本文,你将掌握这两个开关的默认值、底层执行链路(缓存命中判断、quality_score 计算),并能直接照抄 C 代码片段在自己的项目中启用“缓存 + 质量评分”的组合抽取。
关联文档:config_cache_quality.md,对应契约测试:config_cache_quality.json。
场景速览:一次配置同时启用缓存与质量评分
在 xberg 中,配置通过 JSON 字符串传入 C API。下面的代码一次性开启了两个开关:enable_quality_processing(质量后处理)与use_cache(结果缓存),然后对同一个 URI 执行抽取:
#include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "xberg.h" int main(void) { XBERGAlefHandle input_handle = xberg_extract_input_from_json("{\"kind\":\"uri\",\"uri\":\"https://example.com/pdf/fake_memo.pdf\"}"); XBERGAlefHandle config_handle = xberg_extraction_config_from_json("{\"enable_quality_processing\":true,\"use_cache\":true}"); XBERGAlefHandle result = xberg_extract(input_handle, config_handle); xberg_extract_input_free(input_handle); xberg_extraction_config_free(config_handle); xberg_extraction_result_free(result); return EXIT_SUCCESS; }xberg_extract_input_from_json:将 JSON 形式的输入描述(这里是一个uri类型的输入)转换为内部句柄;xberg_extraction_config_from_json:把 JSON 配置反序列化为ExtractionConfig;xberg_extract:执行抽取主流程,返回结果句柄;- 三个
*_free调用负责释放输入、配置与结果句柄,避免内存泄漏。
三个句柄类型均来自生成的 C 头文件xberg.h(FFI 仓库见 crates/xberg-ffi/include/xberg.h)。该片段与契约测试的配置完全一致,实测会返回quality_score字段(见 config_cache_quality.json)。
两个开关的默认值与底层字段
这两个开关在 xberg 的ExtractionConfig结构中均有对应的布尔字段,定义于 core.rs:
/// Enable caching of extraction results #[serde(default = "default_true")] pub use_cache: bool, /// Enable quality post-processing #[serde(default = "default_true")] pub enable_quality_processing: bool,需要注意:
- 默认值都是
true(见impl Default中的use_cache: true, enable_quality_processing: true,core.rs)。也就是说,即使你的 JSON 配置只写{"use_cache": true},质量后处理默认也是开着的;反过来只开质量开关,缓存也默认生效。 - 二者在 JSON 中同时出现互不冲突:缓存决定“结果是否可复用”,质量后处理决定“结果是否附带质量评分”,属于抽取流水线中两个不同阶段(缓存发生在提取器执行前后,质量评分发生在后处理阶段)。
serde(deny_unknown_fields)表明配置结构是严格校验的,未知字段会被拒绝,所以拼写错误会直接导致xberg_extraction_config_from_json解析失败。
同样的配置组合在契约测试中也有体现:config_cache_quality.json 的config段设置了"use_cache": true, "enable_quality_processing": true,并断言返回结果results[0].quality_score落在[0.0, 1.0]区间内(assertions)。
use_cache:缓存键、命中判定与失效
缓存功能的实际执行位于 file.rs 的extract_file_with_extractor:
if !config.use_cache || config.cache_ttl_secs == Some(0) { return extract_file_uncached(path, mime_type, config).await; } let content_hash = crate::cache::blake3_hash_file(path)?; let config_hash = hash_extraction_config(config, mime_type); let cache_key = format!("{content_hash}_{config_hash}");几个关键点:
- 关闭方式:
use_cache = false或cache_ttl_secs = 0都会强制走无缓存路径; - 缓存键构成:
blake3内容哈希 + 配置哈希(hash_extraction_config(config, mime_type))+ MIME 类型,任何一项变化都会导致键不同,从而避免脏命中; - 命中与回填:命中后直接
rmp_serde::from_slice反序列化返回缓存结果(L302-L308);未命中则执行真实抽取,再把结果rmp_serde::to_vec序列化后写入缓存(L310-L316),因此返回给调用方的始终是完整、结构一致的ExtractedDocument; - 命名空间与 TTL:
cache_namespace与cache_ttl_secs两个可选字段(core.rs)分别控制缓存分区隔离与过期时间,适合多租户或对时效敏感的场景。
配置组合对缓存键的影响
同一个文件、同一个enable_quality_processing开关组合,才会命中同一条缓存。由于use_cache、cache_ttl_secs、cache_namespace属于“缓存控制字段”,在计算配置哈希前会被归一化剔除(见 file.rs),而质量开关属于参与哈希的配置,因此本文示例中“开质量 + 开缓存”与“关质量 + 开缓存”会使用不同的缓存键,互不污染。
enable_quality_processing:质量评分的计算与语义
质量后处理由QualityProcessor插件实现,位于 quality_processor.rs。它是一个PostProcessor,运行在Early处理阶段,当config.enable_quality_processing为true时计算质量分,并写入ExtractedDocument::quality_score(L22-L27)。
quality_score 描述的是什么
源码注释明确指出(L29-L31):
The score describes retained text, not extraction completeness or recall. Callers must inspect
ExtractedDocument::processing_warningsseparately.
即quality_score衡量的是保留文本的整洁度/可读性,不是抽取完整性或召回率。需要判断“是否漏掉了某些内容”时,应单独检查processing_warnings。契约测试也印证了这一点:config_cache_quality.json只断言分数在[0.0, 1.0]之间(L52-L59),并未把它解释为“抽取质量”的全面指标。
OCR 置信度对分数封顶的影响
一个值得注意的实现细节:当 OCR 已运行且识别出足够多的词(达到MIN_OCR_WORDS_FOR_CONFIDENCE_FLOOR阈值)时,质量分会被单词数加权的 OCR 平均置信度封顶(issue #1669)。这是因为纯文本形状启发式只读保留文本本身——一页 OCR 仅以 81% 置信度识别的文本,看起来可能“形状干净”而得 1.0 分。该均值通过ConfidenceSignals::ocr_confidence_from_elements/ocr_confidence_from_pages折入,与ExtractionConfidence::ocr_aggregate使用同一套权重,避免两处漂移(issue #1694)。这意味着在“扫描件 + OCR + 质量评分”的组合下,质量分会诚实反映识别置信度,而不会虚高。
与其他配置的配合
质量开关还可以与result_format、content_filter(文档“家具”过滤)、postprocessor等字段协同。在 engine/mod.rs 与 merge.rs 中,enable_quality_processing与use_cache均参与配置合并与覆盖解析,Rust 测试也验证了默认值、显式覆盖等场景(见 mod.rs 的test_default_config:默认两者均为true)。
完整可运行的调用流程总结
- 构造输入句柄:
xberg_extract_input_from_json("{\"kind\":\"uri\",\"uri\":\"https://example.com/pdf/fake_memo.pdf\"}"); - 构造配置句柄:
xberg_extraction_config_from_json("{\"enable_quality_processing\":true,\"use_cache\":true}"); - 执行抽取:
xberg_extract(input_handle, config_handle); - 按需读取
results[0].quality_score(0.0~1.0); - 依次释放三个句柄。
实战注意事项
- 首次执行时缓存未命中,会执行完整抽取并回填;第二次对同一文件、同一配置执行时命中缓存,返回速度显著提升,且
quality_score不会丢失(结果以序列化形式完整保存); - 若想验证缓存是否生效,可临时将
use_cache设为false对比耗时; - 若文件内容变化(内容哈希改变)或抽取配置变化(配置哈希改变),缓存键自动失效,无需手动清理;
- 对时效性敏感的数据(如定时抓取的网页),建议配合
cache_ttl_secs控制缓存有效期。
延伸阅读
- 配置结构定义:crates/xberg/src/core/config/extraction/core.rs
- 缓存执行链路:crates/xberg/src/core/extractor/file.rs
- 质量处理器插件:crates/xberg/src/text/quality_processor.rs
- 契约测试与断言:fixtures/contract/config_cache_quality.json
- C 绑定头文件:crates/xberg-ffi/include/xberg.h
- 后端
- 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 OCR 流水线深度解析:后端执行、结果缓存与跨后端质量不变量
Xberg OCR 流水线深度解析:后端执行、结果缓存与跨后端质量不变量 Xberg 的 OCR 能力覆盖图像、PDF 扫描件到多后端的完整链路,其设计核心是「
后端AI 应用NLPxberg C 绑定实战:extract_batch 批量提取中的安全限制与 max_content_size 尺寸上限
xberg C 绑定实战:extract_batch 批量提取中的安全限制与 max_content_size 尺寸上限 本篇基于 xberg 仓库中自动生成的
后端AI 应用NLPxberg C 绑定实战:用 VLM 视觉大模型(liter-llm)配置 OCR 文本提取
xberg C 绑定实战:用 VLM 视觉大模型(liter llm)配置 OCR 文本提取 本文以 xberg 的 C FFI 接口为主线,讲解如何配置 VL
后端AI 应用NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考