内容
# VerifyDoc
> **用于文档的结构化 JSON 提取的可信层。** 包装任何提取器 - 返回 JSON,其中**每个字段**都带有**校准置信度**、**来源定位**(页面 + 边框 / 字符跨度)和**接受/审核决策**,以适应您的错误预算。
[](https://github.com/bhaskargurram-ai/verifydoc/actions/workflows/ci.yml)
[](LICENSE)
[](pyproject.toml)
[](https://github.com/psf/black)

*上方:实际运行的管道(`scripts/make_demo_gif.py`)。提取器返回 `$1,432.50`;页面显示 `$1,234.50`。定位支持下降到 0.78,字段未达到接受阈值,审查人员被指向确切的源区域。其他三个字段自动接受。*
## 问题
现代文档解析器读取页面的准确率超过 96% - 但仍会发出**流畅、看似合理、但错误的值**(`$42.50` → `$45.20`),并且**没有可靠的字段级信号告诉您哪些值是值得信赖的**。商业 API(Box、Azure、Textract)将字段级置信度作为封闭功能出售。没有流行的开源解析器以此为特色。([完整的 USP 审计](docs/USP.md))
VerifyDoc 不与解析器竞争 - 它**建立在任何解析器之上**:
```
文档 + 模式 ─► 导入 ─► 提取器适配器 ─► 置信度 ─► 校准
(任意模型) 信号 (在校准分割上拟合)
─► 定位 ─► 放弃策略 ─► 验证 JSON + 审查 UI
(边框/跨度) (目标风险 α)
```
在选择的运行点,VerifyDoc 自动接受尽可能多的字段,同时将接受的字段中的错误率保持在目标以下(例如 ≤ 2%)- 所有其他字段都被路由到 `审查` **并附带其源位置**,以便人类能够快速验证而不是逐一检查每个字段。
## 快速入门
```bash
pip install verifydoc # 核心(文本管道 + 评估框架)
pip install 'verifydoc[pdf]' # + PDF/图像导入
```
```python
from verifydoc import verify
# 现成的示例位于 examples/ 目录中
result = verify("examples/invoice.txt", schema="examples/invoice_schema.json")
for f in result.fields:
print(f"{f.path:12} = {f.value!r:24} 置信度={f.confidence:.2f} {f.decision}")
if f.grounding:
print(f" └─ 页面 {f.grounding.page},边框 {f.grounding.bbox}")
```
```bash
verifydoc extract examples/invoice.txt --schema examples/invoice_schema.json --threshold 0.8
streamlit run ui/streamlit_app.py # 审查 UI:绿色/红色字段 + 点击查看源
```
查看 [`examples/`](examples/) 目录中的完整可运行示例。
## 面向 AI 代理(MCP)
为任何支持 MCP 的代理(Claude Desktop、IDE、自定义代理)提供**用于读取文档的可信层** - 以便它对自信、定位的字段采取行动,并将其他字段升级而不是凭空捏造:
```bash
pip install 'verifydoc[mcp]'
verifydoc-mcp # 标准输入输出 MCP 服务器,暴露 verify_extraction() 接口
```
代理提取的每个字段都带有 `置信度 + 定位 + 接受/审查`。有关单行客户端配置,请参阅 [docs/MCP.md](docs/MCP.md)。
模式是普通的 JSON 模式,每个叶子节点可选地声明**如何评分**(可执行模式模式):
```json
{
"type": "object",
"properties": {
"invoice_id": {"type": "string"},
"vendor": {"type": "string", "x-scoring": "semantic"},
"total": {"type": "number", "x-numeric-tol": 0.01}
}
}
```
## 内部结构
| 层 | 模块 | 状态 |
|---|---|---|
| **适配器** (所有模型代码在此隔离) | mock · text-search · RapidOCR · PaddleOCR · dots.ocr · Docling/MinerU 输出 · API-VLM(OpenAI/Anthropic) | ✅ |
| **置信度信号** | token-prob · verbalized · consensus(k 样本投票) · grounding-based · combined | ✅ |
| **校准器** (在专用分割上拟合,永不测试) | temperature · Platt · isotonic · histogram · **split conformal** · **grounding-conditioned(Mondrian)conformal**(新颖 - 恢复覆盖率, pooled 阈值会损失) | ✅ |
| **定位** | value → 页面/边框/字符跨度附件,带支持分数 | ✅ |
| **策略** | 经验和共形接受阈值,用于目标选择性风险 | ✅ |
| **评估框架 / VerifyDocBench 评分器** | Field-F1 · exact · CER/WER · ANLS · TEDS/TEDS-Struct · GriTS · omission vs hallucination · ECE/Adaptive-ECE/MCE/Brier/NLL/TCE · RC/AURC/E-AURC/Coverage@Risk/AUROC/AUPR/FPR@95 · box IoU/span-F1/grounding-conditioned correctness · bootstrap CIs + paired tests | ✅ |
每个指标在 [PROJECT.md §5](PROJECT.md) 中实现精确定义,并带有手工计算的数值回归测试(201 个测试,`eval/` 覆盖率 98%)。
## 真实文档的结果
两个独立的真实 OCR 提取器(**RapidOCR** 和 **PaddleOCR**)在真实的 **CORD** 收据和 **FUNSD** 表单上,通过评估框架评分([完整表格 + 阅读](paper/generated/REAL_MODELS_RESULTS.md)):
| 置信度信号 | 排名错误? | CORD AUROC(RapidOCR / PaddleOCR) |
|---|---|---|
| **学习组合器** | ✅ 最佳 | **0.89 / 0.84** |
| **定位** | ✅ 强大 | 0.82 / 0.74 |
| token-probability | ~ 中等 | 0.69 / 0.68 |
| verbalized / consensus | ✗ 无信息 | 0.50 / 0.50 |
- **定位是一种真实的可信信号:** 定位字段 **84–85% 正确 vs ~1%** 对于未定位的字段(差距 ≈ +0.84;框精度 @IoU 0.5 = 0.75–0.78)。
- **放弃层是诚实的:** 使用弱字段提取器,基本错误率很高,因此在 2–5% 的预算下,共形放弃会正确拒绝自动接受 - 您报告 **选择性风险**,而不是标题准确率。
- 合成切片(强提取器)显示了另一端:Coverage@2% ≈ 1.0。
论文在真实数据上成立:**定位 + 学习融合排名错误;自我报告和单样本共识置信度不。**
## 基准
```bash
make results # 从配置中重新生成论文/generated 中的所有表格/图表
```
评估框架运行 **信号 × 校准器 × 完整指标套件**,带有文档级校准分割(代码中声明不相交),自举 CI 和共形保证行。它提供了一个确定性的 **合成** 切片(在 CI 中运行)以及 **CORD** 和 **FUNSD** 加载器,带有黄金源框;`extractor:` 调度到任何适配器(`rapidocr`、`paddleocr-vl` 等),`dataset:` 调度到任何切片。有关重现真实模型行的详细信息,请参阅 [GPU 运行手册](docs/REAL_MODELS.md)。核心声明(定位优于口头表达;共形保持其保证)也在 **CI 中作为单元测试强制执行**,而不仅仅是声明。
## 为什么不直接使用解析器的自身分数?
因为它不存在(Docling/MinerU/Marker),或者它是一个原始识别分数,从未针对字段级正确性进行校准(PaddleOCR/dots.ocr)。有关审计,请参阅 [docs/USP.md](docs/USP.md),有关“校准”的内容,请参阅 `paper/generated/` 中的可靠性图表。
## 路线图
- [x] v0.1 — 库 + CLI + 评估框架 + 合成基准切片 + UI
- [x] v0.2 — CORD + FUNSD 真实切片,带有黄金框;学习组合器;速度提高 1000 倍的定位器
- [x] v0.3 — 真实模型结果(RapidOCR + PaddleOCR 在 CORD/FUNSD 上)
- [x] v0.4 — 供应商中立的 API-VLM 提取器(OpenAI/Anthropic),带有 k 样本共识;可编译的论文,带有自动生成的表格
- [x] v0.5 — **新方法**(基于定位的共形,+0.50 覆盖率,固定风险)+ **MCP 服务器**(代理可信层)+ 真实前沿 VLM 结果
- [x] v0.6 — 在 **真实数据上验证**(FUNSD 24%→71% 覆盖率,2% 风险);注释者间协议工具(`verifydoc iaa`);数字感知定位
- [ ] dots.ocr via vllm; SROIE / DocILE / XFUND 切片; 大规模人类标记正确性
- [ ] 论文提交([欢迎贡献](CONTRIBUTING.md))
## 文档
- [工作原理](docs/how-it-works.md) — 管道、放弃想法、为什么定位是一种可信信号
- [真实模型结果](paper/generated/REAL_MODELS_RESULTS.md) — RapidOCR + PaddleOCR 数字和阅读
- [GPU 运行手册](docs/REAL_MODELS.md) — 重现真实提取器行
- [USP 审计](docs/USP.md) · [论文草稿](paper/main.tex) · [完整规格](PROJECT.md)
## 开发
```bash
git clone https://github.com/bhaskargurram-ai/verifydoc && cd verifydoc
uv venv .venv && uv pip install -e ".[dev]"
make test lint typecheck # 所有绿色之前任何 PR(CI 强制)
make results # 重新生成基准测试表格 + LaTeX
make paper # 编译论文(需要 LaTeX 工具链)
```
欢迎贡献 - 请参阅标记为 `good-first-issue` 的问题。所有特定模型代码都位于 `verifydoc/adapters/` 目录中;新的提取器是一个文件。
## 引用
```bibtex
@software{verifydoc2026,
author = {Gurram, Bhaskar},
title = {VerifyDoc: 校准、放弃、定位文档提取},
year = {2026},
url = {https://github.com/bhaskargurram-ai/verifydoc}
}
```
Apache-2.0.