- 后端
- 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 文档智能提取管线中的一个后处理能力:启用后,每次ExtractAsync调用返回的文档结果都会附带检测到的语言编码列表,便于下游按语言路由、过滤或标注内容。本篇以 C# 绑定为切入点,完整讲解LanguageDetectionConfig的三个配置字段及其默认值、单语言与多语言两种检测模式的行为差异,并结合仓库中 Rust 核心源码与端到端测试,说明min_confidence阈值、200 字符分块机制与结果字段的真实含义。
语言检测在 xberg 中的定位
xberg 的核心提取管线由 Rust 实现,语言检测是其中的一个可选后处理器(post-processor)。从源码结构看,语言检测模块 基于whatlang)。
在管线中的实际挂载点是一个名为language-detection的后处理器LanguageDetector(见 processor.rs)。它运行在ProcessingStage::Early阶段,只有当配置中携带了language_detection块(should_process判断config.language_detection.is_some())时才会执行;执行结果写入ExtractedDocument的两个字段:detected_languages(ISO 编码列表)与detected_language_confidences(结构化置信度明细)。也就是说:不配置language_detection,提取结果中就不会有语言信息。
LanguageDetectionConfig 字段与默认值
LanguageDetectionConfig在 Rust 侧定义于 core/config/extraction/types.rs,C# 侧对应的强类型 record 位于 LanguageDetectionConfig.cs。两个语言版本的字段完全一一对应:
| 字段(C#) | 序列化名 | 类型 | 默认值 | 含义 |
|---|---|---|---|---|
Enabled | enabled | bool | true | 是否启用语言检测 |
MinConfidence | min_confidence | double | 0.8 | 最低置信度阈值,取值范围0.0–1.0 |
DetectMultiple | detect_multiple | bool | false | 是否检测文档中的多种语言 |
三个要点需要特别注意:
Enabled默认就是true,因此在 C# 中new LanguageDetectionConfig()即等价于一个开启检测、单语言模式、阈值为 0.8 的配置。真正"关闭语言检测"的方式是不设置ExtractionConfig.LanguageDetection(保持null),而不是把Enabled设为false——虽然两种方式都能让结果不带语言字段,但null意味着后处理器根本不会进入处理流程。MinConfidence默认 0.8:这是 whatlang 对整篇文档做一次检测时通常足够可靠的置信度门槛。调低(如 0.3、0.5)会接受更多"模棱两可"的判定,调高(如 0.99)则只有几乎无歧义的语言才会被返回。DetectMultiple默认false:只返回一个主要语言;为true时走分块多语言检测路径(详见下文)。
C# 最小可运行示例:检测并读取 ISO 639-3 编码
关联文档给出的示例是开启检测、单语言模式、阈值为 0.5,从远程text/plain文档提取文本并打印检测结果。下面这段代码保留了原示例的完整逻辑,并补全了命名空间与必要的类型引用,可直接复制运行:
using System; using System.Text.Json; using Xberg; var ConfigOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var result = await XbergConverter.ExtractAsync( new ExtractInput { Kind = JsonSerializer.Deserialize<ExtractInputKind>("\"uri\"", ConfigOptions)!, MimeType = "text/plain", Uri = "https://example.com/text/report.txt" }, new ExtractionConfig { LanguageDetection = new LanguageDetectionConfig { DetectMultiple = false, Enabled = true, MinConfidence = 0.5d } }); Console.WriteLine(result.Results[0].DetectedLanguages);几点说明:
ExtractInput.Kind需要反序列化为ExtractInputKind枚举,这里通过JsonSerializer.Deserialize<ExtractInputKind>("\"uri\"", ...)把字符串"uri"转成枚举值;PropertyNameCaseInsensitive保证 JSON 字段名大小写不敏感。- 只要文档文本能被 whatlang 以不低于
MinConfidence的置信度识别,DetectedLanguages就是一个非空列表。例如英文文档通常返回["eng"](ISO 639-3 编码)。 - 该示例对应的端到端契约测试是 ContractTests.cs 中的
Test_LanguageDetectionConfig:它以同样的参数(text/plain、min_confidence: 0.5)断言result.Results[0].DetectedLanguages![0] == "eng",可用于验证绑定行为。
多语言模式:DetectMultiple 与分块检测
当文档包含多种语言(如混合中英文的技术手册、多语言 UI 文案、国际新闻报道)时,把DetectMultiple设为true会启用分块检测。关联的多语言示例(见 language_detection_multilingual.md)展示了完整写法:
using System; using System.Text.Json; using Xberg; var ConfigOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var result = await XbergConverter.ExtractAsync( new ExtractInput { Kind = JsonSerializer.Deserialize<ExtractInputKind>("\"uri\"", ConfigOptions)!, MimeType = "text/markdown", Uri = "https://example.com/markdown/comprehensive.md" }, new ExtractionConfig { LanguageDetection = new LanguageDetectionConfig { DetectMultiple = true, Enabled = true, MinConfidence = 0.3d } }); Console.WriteLine(result.Results[0].DetectedLanguages);对应的端到端测试Test_LanguageDetectionMultilingual(ContractTests.cs)使用text/markdown源与min_confidence: 0.3,断言返回的语言列表至少包含一个元素。
底层实现:200 字符分块与聚合排序
多语言模式的内部逻辑可以在 mod.rs 中完整看到,其核心步骤为:
- 按字符分块:
CHUNK_SIZE = 200(模块内pub(crate)常量,见 mod.rs),把提取出的全文按每 200 个字符切成若干块。注意是按字符(char)切分,天然兼容 CJK 等多字节文本。 - 逐块检测并过滤:对每个块调用 whatlang 的
detect,仅当info.confidence() >= min_confidence时才计入该语言的统计(LangAggregate累加块数与置信度之和)。 - 回退逻辑:如果没有任何一个块通过阈值(
lang_aggregates.is_empty()),则自动回退到单语言模式对全文再做一次检测。 - 排序输出:按"命中块数"降序排列,块数相同按 ISO 639-3 编码字典序打破平局,保证结果确定性。
- 置信度聚合:每个语言返回的
confidence是它所有命中块的 whatlang 置信度平均值,proportion是命中块数占总块数的比例。
为什么高阈值会"压掉"多语言结果
官方指南特别提醒:分块置信度通常低于整篇文档置信度。一段 200 字符的文本比整篇文档更容易让 whatlang 犹豫,因此若把min_confidence设得过高(例如维持默认 0.8),大量真实语言块会被阈值过滤,可能导致多语言模式下只返回极少数语言甚至触发回退。这正是多语言示例把阈值降到 0.3 的原因。反之,若你只关心"显著的语言信号",可以调高阈值过滤掉偶发出现的噪声语言。
结果字段:DetectedLanguages 与 DetectedLanguageConfidences
检测结果写入ExtractedDocument,C# 侧定义于 ExtractedDocument.cs:
| C# 属性 | 类型 | 说明 |
|---|---|---|
DetectedLanguages | List<string>? | ISO 639-3 语言编码列表;检测禁用、文本为空或无语言达到阈值时为null |
DetectedLanguageConfidences | List<LanguageConfidence>? | 每个语言的结构化明细,与DetectedLanguages顺序一一对应 |
其中LanguageConfidence携带四个字段(Rust 侧定义见 types/extraction.rs):
| 字段 | 含义 |
|---|---|
Language | ISO 639-3 编码,如"eng"、"spa"、"cmn" |
Confidence | 置信度[0.0, 1.0]。单语言模式为 whatlang 对全文的Info::confidence();多语言模式为该语言所有命中块的置信度均值 |
Proportion | 该语言占分析内容的比例[0.0, 1.0]。单语言模式恒为1.0;多语言模式为命中块数 / 总块数 |
Script | 检出的书写系统,如"Latin"、"Cyrillic" |
Reliable | 是否可靠。单语言模式沿用 whatlang 内部 0.9 可靠阈值;多语言模式对聚合后的均值置信度应用同一 0.9 阈值(AGGREGATE_RELIABLE_THRESHOLD,见 mod.rs) |
ISO 639-3 编码由lang_to_iso639_3映射生成(mod.rs),例如Lang::Eng => "eng"。需要留意:C# 绑定中DetectedLanguages的注释写的是 "ISO 639-1 language codes",但实际映射逻辑输出的是 ISO 639-3 三位编码,与官方指南表述一致,属绑定注释的遗留偏差,编程时应按 ISO 639-3 处理返回值。
配置注入方式:全局配置与按文件覆盖
LanguageDetectionConfig有两个注入位置:
- 全局配置:挂在
ExtractionConfig.LanguageDetection上(C# 见 ExtractionConfig.cs),作用于ExtractAsync的整次调用。 - 按文件覆盖:挂在
FileExtractionConfig.LanguageDetection上(FileExtractionConfig.cs),用于批量提取时对单个文件单独覆盖语言检测参数——例如批量中多数文件是单语言、个别文件需要开启多语言检测。
在 Rust 侧,ExtractionConfig的language_detection字段默认None表示不检测(见 配置参考);同一配置参考文档中也确认FileExtractionConfig.language_detection支持按文件覆盖(configuration.md)。
调参与边界行为速查
- 完全不想要语言检测:不要给
ExtractionConfig.LanguageDetection赋值,后处理器should_process返回false,零开销跳过。 - 只要主要语言:
DetectMultiple = false(默认)。低于min_confidence时整个检测被丢弃,DetectedLanguages为null。 - 要全部语言:
DetectMultiple = true,并适当降低min_confidence(0.3–0.5 是端到端测试采用的取值)。 - 空文本或纯无字母内容:
detect_language_details对text.trim().is_empty()直接返回None(mod.rs);whatlang 无法分类的块(无字母内容)不计入任何语言。 - 性能提示:
LanguageDetector::estimated_duration_ms按text_length / 1024估算耗时(processor.rs),文本越长耗时越长;多语言模式会逐块调用 whatlang,开销随块数线性增长。
结合文档与测试进一步验证
- 官方语言检测指南:语言检测指南 完整描述了两种模式与阈值行为,是本文所有参数语义的第一手依据。
- 全量配置参考:configuration.md 收录了
LanguageDetectionConfig的字段表格与ExtractionConfig.language_detection的默认值说明。 - C# API 参考:api-csharp.md 提供
XbergConverter.ExtractAsync的完整签名(输入ExtractInput+ExtractionConfig)。 - 端到端契约测试:ContractTests.cs 覆盖单语言与多语言两条路径,可视为绑定正确性的验证基线。
- 契约 fixtures:language_detection_config.json 与 language_detection_multilingual.json 提供了 mock 服务器侧对应的输入样例。
- Rust 单元测试:mod.rs 内的
#[cfg(test)]模块包含大量检测用例(如eng/spa/cmn断言、多语言排序、min_confidence回归测试 GH#1223 等),适合深入理解边界行为。
语言检测是文档智能管线中成本极低、收益直接的一环:一次配置即可让每次提取自动携带 ISO 639-3 编码与置信度明细,为下游的多语言路由、语种过滤、机器翻译预处理等场景提供可靠输入。按本文给出的字段语义与调参建议,你可以在 C# 应用中快速落地单语言与多语言两种检测方案。
- 后端
- 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 API 配置、ISO 639-3 输出与底层分块检测原理
xberg 多语言文档语言检测实战:C API 配置、ISO 639 3 输出与底层分块检测原理 本文围绕 xberg 仓库中 C 语言绑定的多语言检测示例(
后端AI 应用NLPxberg 语言检测实战:通过 C FFI 开启 Language Detection 并读取 ISO 639-3 结果
xberg 语言检测实战:通过 C FFI 开启 Language Detection 并读取 ISO 639 3 结果 在 xberg 的多格式文档智能管线中
后端AI 应用NLPxberg C FFI 多语言 OCR 配置实战:以 Tesseract 语言列表识别多语种文档
xberg C FFI 多语言 OCR 配置实战:以 Tesseract 语言列表识别多语种文档 本篇技术文章聚焦 xberg 文档智能库的 C FFI 接口中
后端AI 应用NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考