文档解析与信息抽取
合同、发票、对账单转结构化数据,图片和扫描件交给支持识图的模型,带文字层的 PDF、Word 先提取文本再交给文本模型,两路都要求按 JSON 输出,再由程序校验字段。按每月 1 万页扫描件加 5,000 份文本合同估算,用最低价分组计算,模型费用每月约 ¥178。
价格更新于 2026年11月12日 20:17|
01
业务问题
财务、法务和供应链每天要从发票、合同、对账单、装箱单里把数据抄进系统。版式一多,传统 OCR 加规则的方案维护起来很费劲,供应商换个模板就得重新配置。
识图大模型能直接看懂不同版式的票据和表格,按你给的字段名返回 JSON。它也会读错、漏字段,偶尔把看不清的值猜出来,所以结果必须先校验再入库。
更稳的做法是按文档类型先定好字段清单,让模型严格按清单输出,再用程序检查格式和金额合计,校验不过的进入人工复核。
02
推荐模型组合
读图片与扫描件(识图模型)
gemini-3.8-flashGoogle输入 ¥1.5 / 输出 ¥7.5 每百万 tokens· 标准分组直接读取发票照片、扫描版合同、表格截图,按字段返回 JSON。图片会换算成输入 tokens,分辨率越高 tokens 越多,可以先把图片缩到文字清晰可读的尺寸。
处理文本型文档(对话模型)
deepseek-v4.1-flashDeepSeek输入 ¥2.8 / 输出 ¥11.2 每百万 tokens· 国产模型分组有文字层的 PDF、Word、邮件正文先用程序提取文本,再交给文本模型抽取条款、日期和金额。不需要识图,单价更低,适合长合同。
推荐模型按实时目录自动选取,价格取各模型最低价分组,更新于 2026年11月12日 20:17。点模型名可查看全部分组价格。
03
参考架构
- 1
分类与预处理
先判断文档类型(发票、合同、对账单)。能提取文字层的直接取文本;扫描件和照片转成图片,压缩到合适的分辨率。
- 2
定义字段
每类文档写一份字段清单:字段名、类型和格式(日期统一 YYYY-MM-DD,金额用数字),写进提示词。
- 3
调用模型
图片走识图模型,文本走文本模型,temperature 设为 0,用 response_format 要求返回 JSON。部分模型不支持 response_format,就在提示词里要求只返回 JSON,并在代码里截取 JSON 部分。
- 4
程序校验
检查必填字段、日期和金额格式;发票核对明细合计与总额,合同核对各个日期的先后。不合格的自动重试一次。
- 5
人工复核
重试后仍不合格、或金额超过阈值的单据进入人工复核队列,复核结果回写系统,典型错例可以加进提示词当示例。
04
成本估算
假设:每月处理 1 万页发票和扫描件,每页输入约 2,000 tokens(图片约 1,500、指令约 500),输出约 400 tokens;另有 5,000 份带文字层的合同,每份输入约 6,000 tokens,输出约 600 tokens。
| 项目 | 模型 | 用量假设 | 费用 |
|---|---|---|---|
| 扫描件与图片抽取 | gemini-3.8-flash | 10,000 次 × 输入 2,000 + 输出 400 tokens | ¥60 |
| 文本合同抽取 | deepseek-v4.1-flash | 5,000 次 × 输入 6,000 + 输出 600 tokens | ¥117.6 |
| 合计(每月) | ¥177.6 | ||
按各模型最低价分组的实时价格计算,价格更新于 2026年11月12日 20:17。
只含模型调用费用,不含预处理、存储和人工复核成本。图片换算成多少 tokens 因模型和分辨率而异,表中按每页约 1,500 tokens 估算,实际以响应里的 usage 为准。页数翻倍,费用大致翻倍。
05
示例代码
把图片转成 base64 放进 image_url,要求模型按字段清单返回 JSON,再检查字段是否齐全。
import base64
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://open.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])
FIELDS = ["invoice_number", "issue_date", "seller_name", "buyer_name", "total_amount", "currency"]
PROMPT = (
"Extract these fields from the invoice image and reply with one JSON object only: "
+ ", ".join(FIELDS)
+ ". Use null for anything you cannot read. Dates as YYYY-MM-DD, amounts as numbers."
)
def parse_json(text):
"""Some models add text around the JSON; keep the outermost object."""
return json.loads(text[text.find("{"): text.rfind("}") + 1])
def extract(path):
with open(path, "rb") as f:
data_url = "data:image/png;base64," + base64.b64encode(f.read()).decode()
resp = client.chat.completions.create(
model="gemini-3.8-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": PROMPT},
{"type": "image_url", "image_url": {"url": data_url}},
],
}],
response_format={"type": "json_object"},
temperature=0,
)
record = parse_json(resp.choices[0].message.content)
missing = [k for k in FIELDS if k not in record]
if missing:
raise ValueError("missing fields: " + ", ".join(missing))
return record
print(extract("invoice.png"))
# Text-layer PDFs and Word files: extract the text yourself and send it to deepseek-v4.1-flash with the same field list.常见问题
每月处理 1.5 万份文档要多少钱?
按 1 万页扫描件(每页输入约 2,000 tokens)加 5,000 份文本合同(每份输入约 6,000 tokens)估算,用最低价分组计算约 ¥178。图片分辨率和合同长度对费用影响最大。
抽取结果能保证准确吗?
不能保证。模型可能读错模糊的数字、漏掉字段,所以结果要经过程序校验(格式、合计、必填项),关键单据保留人工复核。
PDF 可以直接发给模型吗?
有文字层的 PDF 建议先用程序提取文字,再发给文本模型,费用更低;扫描版 PDF 先转成图片,每页一张交给识图模型。
模型不按 JSON 返回怎么办?
优先用 response_format 要求 JSON。模型不支持时,在提示词里写明只返回 JSON,代码里截取第一个左花括号到最后一个右花括号之间的内容再解析,解析失败就重试。
涉及敏感信息的合同能用吗?
请求会经本站转发给模型服务处理。包含个人信息或商业机密的文档,建议先脱敏(隐去身份证号、银行账号等)再提交,并按你们自己的数据合规要求评估。