乏味但有价值的用例
二十年来,从非结构化文档中提取结构化数据一直是一个持续数月的项目:OCR 流水线、正则表达式规则、边界情况处理,以及按供应商制作布局模板。使用受 JSON Schema 约束的 LLM 后,只需 30 行代码,首次处理就能达到较高准确率,并可在一天内上线。下面的示例运行在 Kunavo 上——一个独立的 OpenAI 兼容网关;但这种模式属于模型本身,对任何模型的调用方式都相同。
只处理发票吗?本页面是跨文档概览。专门的发票数据提取指南会深入介绍这一种文档:旧式模板与模型方法如何与视觉 LLM 调用进行比较、完整的受 Schema 约束的 Python 教程、算术护栏、双层模型路由,以及每张发票的成本。
特别适合这种方法的类别:
- 发票、收据、采购订单
- 合同、法律协议(提取当事方、日期、义务)
- 简历 / CV(解析为适合 ATS 的结构)
- 从电子邮件签名或网页中补充潜在客户信息
- 医疗记录、化验报告(需处理 PII)
- 房地产房源、产品目录
- 电子邮件分拣和结构化导入
30 行代码的核心模式
import json
from openai import OpenAI
client = OpenAI(api_key="sk-kn-...", base_url="https://api.kunavo.com/v1")
# The schema is the output contract. Claude enforces a json_schema
# response_format (json_object it does not), so the reply has this shape
# unless max_tokens cuts it off (finish_reason == "length").
STR = {"type": ["string", "null"]}
NUM = {"type": ["number", "null"]}
INVOICE = {
"type": "object",
"properties": {
"vendor": {"type": "string"},
"invoice_number": STR, "date_iso": STR, "due_date_iso": STR,
"currency": STR, "subtotal": NUM, "tax": NUM, "total": NUM,
"line_items": {"type": "array", "items": {
"type": "object",
"properties": {"description": {"type": "string"},
"qty": NUM, "unit_price": NUM, "amount": NUM},
"required": ["description", "qty", "unit_price", "amount"],
"additionalProperties": False,
}},
},
"required": ["vendor", "invoice_number", "date_iso", "due_date_iso",
"currency", "subtotal", "tax", "total", "line_items"],
"additionalProperties": False,
}
RESPONSE_FORMAT = {"type": "json_schema",
"json_schema": {"name": "invoice", "schema": INVOICE}}
RULES = "Extract the invoice. Use null for missing fields. Dates in ISO 8601."
# Extract structured fields from an invoice PDF (after OCR)
def extract_invoice(ocr_text: str) -> dict:
resp = client.chat.completions.create(
model="claude-haiku-4-5",
messages=[
{"role": "system", "content": RULES},
{"role": "user", "content": ocr_text},
],
response_format=RESPONSE_FORMAT,
max_tokens=1200,
)
return json.loads(resp.choices[0].message.content)
# Extract from an image directly (no OCR step needed)
def extract_invoice_from_image(image_url: str) -> dict:
resp = client.chat.completions.create(
model="claude-haiku-4-5", # vision + an enforced schema
messages=[
{"role": "system", "content": RULES},
{"role": "user", "content": [
{"type": "text", "text": "Extract this invoice:"},
{"type": "image_url", "image_url": {"url": image_url}},
]},
],
response_format=RESPONSE_FORMAT,
max_tokens=1200,
)
return json.loads(resp.choices[0].message.content)有两种流程:纯文本流程(先单独执行 OCR)和直接视觉流程(视觉模型读取图像并在一次调用中输出 JSON)。视觉流程构建更快,但每次调用成本略高;OCR 后接 LLM 的流程在大规模场景下更便宜,因为 OCR 对每页只需付费一次。
准确率基准
在公开发票数据集上(来自 50 家供应商的 1,000 张发票),使用 JSON 模式和 200 词系统提示词:
- Claude Haiku 4.5:字段级准确率 96%
- Claude Sonnet 4.6:字段级准确率 98%
- 传统模板:对已知供应商为 80-90%,对新供应商为 0%
LLM 可以零样本处理新供应商的布局。在系统提示词中加入 2-3 组示例对(few-shot)后,Haiku 可以用很低的成本接近 Sonnet 的准确率。
每份文档的成本
- 发票(约 2K 输入 token、约 500 输出 token):Haiku 约 $0.003,Sonnet 约 $0.02
- 一页合同(约 5K 输入 token):Haiku 约 $0.005,Sonnet 约 $0.04
- 10 页合同(约 50K 输入 token,输出结构化摘要):Sonnet 约 $0.30
- 简历(约 3K 输入 token):Haiku 约 $0.003
- 带视觉输入的收据图像:Haiku,成本约等于一张发票——图像约计为 1.5K 输入 token
每月处理 10,000 张发票:使用 Haiku 约 $30。最接近的商业替代方案(Rossum、AWS Textract + 后处理)处理相同数量时每月约需 $2,000-5,000。
保持高准确率的 5 个模式
- 明确处理 null:告诉模型缺失字段使用
null,不要使用“N/A”或空字符串。下游代码可以区分“缺失”和“有意留空”。 - 使用 ISO 8601 日期:明确说明这一点。否则模型会选择地区格式,导致下游解析失败。
- 货币使用 ISO 代码:“USD”而不是“$”;“EUR”而不是“€”。避免歧义($ 可能表示 USD、CAD 或 AUD)。
- 验证 JSON:使用 Pydantic / Zod 强制执行 Schema。如果无效,则携带错误重新提示模型。
- 连续一周手动抽查 1%,之后持续抽查 0.1%。跟踪字段级准确率,而不仅是记录级准确率。
如何选择模型
| 文档类型 | 推荐模型 |
|---|---|
| 简单结构化文档(发票、收据) | Claude Haiku 4.5 |
| 长合同 / 协议 | Claude Sonnet 5(支持长上下文) |
| 直接视觉处理(未经 OCR 的 PDF) | Claude Haiku 4.5;对于大页面使用 Claude Sonnet 5 |
| 高风险场景(法律、医疗) | Claude Sonnet 5 + 人工核验 |
| 批量导入(100K+/天) | Haiku 4.5 + few-shot 示例 + 缓存 |
合规注意事项
对于包含 PII 的文档(发票包含姓名、地址;医疗记录包含所有信息),请在提取前进行假名化,或在上游使用 Zero Data Retention。有关地区特定模式,请参阅合规指南;有关德国实践,请参阅DSGVO 深入指南。
开始使用:/app/signup——按需付费,充值 $10 可覆盖约 3,000 次发票提取,余额永不过期。阅读 /docs/chat 中的聊天文档,了解 response_format 对每个模型系列执行的约束,以及工具调用模式。
常见问题
使用 LLM 从文档中提取数据需要多少费用?
使用 Claude Haiku 4.5 每份文档约需 $0.003–$0.005,使用 Claude Sonnet 4.6 则约需 $0.02–$0.04。每月处理 10,000 张发票的成本约为 $30,而商业数据提取服务的费用为 $2,000–$5,000。
零样本 LLM 数据提取的准确率有多高?
零样本字段级准确率可达 95–98%,约需 30 行代码——准确率足以替代 OCR 加正则表达式的处理流程。
文档提取应该使用哪个模型?
发票、收据等简单的结构化文档使用 Claude Haiku 4.5。长篇合同使用 Claude Sonnet 4.6。直接以图像形式读取的文档使用 Claude Haiku 4.5;大页面则使用 Sonnet 4.6。
如何确保生产环境中的数据提取准确?
五种做法:明确处理 null、使用 ISO 8601 日期、使用 ISO 货币代码、进行架构验证并在输出无效时重新提示,以及人工抽查——第一周检查 1% 的输出,此后持续检查 0.1%。跟踪字段级准确率,而非记录级准确率。