解析方案

首页/文章/文章

# Resume Parser v15 解析方案(v2 设计稿) 更新日期:2026-08-18适用范围:替代本文件此前的 v15 方案描述,对应 `V15重构历程与目标.md` 第 7 章的理想架构落地路径。

## 0. 结论先行 历程文档记录的失败不是提示词不够好,而是三个结构性缺口:

  1. **没有可信证据层**:`PyMuPDF` 原生块 + 启发式分栏是唯一输入,扫描件、文本框、表格、双栏没有统一的坐标/置信度/阅读顺序模型。模型收到错序证据时,任何提示词都救不回来。2. **没有共享的记录边界**:三路并行让基本信息、工作、项目各自独立理解同一份简历,彼此不知道对方划出的公司/项目边界,所以出现”项目为空""工作与项目重叠""同一段经历两种解释”。3. **没有字段级完整性判定**:`HTTP 200` 和 Pydantic 通过都不代表字段被提取。缺少”原文有证据但字段为空”的机器判定,所以低权重字段(教育年月、薪资、汇报对象、Q&A)被模型静默放弃后无人发现。 方案的核心是在文档层与字段抽取层之间插入一个****骨架索引层****,并把”补抽”变成有上限的确定性状态机: ```textL1 证据层  ->  L2 骨架索引  ->  L3 字段族抽取  ->  L4 完整性审计/定向补抽  ->  L5 确定性治理  ->  Contract Adapter``` L2 是本方案与之前所有尝试的关键差异。它

    test
    test

    用一次****廉价、小输出**的全局调用只产出记录边界和证据索引,不产出业务字段;之后所有字段族抽取共享同一份边界,归属冲突在进入并行之前就被消除。 ## 1. 为什么不是之前的任何一种 | 已试方案 | 失败根因 | 本方案的处理 || --- | --- | --- || 完整 Schema 单次抽取 | 输出预算被长文本吃掉,低权重字段被主动放弃 | 字段族拆分,每族 ≤ 12 字段,长文本只回 refs || 程序先切章节再并行 | 程序无权决定语义边界 | 边界由 L2 模型基于全局证据决定,程序只提供块与坐标 || 三路并行紧凑抽取 | 各路无共享边界,部分失败被当成功 | 全部子任务共享 L2 骨架;每族独立状态,禁止静默合并 || 开放式 Agent 自主循环 | 调用数、延迟、可复现性不可控 | 固定 DAG,补抽最多 2 次,每步输入输出合同固定 || 正则补丁回填字段 | 同一词在不同简历含义不同 | 正则只用于**证明证据存在****(标签锚点),永不写入字段值 | **标签锚点(label anchor)**是本方案里唯一允许的确定性文本信号,必须严格区分于 v14 的正则补丁:

  • 允许:判定”块 `p2` 里出现了`离职原因`这个标签”,据此建立证据索引、触发补抽。- 禁止:从该块用正则截取”离职原因”的值并写进 `reason_leave`。值永远由模型在完整上下文中判断。 这条边界让我们既能机器判定”漏了”,又不回到样本驱动的补丁模式。 ### 1.1 与 v14 的可证伪差异(本方案的立项依据) “有确定性代码”不是 v14 的问题,任何解析系统都有。v14 的问题是****确定性代码参与了语义决策****:它写字段值、切章节边界,于是 LLM 只能在错误前提上工作,补丁只能靠加更多补丁维持。 v15 用三条硬约束把确定性代码钉死在非语义层:
  • **约束 A — 规则不可写值。** 确定性代码只允许产出三类东西:证据存在标记(`evidence_exists`)、`block_id` 引用、格式归一化(日期补零、去重、空对象过滤)。任何业务字段的****值**只能来自模型输出或按 `refs` 回溯的原文。- **约束 B — 规则不可定边界。** 章节归属、公司/项目/学历的记录边界只能由 L2 模型基于全局证据输出。程序不得按标题、日期或版面切分记录。- **约束 C — 规则必须可删。** 删掉整张标签锚点表后,系统必须仍然输出**正确****结果,只是召回下降。 约束 C 是可执行的验收测试,不是原则宣言: ```text在 gold 集上跑两次:A = 启用锚点表,B = 锚点表置空允许:B 的字段召回低于 A(漏提取)不允许:B 中出现 A 里本来正确、现在变错的字段值``` 任何一条规则一旦让 B 出现”由对变错”,就证明它在写值或定边界,必须删除。v14 做同样的 ablation 会直接崩:因为补丁本身就是输出的一部分。 由此得到的维护成本差异才是重构的真正收益: | | v14 新增一条规则 | v15 新增一条锚点 || --- | --- | --- || 影响面 | 可能改写任意字段值 | 只可能多触发一次补抽 || 证明责任 | 必须回归全量样本证明无副作用 | 只需证明它命中了该标签 || 最坏后果 | 其他版式字段被写错 | 浪费一次模型调用 || 可删除性 | 删除即回归错误 | 删除只降召回 | 如果实现过程中出现”不加这条规则结果就是错的”,说明该处设计已经退化成 v14,应当回到 L2/L3 的合同去修,而不是保留规则。 ## 2. L1 文档证据层 目标:任何格式最终产出同一个 `EvidenceDocument`,模型永远不接触解析器差异。 ### 2.1 统一块模型 每个块必须携带:`block_id`(稳定、全局唯一)、`page_number`、`bbox`、`text`、`kind`、`source`、`reading_order`、`confidence`、`origin`(`native` / `ocr` / `table` / `textbox`)、`column_index`。 现有 `schemas/layout.py` 的 `LayoutBlock` 已有前 7 项,需要补 `confidence`、`origin`、`column_index`,并把 `block_id` 从”页内序号”改为”页内 + 来源”复合 ID,避免原生块与 OCR 块 ID 冲突。
解析方案
https://yicheng.ink/posts/解析方案/
作者
yicheng
发布于
2026-08-19
许可协议
CC BY-NC-SA 4.0

当前页面没有目录