| name | entity-extraction |
| tier | meta |
| description | Extract specific entities, values, and text segments from documents as required by verification rules. Use after tree processing has located the relevant section, when a rule needs a specific number, date, name, amount, clause, or any domain-specific entity extracted. Covers extraction method selection (regex vs LLM), schema design, postprocessing, and confidence annotation. Also use when designing the extraction step of a workflow for worker LLMs. |
实体提取
实体就是你需要核查的对象:一个数字、一个日期、一个名称、一个条款、一个百分比、一段陈述。规则告诉你要核查什么,提取负责把可核查的值从原文中取出来。换句话说,规则定义了"核查目标",而实体提取是把这个目标从纸面化为程序可比较、可判定的结构化数据的关键一步。没有可靠的提取,后续的判定和报告都是空中楼阁;提取阶段每多一分误差,下游的判定和汇总就会把这分误差放大。在金融与监管合规这类对数字、口径、时点极其敏感的场景里,提取的稳定性直接决定整套验证流程能否被信任。
提取场景分类
不同的提取场景需要不同的策略。先对照下面四类,识别当前规则属于哪一种,再去选具体的实现方法:
单一章节中的单一实体
最简单的情况。一条规则只需要从一个固定位置取一个值。
- 示例:"从关键指标表中提取资本充足率。"
- 思路:先通过树处理定位到对应章节,再用正则或 LLM 对该段文本做一次提取即可。
单一章节中的多个实体
一条规则需要从同一段落或同一张表里取出多个相关的值。
- 示例:"从贷款协议摘要中提取借款人姓名、贷款金额、利率和到期日。"
- 思路:设计一次提取调用,让模型或脚本一次性返回所有字段。比拆成多次调用更高效,也更容易保持字段之间的一致性,避免重复加载相同的上下文。
多个章节中的单一实体
同一个值分散在多个位置,或需要交叉比对、汇总。
- 示例:"提取抵押物总价值,该值可能列在抵押物章节,也可能列在附件 A。"
- 思路:先把所有可能含有该值的章节内容汇总,再做一次提取。务必在结果中标注该值的来源章节,方便后续追溯和审计。
全文档级别的实体
该值可能出现在任意位置,或者规则本身是针对整份文档的属性。
- 示例:"核查文档是否包含有效的签章页。"
- 思路:对于编码 agent,可以直接扫描整份文档。对于 worker LLM 工作流,建议设计两遍流程:第一遍粗扫整篇定位候选位置,第二遍只对候选段做精提取。这样能避免把整篇文档塞进单次调用导致上下文超限,也便于在候选阶段做并行化处理。
方法选择
提取方法的选择本质上是一次成本-准确率的搜索。目标是找到能稳定达到准确率阈值的最低成本方案。正则表达式是最小、最便宜的"模型"——零成本、即时、确定性、可重放、可被单元测试覆盖。Worker LLM 能力更强,覆盖语义层面的提取需求,但消耗 tokens 和时间,且每次输出可能存在细微差异,需要后处理与校验来兜底。任何搜索策略都成立:可以先试最便宜的方法再逐步升级,也可以先试最强的方法再逐步降级,可以在中间档位做二分查找,也可以基于 AGENT.md 中沉淀的历史经验直接跳到已验证可行的方法上,不必每次都从零开始重新试错。重要的是先想清楚"达标"的标准是什么,再开始搜索,否则容易在没有目标的情况下无限抬高成本。
可用方法
正则 / Python —— 成本:零。速度:即时。结果确定。适用场景:日期、金额、百分比、标识符、固定短语、编号、电话、地址等任何格式可预测的值。任何能写出清晰格式约束的字段,都应该优先考虑正则。
Worker LLM —— 成本:API tokens。速度:秒级。具备语义理解能力。适用场景:需要结合上下文判断、条件性取值、语义匹配、结构模糊、识别误导性或暗示性表述、表格语义解读,凡是依赖理解而非模式匹配的任务。Worker LLM 在表面形式不稳定但语义清晰的场景下尤其有价值。
实际验证任务中存在大量需要语义理解的场景——"这段描述是否具有误导性?"、"该条款是否充分披露风险?"、"该担保人的业务描述是否与其所述行业一致?"、"产品类型表述与底层资产是否匹配?"——这些都不是正则能处理的问题。遇到此类任务,毫不犹豫地使用 worker LLM;不要为了节省 tokens 而把不适合的任务硬塞给正则,否则就是用低成本换高漏报或高误报,最终在审计或复核环节付出更大代价。
搜索过程
如果某个方法的结果低于准确率阈值,就换一种方法或换一档更强的模型。正则可行且达标——保留它,反正免费、稳定、可回放。正则结果不达标,升级到 worker LLM。便宜档的 worker LLM 不够准确,再换更高一档的模型。每个项目都应当把"哪类提取适用哪个方法"沉淀到 AGENT.md 里,作为后续同类规则的参考;这样下一条规则上来就能直接选对档位,而不是每次都从最便宜的方法重新搜索一遍。同时记录失败案例和阈值不达标的边界条件,让后续同类规则可以提前避坑、节省迭代成本。
项目术语表
项目术语表(由 rule-extraction 构建并维护,存储在 rules/glossary.json)是设计提取时的有用资源。它记录了在多条规则中反复出现的实体的规范名称以及已知别名。在动手提取前先读一遍术语表,有助于保持实体命名与项目 schema 对齐,避免对同一事物使用并列的不同标签——例如同一个字段在不同规则里被叫作"资本充足率"、"资本充足比例"、"CAR"等,最终汇总报告时就会出现重复或漏匹配。
术语表是否要承担命名约定之外的角色——例如,对表面形式稳定的实体直接驱动便宜的模式匹配——是逐项目判断的。在这里同样适用成本-准确率逻辑:在当前任务上能达到准确率阈值的方法就是合适的方法。如果术语表里某个实体的别名集合稳定且可枚举,那么基于术语表生成正则可能是性价比最高的方案;如果别名在新文档中持续扩展、随业务术语演化,那不如直接交给 worker LLM 做语义识别。术语表的另一个隐藏价值在于:它把命名约定固化成项目级单一事实来源,减少跨规则、跨技能之间因为称呼不同而产生的不一致问题。
Schema 设计
为每次提取定义清晰的预期输出。保持简单、按需扩展(JIT 原则):
{
"entity_name": "capital_adequacy_ratio",
"value": 12.5,
"unit": "%",
"raw_text": "资本充足率为12.5%",
"source_location": "Chapter 2, Table 1, Row 3",
"confidence": 0.95,
"extraction_method": "regex"
}
Schema 通常需要包含以下信息:
- value:提取出的值,已经过归一化处理。
- unit:单位(如 %、元、天等),如果适用就填写。
- raw_text:值所在的原文片段。这是后续判定步骤的核心证据,也是出现争议时最容易回溯定位的字段。
- source_location:值在文档中的位置(章节号、表名、行列号等)。
- confidence:置信度,详见
confidence-system。
- extraction_method:使用的提取方法(regex、LLM-TIER2 等),便于事后做方法效果分析。
不要过度设计 schema。最开始保持最小集合,在测试中遇到判定需要什么信息再补充对应字段;不要在第一次就把可能用到的字段全部塞进去。冗余字段不仅增加 prompt 体量、增加 worker LLM 的失误面,还会让后续维护时不清楚哪些字段是真正被消费的、哪些是历史残留。schema 一旦写错或扩张得太快,回头清理的成本会很高。
后处理
提取出的原始值通常需要归一化才能与规则中的阈值或目标值做严格比较:
- 中文数字 → 阿拉伯数字:一百二十万 → 1200000
- 日期标准化:2024年3月15日 → 2024-03-15
- 单位换算:万元 → 若规则的阈值以元为单位,需要乘以 10000 再比较。
- 空白与噪声清理:去除多余空格、换行符、转义符、表格分隔符等格式残留。
- 百分比归一化:0.125 → 12.5%,或反向转换,取决于规则期望的形式。
把后处理实现为规则技能 scripts/ 目录下的 Python 函数。它们是确定性的、可复用的,且便于单元测试。提取与后处理分离也让 schema 中的 raw_text 保持忠实于原文,归一化后的值放进 value,两者各司其职。这种分层好处还在于:当后处理逻辑出现 bug 时,只要 raw_text 是对的,就可以重跑归一化而不必重新调用 LLM、节省成本。
置信度标注
每次提取都应当带上一个置信度估计,作为后续判定与汇报阶段的重要输入:
- 正则匹配,格式校验通过:0.90-0.95
- LLM 提取,高度确定:0.80-0.85
- LLM 提取,存在一定歧义:0.60-0.75
- 回退或推断得到的值:0.40-0.60
- 未找到值:0.0(标记为 MISSING)
以上只是起始值。随着 ground truth 累积,应根据实际准确率持续校准(详见 confidence-system)。低置信度的提取应在判定阶段被特别对待,例如触发人工复核或交叉比对,而不是直接当作高置信度结果使用。置信度本身不是装饰字段,而是判定阶段做风险加权的依据;如果整套流程对置信度毫无消费,那这个字段就形同虚设,反而会让团队对系统输出产生虚假的"完整感"。
Prompt 设计:要什么,说什么
写 prompt 时要直接描述你想要的输出形态,而不是反复强调你不想要的内容。在 prompt 里写"不要包含解释"或"不要输出额外文本",远不如在后处理时从输出中剥离非 JSON 文本来得可靠——大模型在压力下经常会"为了帮助你"补充一些自以为有用的说明、致歉、或开场白,从而违反否定指令。如果确实必须告诉 LLM 不要做某事,那就把控制点放在后处理的输出过滤上,而不是 prompt 中的否定句。换言之:用确定性的后处理来兜底不确定的 LLM 行为,永远比单靠 prompt 措辞更稳。同理,"必须返回合法 JSON"也应当配套一段健壮的解析与修复逻辑,而不是天真地假设模型每次都能完美输出。
Worker LLM 上下文适配
为 worker LLM 工作流设计提取时,需要预先估算并约束上下文规模:
- 估算 prompt 体量:系统 prompt + 指令 + 示例 + 输出格式 = N tokens。
- 留给文档内容的可用上下文 = 模型上下文窗口 - N。
- 若目标章节超出可用上下文,回到树处理进一步收窄,或将其切分为多次调用。
- 始终为模型的响应预留足够空间,否则可能在生成中途被截断,导致 JSON 不完整。
- 用真实使用的模型做端到端测试以验证上下文确实能装下——编码 agent 估算的 token 数可能与 worker LLM 自己的分词器结果不一致,尤其是在中文、表格与代码混排的场景下,差异可能达到数十个百分点,仅凭估算容易在生产环境上线后才发现窗口被打爆。
抽取也有边缘案例
抽取和判断同样重要,对最终准确率的贡献不可低估。一个跨项目的经验:超过一半的最终错误其实可以追溯到抽取问题,而非判断问题 —— 抽取器返回了错值、错单位、或从错的章节取了内容,判官则忠实地从错的输入里得出了错的 verdict。
把抽取按和判断同样的迭代纪律来做:
- 反思 / 迭代:在样本集上跑过一次抽取器之后,回看失败的 case。是漏了某种模式(往 prompt 或正则里补)?是格式怪癖(单位换算、本地化)?还是文档类型问题(抽取器对 A 类对、对 B 类错)?
- 边缘案例登记:当一个抽取失败没办法以合理代价改进标准抽取器时,把它登记到
corner-case-management 里 —— 注册表形状和判断边缘案例一样,resolution 类型换成 code / prompt / parser 级别的转换即可。
- 独立验证抽取器:只在判断侧失败的端到端测试可能掩盖一个差劲的抽取器 —— 它的输出虽然不准,但碰巧 大部分时候 让判官得出了正确的 verdict。在 QC 复核里抽查的应当是抽取值本身,不只是最终 verdict。
当你想通过调判官的 prompt 来提升准确率时,先检查抽取器是不是给判官喂了正确的输入。更便宜、更耐久的修复点几乎总在抽取器里。