结构化提取

JSON 里为什么值得多存页号和原文片段

提取结果只有一个 `amount: 1200`,审校员仍得重新翻完整份文档。多保存页号和短原文片段,往往比再加一个小数位的“置信度”更有用:它让错误可以被定位,也让后续纠正有据可查。

阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。 提取结果只有一个 amount: 1200 ,审校员仍得重新翻完整份文档。多保存页号和短原文片段,往往比再加一个小数位的“置信度”更有用:它让错误可以被定位,也让后续纠正有据可查。 证据对象应该能带人回到原文 下面采用从一开始的页码。若你的解析库从零开始,要在边界处转换,并在协议中注明。片段只保留与字段相关的短句,避免把整页敏感信息复制进日志、搜索索引或通知消息。 先校验形状,再校验对应关系 from jsonschema import Draft202012Validator schema = { "type": "object", "required": ["value", "evidence"], "additionalProperties": False, "properties": { "value": {"type": "string"}, "evidence": {"type": "object", "additionalProperties": False, "required": ["page", "quote"], "properties": {"page": {"type": "integer", "minimum": 1}, "quote": {"type": "string", "minLength": 1}}} } } v = Draft202012Validator(schema) pages = ["Invoice total: USD 1200."] record = {"value": "1200", "evidence": {"page": 1, "quote": "USD 1200"}} assert v.is_valid(record) def quote_exists(r): if not v.is_valid(r): return False e = r["evidence"] return e["page"] <= len(pages) and e["quote"] in pages[e["page"] - 1] assert quote_exists(record) fake = {"value": "9999", "evidence": {"page": 1, "quote": "USD 9999"}} assert v.is_valid(fake) assert not quote_exists(fake) assert not quote_exists({"value": "1", "evidence": {"page": 9, "quote": "x"}}) 这个合成例子故意构造了一条结构合法、证据不存在的记录。它说明 Schema 和来源比对不能互相替代。真实 PDF 可能存在断词、连字和空白差异,子串匹配只是最小演示,不能直接宣称为完整证据验证算法。 证据也要绑定文件版本 保存项 可以解决 不能保证 文件内容哈希 识别对应版本 上传者拥有文件权限 页号 缩小查找范围 页面没有重排 原文片段 快速核对文本 字段语义必然正确 坐标及坐标系 定位页面区域 OCR 结果已经准确 原文存在也可能引用错位置 一份文件里可能有多次出现的相同金额。即使片段存在,也要判断它是不是合计、税额或上期余额。进一步的验收可以检查字段标签、所在表格和邻近上下文;遇到多个候选,不应只拿第一个。 双语审校最需要可追溯性 把这类来源记录与 OmniDoc(产品入口) 的双语核对一起使用,审校可以从译文数字跳回源页确认含义。价值不在于让输出看起来更复杂,而在于让每一次纠正都能解释清楚,减少来回查找原件的时间。 参考: JSON Schema 对象结构 。 - 1 -
更新于 2026-10-08