PAYATHON 2026

如何修复 Layout 3.1 容器 JSON 响应缺少语言数据

架构老王

结论

languages 是 Layout 3.1 的可选分析功能,使用 prebuilt-layout 时不会自动启用。调用 begin_analyze_document() 时,必须显式传入 DocumentAnalysisFeature.LANGUAGES。如果没有传入,响应中的 "languages": [] 是正常结果。

Document Intelligence Studio 通常会启用对应的附加分析功能。因此,同一份 PDF 在 Studio 或另一段云端调用代码中可能返回语言信息,而容器调用没有返回。比较结果前,需要先确认两边的请求参数一致,不能只看模型名称。

正确启用语言检测

使用 azure-ai-formrecognizer==3.3.0 时,可以这样调用:

from azure.ai.formrecognizer import (
    DocumentAnalysisClient,
    DocumentAnalysisFeature,
)
from azure.core.credentials import AzureKeyCredential

client = DocumentAnalysisClient(
    endpoint="http://localhost:5000",
    credential=AzureKeyCredential("YOUR_API_KEY"),
)

with open("sample.pdf", "rb") as document:
    poller = client.begin_analyze_document(
        model_id="prebuilt-layout",
        document=document,
        features=[DocumentAnalysisFeature.LANGUAGES],
    )

result = poller.result()

for language in result.languages or []:
    print(
        f"locale={language.locale}, "
        f"confidence={language.confidence}, "
        f"spans={language.spans}"
    )

如果还需要其他附加功能,可以一起传入:

features=[
    DocumentAnalysisFeature.LANGUAGES,
    DocumentAnalysisFeature.KEY_VALUE_PAIRS,
]

只添加当前容器版本实际支持的功能。云服务支持某项功能,不代表正在使用的容器镜像也支持。

使用 REST API 验证

要排除 SDK 序列化或版本匹配问题,可以直接向容器发送 REST 请求。需要确认查询参数中包含:

features=languages

例如:

curl -i -X POST \
  "http://localhost:5000/formrecognizer/documentModels/prebuilt-layout:analyze?api-version=2023-07-31&features=languages" \
  -H "Content-Type: application/pdf" \
  --data-binary "@sample.pdf"

这个请求通常会先返回 202 Accepted,之后需要根据响应头中的 Operation-Location 继续轮询。不同容器镜像的路由约定可能略有不同,应以对应镜像的 API 文档和实际响应为准。

如果 REST 调用能够返回语言信息,而 SDK 调用不能,重点检查以下几项:

  • SDK 请求中是否确实包含 features=languages
  • azure-ai-formrecognizer 的实际运行版本是否为 3.3.0
  • 请求是否发往预期的容器地址,而不是另一套服务
  • 反向代理是否删除或重写了查询参数

可以先确认运行时的包版本:

import azure.ai.formrecognizer

print(azure.ai.formrecognizer.__version__)

日志中的两类信息

Not a TIFF or MDI file

Not a TIFF or MDI file, bad magic number 20517 (0x5025).

PDF 文件通常以 %PDF 开头,其中 0x50 0x25 对应 %P。这条日志很可能产生于格式探测阶段:解析器先尝试将文件识别为 TIFF 或 MDI,识别失败后再进入 PDF 处理流程。

如果请求最终成功,页面和文本也能正常返回,这条信息通常不是 languages 为空的原因。

BillingInternalServerError

Failed to track On-Premises Usage
errorCode='BillingInternalServerError'

这表示容器向配置的 Azure 计量终结点提交用量时失败。可以从以下方面排查:

  • Billing URL 是否正确
  • ApiKey 是否属于对应的 Document Intelligence 资源
  • 容器能否通过 DNS、代理和防火墙访问该终结点
  • 系统时间和 TLS 证书链是否正常
  • Azure 资源是否仍然有效

这个错误与语言检测参数是两个不同的问题。如果文档分析仍能成功返回结果,它通常无法解释为什么只有 languages 数组为空。不过,计量失败也不能长期忽略,因为容器需要有效的 Azure 计费配置才能合规、稳定地运行。

如果启用后仍然为空

可以按以下顺序排查:

  1. 确认请求参数中确实存在 features=languages。

  2. 对同一个容器发送 REST 请求,排除 SDK 层的差异。

  3. 检查容器的实际构建版本。日志中显示的是:

    Form Recognizer Layout 2023-07-31 20240203.1
    
  4. 查看该镜像版本的功能支持表,确认 Layout 容器支持 languages 附加功能。

  5. 拉取或固定到 Microsoft 当前建议的 Layout 3.1 镜像版本后重新测试,避免继续使用旧的缓存镜像。

  6. 比较容器与云服务的完整请求,不要只比较 model_id="prebuilt-layout"。

  7. 如果 REST 请求明确包含 features=languages,但容器仍持续返回空数组,而云服务对同一文件可以返回结果,应保存以下材料并提交 Azure 支持请求:

    • 完整的镜像名称和标签
    • 容器 Build information
    • API 版本
    • 已脱敏的请求 URL 及查询参数
    • requestId
    • 最小复现 PDF
    • 容器响应与云服务响应的差异

还需要注意,locale 参数和语言检测不是一回事。locale 用于向 OCR 提供语言或区域提示,features=languages 才会要求服务在结果中生成 languages 数据。

备注:内容仅供参考。