alitrack

一次 VLM 调用替代两次:GAIK Vision Extractor 把文档提取成本砍了一半

一次 VLM 调用替代两次:GAIK Vision Extractor 把文档提取成本砍了一半

企业文档结构化提取,今天还在用「先解析、再提取」的两步法。拆成两次 LLM 调用,先让模型把 PDF 转成 Markdown,再让另一个模型从 Markdown 里提取字段。
这个模式有个结构性问题:第一个模型决定「怎么表示文档」的时候,不知道第二个模型「需要什么」。
如果 Parser 把合并单元格拍平了、跨页表格截断了、侧边注释丢掉了,Extractor 只能从有损的中间表示里「猜」答案。更糟的是,它会输出一段看起来完全正确的 JSON——你很难发现数据已经错了。
芬兰 FAIR 项目的 Umair Ali Khan 在 5 月发表了一篇工程实践文章,给出了一个更优雅的方案:Vision Extractor,把解析和提取合并为单次 VLM 调用。

核心思路:Parser 的中间表示,移进模型推理内部

传统两步法的本质问题是:Parser 的输出是 Extractor 的唯一信息来源。模型拿到的是 Markdown,不是原图。一个跨页表格被截成两段,Extractor 无法「回头查看」第二页的原始图像。
Vision Extractor 的做法很简单——不在 Prompt 里要求模型输出中间表示,而是要求它在内部完成版面分析,然后直接输出结构化数据。

1SYSTEM_PROMPT = """
2...
3Before extracting, internally analyze the document by identifying
4each layout element as if wrapping it in a <div> tag with:
5- data-bbox="[x1, y1, x2, y2]"
6- data-label="<category>"
7
8Use this analysis to inform your extraction,
9but output only the structured data.
10..."""

Parser 的中间表示不再是输出 token,而是变成了模型推理过程中的一个环节。模型带着提取任务阅读文档,同时理解版面,同时输出指定字段。
效果:调用次数从 2 次降到 1 次,中间 token 直接省掉,延迟降低,信息损失降低。

Schema 自动生成:从自然语言到 Pydantic 模型

用户的提取需求通常是用自然语言描述的,比如:

"提取采购订单号、日期、供应商名称和所有行项目。"

Vision Extractor 内置了一个 Schema Generator,能从自然语言自动推导输出结构,并生成 Pydantic 模型。
它把输出结构分为三类:

  • Flat(单层):每个字段只出现一次。比如酒店订单,一个预订号、一个入住日期
  • Nested list(嵌套列表):输出是一张表格,每行有相同的字段
  • Parent with nested list(主表+子表):顶层字段一次,行项目重复出现

第一版生成的 schema 可以持久化为 schema.py + requirements.json,后续相同类型的提取任务直接复用。
这套设计在工程层面很实用——业务用户不需要写 Python 类型定义,写自然语言需求就好。

字段级置信度:不只是整体打分

多数文档提取方案只给出「整体置信度」,Vision Extractor 给的是每个字段的置信度分数和推理过程。
评分规则:

置信度含义示例
0.95–1.00确定值明确无歧义出现在文档中
0.80–0.94高需少量解释(日期格式转换、缩写展开)
0.60–0.79中需跨段推理或推断
0.40–0.59低证据弱或存在冲突
0.01–0.39极低仅凭猜测,必须人工审核

输出示例:

1{
2  "drawing_number": {
3    "value": "A-201",
4    "confidence_score": 0.99,
5    "confidence_reason": "Drawing number is explicitly stated as the sheet identifier."
6  },
7  "slab_thickness": {
8    "value": "4\"",
9    "confidence_score": 0.97,
10    "confidence_reason": "Slab section notes explicitly label the concrete slab as 4 inches thick."
11  }
12}

这个设计让 Human-in-the-loop 变得实际:审核者不需要重读整份文档,只看低置信度字段及其推理即可。

实际成本:单次调用约 $0.007 到 $0.022

文中给出了三组实测数据,全部使用 gpt-5.4-mini、reasoning_effort=low:

场景文件数LLM 耗时Token 总量费用
建筑蓝图提取(18 个字段)17.8s4,550$0.0065
采购订单提取(跨 2 页)118.3s10,736$0.022
PO + 3 份 BOM 跨文档关联47.7s10,064$0.012

最关键的数字是:小模型 + 低推理成本已经能覆盖大部分文档提取任务。不是所有场景都需要 GPT-5.5 级别的模型。
对复杂版面的文档,作者建议从小模型加低推理配置开始,如果需要更高精度再切换到大模型或提高 reasoning_effort。

跨文档关联:一次调用内完成

一个更复杂的场景:采购订单(PO)+ 多份物料清单(BOM)。
PO 里有物料编号,每份 BOM 有对应的技术规格。传统做法需要多次提取、手动关联。Vision Extractor 能在一次调用里完成:

  1. 提取 PO 的头部信息(订单日期、买家、地址)
  2. 提取每行项目的物料编号和数量
  3. 用物料编号去匹配对应的 BOM
  4. 从 BOM 中提取技术规格
  5. 组装成最终输出

四个 PDF 文件,一次调用,7.7 秒,$0.012。

开源与可用性

Vision Extractor 是芬兰 GAIK(Generative AI-enhanced Knowledge Management) 项目的一部分,MIT 协议开源。

1pip install "gaik[vision-extract]"

使用示例:

1from gaik.software_components.vision_extractor import VisionExtractor
2
3extractor = VisionExtractor(
4    model_provider="openai",
5    model="gpt-5.4-mini",
6    reasoning_effort="low",
7    include_verification=True,
8)
9
10result = extractor.extract(
11    file_paths=["po.pdf"],
12    user_requirements="Extract purchase order number, date, vendor name, and all line items.",
13)

支持 OpenAI、Azure OpenAI、Google Vertex AI 三家 Provider。完整代码在 GAIK-project/gaik-toolkit。

适用边界

Vision Extractor 不是万能的。作者明确指出了不推荐的场景:

  • 简单布局的纯文本文档:标准两步法(Docling/PyMuPDF + 轻量提取)更高效
  • 超过 30 页的文档:VLM 上下文窗口限制
  • 高确定性表单:专用 OCR 模型的确定性更好、成本更低

对于中等复杂度、多页、跨文档的场景,它是当前开源方案里最务实的选择之一。

小结

Vision Extractor 的核心贡献不在于发明新架构,而在于把一个已经被验证的想法——单次 VLM 调用替代多阶段 Pipeline——做成了可复用的工程组件。它的三个设计值得借鉴:

  1. Prompt 技巧:让模型在「内部」完成版面分析,不输出中间表示,降低 token 消耗和累积错误
  2. Schema 自动生成:从自然语言需求自动推导输出结构,减少工程落地成本
  3. 字段级置信度:每个字段带置信度分数和推理,让 Human-in-the-loop 从理念变成可操作的设计

文档提取这个领域,2026 年的趋势已经很明显:VLM 能力在快速提升,传统的 OCR + 布局分析 + LLM 提取的三阶段 Pipeline 正在向单次 VLM 调用靠拢。Vision Extractor 告诉我们,这个方向的工程落地门槛已经很低了——七分钱,就能从一份复杂文档里精确提取出你需要的所有字段。