国内团队接入 OCR API,第一反应通常是比较识别率,然后直接调接口。真正上线后才发现,时间大多耗在接入层:图片能不能稳定传上去、晚高峰链路是否可用、账单用美元还是人民币、发票能不能入账,以及批量任务跑到一半失败后怎么续跑。

OCR 和聊天 API 的差别在于输入是图片或 PDF,请求体更大、超时更常见、重试更容易产生重复费用。本文比较官方直连、自建代理和国内 AI 网关三条路线,重点讲图片上传、限流、故障切换与核验清单。具体服务与计费以站内模型价格及服务商文档为准。

说明:OpenAI、Claude、Gemini、百度智能云、腾讯云、阿里云等名称是其各自权利人的商标;本文仅作技术讨论,与相关厂商无隶属或代理关系。跨境网络、数据出境与支付结算需遵守所在地法律法规及平台服务条款。

一、三条路线先摆清楚

官方直连是直接调用 OCR 厂商或模型厂商的接口。若使用国内云厂商的 OCR,链路和付款本来就在境内,通常最省事;若使用海外视觉模型,则要自行处理跨境网络、美元账单和汇率。直连的优点是文档与功能同步快,出了问题能直接对照厂商说明排查。

自建代理是在合规服务器上部署反向代理或网关,把鉴权、日志、重试和限流收口。控制力强,但服务器、证书、升级和值班都由自己承担。OCR 场景还要额外调整请求体上限和超时,否则大图很容易在代理层被截断。

国内 AI 网关提供 OpenAI 兼容入口,人民币结算,通常带控制台、用量统计和发票。接入成本低,也便于统一多个模型;需要确认服务主体、数据条款、限额规则和故障响应方式。

维度 官方直连 自建代理 国内 AI 网关
网络与接入 国内厂商链路短;海外模型需跨境 线路可自选,需自行运维 国内入口,通常开箱可用
图片上传 受厂商请求体与格式限制 需同步调整代理层限制 看网关的请求体与超时配置
付款与发票 国内厂商人民币;海外模型美元 取决于账号与服务器主体 人民币结算,通常可开发票
批量与限流 受厂商 QPS、并发和配额约束 可做队列,但仍受上游限制 看网关限额、调度与重试能力
数据边界 需自行评估出境与条款 数据位置自行负责 需审查服务商条款与资质
运维成本 中,主要是网络与账号 高,服务器、证书、监控 低,控制台集中管理
模型覆盖 以单一厂商为主 可自行扩展 通常覆盖多家模型

没有一条路线适合所有团队。只用国内云 OCR、付款和发票顺畅,直连最省事;需要固定出口与审计,选自建代理;没有运维人力、又要统一多家视觉模型账单,再评估国内网关。

二、网络与图片上传:先解决 413 和超时

OCR 请求体比文本请求大得多。一张 3 MB 的图片转成 Base64 后会增大约三分之一,变成约 4 MB;如果接口只收 Base64,客户端、反向代理和网关都要放开请求体上限。常见故障往往不是“识别不准”,而是 413、连接重置、超时和半截响应。

几个实践建议:

  • 接口支持 URL 或对象存储预签名地址时,优先用 URL 传图,减少请求体。确认链接在识别完成前保持有效,且不需要登录态。
  • 按业务可接受的分辨率压缩,但不要压过头。小字、印章、手写和表格线对清晰度很敏感,建议按长边和文件大小双阈值压缩,并保留原图以便复核。
  • 按 EXIF 方向旋转后再上传,避免整页横置导致识别顺序错乱。
  • 代理层同步调整 client_max_body_size、proxy_read_timeout 和 proxy_send_timeout,不要只改应用侧超时。
  • 多页 PDF 优先使用异步任务接口,而不是把整份文件塞进一次同步请求。

如果由服务商拉取图片 URL,还要确认该地址公网可达、没有 IP 白名单限制,且签名有效期足够覆盖排队时间。

三、付款、合同与发票

国内团队常见的卡点是付款主体。个人卡充值、代付和报销凭证不一致,财务往往无法入账。选方案前先问清楚:合同和谁签、结算币种是什么、能开什么类型的发票、预付款是否有有效期、退款规则如何。

按量计费还要确认账单口径:按图片张数、PDF 页数、请求次数还是 Token 计费;失败请求是否计入;重试是否重复计费;用量能否按项目或 Key 拆分。把这些写进采购对比表,再用同一批图片实测,才能估算真实成本。具体费用以模型价格和合同为准。

四、限流、并发与批量任务

