首页
/ Docling 托管服务实战:用 Docling for IBM watsonx 将文档转换能力以 HTTP 服务方式接入应用

Docling 托管服务实战:用 Docling for IBM watsonx 将文档转换能力以 HTTP 服务方式接入应用

2026-09-06 13:35:34作者:姚月梅Lane

本篇基于 managed.md 展开,讲解 Docling 托管服务的定位与选型逻辑:它相对自建 docling-serve 省去了哪些运维工作、如何通过服务 URL + API Key 的极简方式接入现有应用与 AI Agent,并给出从 REST 原始调用到 Python 客户端、CLI 命令的完整接入路径,以及客户端在超时、重试、用量限额等场景下的真实行为(均有源码佐证)。

为什么选择托管服务

自行部署 docling-serve 意味着你要自己经营整套基础设施:服务器、GPU、扩缩容、模型升级、运行监控。managed.md 明确列出托管服务消除的正是这些工作,具体拆解为三点:

1. 无需运行任何基础设施(No infrastructure to run)

没有服务器、没有 GPU、没有扩容、没有升级、没有运维监控——服务由提供方托管维护。对照 deployment.md 中自托管需要处理的内容(进程编排、计算引擎、Redis 队列、API Key 配置),托管服务把这些全部收敛到服务提供方一侧。对读者而言,这意味着可以把精力从"怎么把服务跑起来"转移到"怎么用好文档理解能力"。

2. 集成方式简单(Simple integration)

托管服务暴露与自托管服务器完全相同REST API。把它接入应用或 AI Agent 只需一次 HTTP 调用——把客户端指向托管端点即可。客户端代码保持可移植性:从自托管切换到托管服务,通常只需要更换 base URL 并补一个 API Key。这一"可移植性"在仓库源码中有一致的体现:

  • Python 客户端 DoclingServiceClient 的构造函数签名就是 url + api_key 两个核心输入,见 client.py
  • CLI 的 convert-remote 命令凭据解析优先级同样是"flag > 环境变量 > .env 文件",与自托管服务共用同一套客户端实现,见 remote.py

3. 与开源版本相同的 Docling 转换(Same Docling conversion)

托管服务执行与开源库、开源服务器相同的文档理解流程和输出格式——Markdown、JSON(DoclingDocument)、HTML、doctags 等格式、OCR、表格结构、增强(代码/公式/图片/图表)能力保持一致。换句话说,托管不是"缩水版 API",而是同一引擎的托管实例,你在本地用 DocumentConverter 验证过的转换行为,在托管端点上是可预期的。

当前可用的托管服务:Docling for IBM watsonx

managed.md 目前列出的托管服务是 Docling for IBM watsonx:一个完全托管、由 IBM 托管运行的 Docling 服务实例,暴露与这些文档页面描述的同一套 REST API。使用方式就是提供两个东西——服务 URL 和 API Key——然后像调用任何其他端点一样调用它。产品页面可在 IBM 官方渠道("Docling for IBM watsonx" 产品页)获取,本文不输出外部链接。

从仓库代码结构看,客户端对托管服务的处理是通用化的:代码中没有任何针对特定云厂商的特判,url 参数可以是任意实现了 docling-serve REST 契约的端点。这正是"同一 REST API"这一承诺在工程上的含义——接入新托管服务不需要改客户端代码,只需换 URL 和 Key。

接入方式一:直接调用 REST API

托管服务与自托管服务的端点完全一致,参考 rest_api.md

端点 方法 用途
/v1/convert/source POST 从 URL / base64 源转换(同步)
/v1/convert/file POST 上传文件转换,multipart(同步)
/v1/convert/source/async/v1/convert/file/async POST 提交异步任务
/v1/status/poll/{task_id} GET 轮询任务状态
/v1/status/ws/{task_id} WebSocket 订阅任务状态
/v1/result/{task_id} GET 获取已完成的结果

认证:服务端要求 API Key 时(自托管侧由 DOCLING_SERVE_API_KEY 开启),每个请求都要携带:

-H "X-Api-Key: <YOUR_KEY>"

对托管服务,把 rest_api.md 示例中的 http://localhost:5001 替换为你的托管服务 base URL 即可,例如提交一次异步转换:

curl -X POST "https://<your-managed-service-host>/v1/convert/source/async" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: <YOUR_KEY>" \
  -d '{"http_sources": [{"url": "https://arxiv.org/pdf/2501.17887"}]}'

