结构化提取

提取订单状态时,为什么应该有 unknown

订单状态不在系统预设列表里时,最省事的做法往往是选一个“最像”的值。省下来的判断,可能变成后续流程的错误:原文只是“等待补充资料”,系统却按“已批准”继续走了。

阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。 订单状态不在系统预设列表里时,最省事的做法往往是选一个“最像”的值。省下来的判断,可能变成后续流程的错误:原文只是“等待更多资料”,系统却按“已批准”继续走了。 允许未知,是为了保留事实 unknown 不该成为所有异常的垃圾桶,但它比无依据的确定答案更诚实。本文把业务状态限定为 pending 、 approved 、 rejected 和 unknown ,并保留原文片段。枚举约束控制的是输出词表,不会判断模型选的那个词是否符合原文。 如果业务不接受未知值,可以把任务转交人工,而不是偷偷在字段里选择默认状态。默认值只有在业务协议明确规定时才合理,不能由提取脚本自行创造。 合成状态映射与枚举检查 from jsonschema import Draft202012Validator schema = {"type": "object", "required": ["state", "source_text"], "properties": {"state": {"enum": ["pending", "approved", "rejected", "unknown"]}, "source_text": {"type": "string"}}, "additionalProperties": False} validator = Draft202012Validator(schema) mapping = {"待审核": "pending", "已批准": "approved", "已拒绝": "rejected"} def map_state(text): return {"state": mapping.get(text, "unknown"), "source_text": text} assert map_state("已批准")["state"] == "approved" assert map_state("等待更多资料")["state"] == "unknown" assert not list(validator.iter_errors(map_state("等待更多资料"))) assert list(validator.iter_errors({"state": "probably-approved", "source_text": "?"})) 这里只做明确词组的映射,不处理同义句、否定句和上下文。文本“未批准”不能因为包含“批准”二字就映射成 approved 。若增加模糊匹配,必须补上这类反例,并留住原文证据。 未知值如何进入工作队列 结果 处理策略 需要保留 明确匹配 进入下一层业务校验 来源片段与规则版本 不在映射中 标记 unknown 原文,不自动改写 多种状态冲突 转人工消歧 所有候选与位置 格式不符合 enum 拒绝结果 错误路径与输出版本 状态词表改变时不要静默兼容 新增状态可能意味着下游需要新增分支。简单把旧的 unknown 自动解释成新状态,会改写历史含义。应保留旧记录,明确迁移范围,并检查哪些任务需要重新提取。 翻译也要保留不确定性 在多语言文档中,先确认源文档状态,再核对目标语言如何表达。不能让译文的肯定语气反过来覆盖原文的不确定。 OmniDoc(产品入口) 可以作为文档翻译入口来评估,但业务状态的放行规则仍应由你的系统明确维护。 参考: JSON Schema enum 。 - 1 -
更新于 2026-10-08