OCR 接口通常同时受 QPS、并发数、单图大小、PDF 页数和账号日配额约束。429 不一定代表服务异常,可能只是瞬时并发过高。批量识别建议按下面的顺序设计:

  1. 为每张图片或每个 PDF 计算 SHA-256,作为幂等键,先查本地结果表再决定是否提交。
  2. 按接口限制拆分任务:单图大小、单请求页数、并发上限分别设阈值。
  3. 并发从低开起,例如先 2–4 路,观察 429 比例和 P95 延迟后再逐步增加。
  4. 对 429 和瞬时 5xx 做指数退避加随机抖动;401、403 和参数错误不要重试,先修配置。
  5. 异步任务记录 task_id、提交时间、状态和结果地址,结果文件及时落盘,因为结果链接往往有过期时间。
  6. 每批结束统计成功数、失败数、计费张数和耗时,失败样本单独进入重跑队列。
  7. 全量结束后抽样人工复核,并核对入库条数与原文件数量。

五、重试、幂等与故障切换

重试之前先做幂等,否则一次网络抖动可能变成两次费用、两条重复记录。下面的示例用图片哈希标记请求,并对可重试错误做退避:

import base64
import hashlib
import os
import time
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZSQH_API_KEY"],
    base_url=os.environ["ZSQH_BASE_URL"],
    timeout=90.0,
    max_retries=0,
)

def ocr_image(path, model, attempts=4):
    raw = open(path, "rb").read()
    key = hashlib.sha256(raw).hexdigest()
    data_url = "data:image/jpeg;base64," + base64.b64encode(raw).decode()
    for i in range(attempts):
        try:
            resp = client.chat.completions.create(
                model=model,
                messages=[{
                    "role": "user",
                    "content": [
                        {"type": "text", "text": "识别图中的全部文字,按原顺序输出。"},
                        {"type": "image_url", "image_url": {"url": data_url}},
                    ],
                }],
            )
            return key, resp.choices[0].message.content
        except Exception as exc:
            if i == attempts - 1:
                raise
            wait = min(2 ** i, 30) + 0.5 * (i + 1)
            print(key[:8], type(exc).__name__, "retry in", wait)
            time.sleep(wait)

key, text = ocr_image("invoice.jpg", os.environ["VISION_MODEL"])
print(key[:12], len(text))

故障切换有一个容易忽略的边界:不同 OCR 引擎的输出不能直接混用。传统 OCR 返回文字和坐标,视觉大模型返回自然语言或 JSON,字段名、坐标体系和置信度口径都可能不同。切换前应固定一组真实样本,比较字符准确率、字段准确率和结构化输出成功率;解析代码、校验规则和人工复核流程要一起调整,而不是只改一个模型名。

六、上线前的核验清单

  • 链路:大图、多页 PDF、晚高峰时段分别压测,记录 413、超时和 5xx 比例。
  • 准确率:用 50–100 张真实图片覆盖清晰、模糊、倾斜、手写、表格和多栏版式。
  • 用量:响应中的 usage 或张数与后台账单能否对上,重试是否被重复计费。
  • 限流:并发上限、429 比例、退避后成功率是否可接受。
  • 数据:图片是否含个人信息或商业机密,服务方的保留、日志和删除策略是否说得清。
  • 退出:Key 能否轮换,余额能否退款,旧服务和回退路线是否保留。

任何一项说不清,都建议先小流量试跑,不要直接把生产流量切过去。

七、按约束选型

先看网络与付款能否长期稳定,再看是否需要固定出口与审计,最后看模型范围和账单能力。使用国内云 OCR 且流程顺畅,直连即可;使用海外视觉模型、又没有跨境运维人力,可以评估国内网关。需要统一入口、人民币结算和多模型对比,可以在中商起航 AI 网关创建测试 Key,先用小批量图片跑通,再逐步放量;可选模型与计费方式见模型价格。

相关阅读:

常见问题

国内直连海外 OCR 接口稳定吗?

取决于本地出口、时段、目标区域和账号限额,不能一概而论。建议用真实图片和真实并发连续观察几天,记录错误率与 P95 延迟,再与网关方案做对照,不要仅凭一次成功请求下结论。

图片用 Base64 还是 URL 上传?

小图用 Base64 简单直接;大图、多页 PDF 或高并发场景优先用 URL 或对象存储预签名地址,能显著减小请求体。无论哪种方式,都要确认接口的大小限制、格式要求和链接有效期。

OCR 批量识别中断了怎么续跑?

用图片内容哈希做幂等键,按批落盘,失败只补缺失部分。重跑前核对已入库条数与原文件数量,避免重复写入,也避免把半批结果当成完整结果。

切换 OCR 服务后结果格式会变吗?

通常会。不同引擎的字段名、坐标体系、置信度和错误结构都可能不同,结构化输出还需要重新做 schema 校验。迁移时应保留旧结果一段时间,并用固定样本对比新旧输出。

发票和用量能按项目拆分吗?

取决于服务方。签约前确认能否按项目、Key 或模型导出用量,账单口径是否包含失败和重试请求,以及发票内容能否匹配采购要求。