响应体中 task_id 用于后续 GET /v1/status/poll/{task_id} 轮询与 GET /v1/result/{task_id} 取回结果;任务状态机为 pending | started | success | failure。完整的请求/响应 schema 在任何运行中的服务上都可通过 /docs(OpenAPI / Swagger)在线查看,这在评估托管服务时是权威参照——文档可能滞后,/docs 不会。

接入方式二:Python 客户端 SDK

仓库自带 Python 客户端 docling.service_client,返回与本地 DocumentConverter 相同的 ConversionResult,无需手搓 HTTP 调用:

from docling.service_client import DoclingServiceClient
from docling.datamodel.service.options import ConvertDocumentsOptions

with DoclingServiceClient(
    url="https://<your-managed-service-host>",
    api_key="YOUR_API_KEY",   # 服务未启用鉴权时省略
) as client:
    result = client.convert(
        source="https://arxiv.org/pdf/2501.17887",   # 也支持 Path / DocumentStream
        options=ConvertDocumentsOptions(to_formats=["md"]),
    )

print(result.document.export_to_markdown())

source 接受 HTTP/HTTPS URL 字符串、本地 pathlib.PathDocumentStream;多文档用 convert_all(source=[...], max_concurrency=4) 并发转换,返回迭代器逐个产出 ConversionResult。可运行的完整示例见 convert.pyREADME

从源码看,这个客户端为"托管场景"做了几个值得注意的设计(均位于 client.py):

  • URL 校验_normalize_base_url 要求传入绝对 http(s) base URL,且不允许把 /v1 拼进 base URL(端点前缀由客户端自动补全),传错会在构造期立即报 ValueErrorclient.py)。
  • 鉴权头:设置 api_key 后,所有 HTTP 请求自动附加 X-Api-Key 头,WebSocket 状态订阅则在 URL 查询参数中携带 api_keyclient.py)。
  • 版本协商:客户端自动附加 Accept-Docling-Document-Version 头,告知服务端其安装的 docling-core 能读取的 DoclingDocument 版本,必要时服务端会向下投影(client.py)——这对跨版本使用托管服务的兼容性有实际意义。
  • 批量语义convert() 默认在状态非 success/partial_success 时抛出 ConversionErrorraises_on_error=True);convert_all() 内部会强制附加 JSON 输出格式以便重建 DoclingDocumentclient.py)。

安装方式:托管场景通常只需 pip install "docling-slim[service-client]",不必安装完整模型栈(见 README)。

接入方式三:docling convert-remote 命令行

CLI 提供了 convert-remote 子命令,内部就是驱动上面这个同步客户端,并复用与本地 convert 相同的导出器,因此写入本地的输出与 docling convert 完全一致remote.py)。它同时适用于自托管服务与托管服务:

# 凭据来自环境变量或工作目录 .env
docling convert-remote report.pdf

# 显式端点 + Key,输出 Markdown 和 JSON 到 ./out
docling convert-remote --service-url https://<your-managed-service-host> \
  --api-key "$KEY" --to md --to json --output ./out report.pdf

# 整个目录,只处理 PDF 和 DOCX,禁用 OCR
docling convert-remote --from pdf --from docx --no-ocr ./inbox

凭据解析(优先级:flag > 环境变量 > .env 文件):

参数 环境变量 说明
--service-url DOCLING_SERVICE_URL 服务 base URL,必填
--api-key DOCLING_SERVICE_API_KEY API Key,服务未启用鉴权时可省略

工作目录存在 .env 文件时会自动加载(override=False,即真实环境变量优先于 .env),见 remote.py

常用参数(完整列表见 docling convert-remote --help):

参数 默认值 说明
--from 全部支持格式 输入格式白名单,同时用于目录过滤
--to md 本地写出格式,可重复
--no-ocr / --force-ocr OCR 开 / 不强制 位图内容是否走 OCR
--ocr-lang 逗号分隔的 OCR 语言
--pipeline standard 服务端处理 PDF/图像所用管线
--enrich-code 服务端增强开关(code / formula / picture 分类 / picture 描述 / chart)
--page-range 仅转换页码范围,如 1-4(从 1 开始)
--document-timeout 服务端处理单文档超时(秒)
--max-concurrency 8 并发文档数上限(客户端侧)
--timeout 300.0 客户端等待每个任务的超时(秒)
--watcher websocket 任务状态跟踪方式:websocketpolling
--output . 结果输出目录

源码上可以看到几个与托管场景直接相关的行为:

  1. 先做健康检查再干活:命令执行时先调用 client.health(),服务不可达会立即以退出码 1 失败并打印 Cannot reach service at <url>remote.py),避免大批量提交后才发现端点写错。
  2. 只暴露服务端认可的可选项option_kwargs 只映射 ConvertDocumentsOptions 中服务会处理的字段;本地执行类参数(device、线程、PDF 后端内部参数、调试可视化器)被刻意排除(remote.py)。这提示一个事实边界:CLI 的选项集是服务端契约的投影,托管服务如果未开启某些增强模型,对应请求会被服务端拒绝或忽略,以该服务的 /docs 为准。
  3. 退出码约定:0 成功;1 运行时/连接失败(服务不可达、转换错误);2 用法/配置错误(三个来源都解析不到 service URL)(remote.py),便于在脚本和 Agent 工作流中做分支处理。
  4. URL 源不会被本地下载:http(s) URL 直接作为 HTTP 源请求发给服务端,由服务端抓取(remote.py)——对托管服务来说这通常更高效,也避免大文件过客户端。

客户端的可靠性行为:超时、重试与用量限额

托管服务通常有网关、限流与配额,客户端在 client.py 中对此有明确处理,了解这些行为有助于排错:

  • 服务端 500/502:指数退避重试(基数 1 秒),默认 http_retries=3,耗尽后抛 ServiceUnavailableErrorclient.py)。
  • 429/503 限流:优先读取响应头 Retry-After(支持秒数与 HTTP-date 两种格式)作为等待时间,同样受重试次数约束(client.py)。
  • 402 支付要求:被解释为用量超限——客户端解析 UsageLimitExceededResponse 并抛出携带 currentUsagelimitUsageLimitExceededErrorclient.py)。这是托管服务特有的信号:请求本身合法,但账户配额/计费被触发,属于业务错误而非瞬时故障,不应盲目重试。异常类定义见 exceptions.py
  • 任务级超时job_timeout 默认 300 秒,由 WebSocket 状态观察者(默认)或轮询观察者执行,WebSocket 失败可回落到轮询(ws_fallback_to_poll=True),见 client.py
  • 并发上限max_concurrency 默认 8、硬上限 512,越界在构造期报错(client.py)。
  • 产物下载防护:对预签名产物 URL 做 SSRF 防护(只允许全局可路由地址,拒绝内网/回环/链路本地地址),防止被恶意或错误配置的服务指向客户端内网(client.py)。

这些行为对自托管服务同样生效,因此把它们理解为"客户端对任何 docling-serve 端点的通用契约"即可。

接入自检清单

把托管服务(如 Docling for IBM watsonx)接入生产前的核对项:

  1. 连通性:先 GET /health(或 client.health())确认端点与 Key 有效;再打开 /docs 核对可用端点与 schema 版本。
  2. 鉴权:确认 Key 通过 X-Api-Key 头传递,并避免把它写进代码仓库;CLI 场景可用环境变量或 .env
  3. 选项裁剪:只发送该服务 /docs 中声明的转换选项;增强类开关(公式、图表、图片描述)以服务端实际部署的模型为准。
  4. 异步优先:长文档建议走 /async 端点 + 轮询/WebSocket,避免同步长请求被网关断开;客户端 SDK 的 convert/convert_all 已内置该生命周期。
  5. 错误分类:区分瞬时错误(5xx/429,可重试)、业务错误(402 用量超限,应停并发并检查配额)与任务失败(TaskExecutionError,看 failure 详情)。

小结与延伸阅读

managed.md 的核心主张可以浓缩为一句话:托管服务用"同一个 REST API + 一个 base URL + 一个 API Key"换取了全部基础设施运维。当前可用的托管服务为 Docling for IBM watsonx;接入侧有原始 REST、Python 客户端(docling/service_client)、docling convert-remote CLI 三种等价路径,且客户端在重试、限额、超时方面有明确的、源码可查的行为。继续深入可阅读 API server 总览REST API 参考部署文档 以及 客户端示例目录

登录后查看全文
热门项目推荐
相关项目推荐