Azure AI Content Understanding Python SDK 1.1.0解説:usageで実装・移行・自動化はどう楽になる?

Azure AI Content Understanding SDK for Python を使っている開発者にとって、2026年4月20日に公開された Azure AI Content Understanding Python SDK 1.1.0 の最大のポイントは、分析結果そのものではなく「分析にどれだけリソースを使ったか」をコードから扱いやすくなったことです。具体的には、AnalyzeLROPoller と AnalyzeAsyncLROPoller に usage プロパティが追加され、REST API が返す UsageDetails を Python SDK 経由で取得できるようになりました。これにより、RAG向けの文書解析、請求書抽出、音声・動画分析などを自動化する際に、処理単位の利用量ログ、しきい値監視、DevOpsパイプラインでのコスト制御を組み込みやすくなります。(GitHub)

目次

Azure AI Content Understanding Python SDK 1.1.0 の変更点

Azure AI Content Understanding Python SDK 1.1.0 は、派手なAPI刷新ではなく、運用面の見通しを良くするアップデートです。公式リリースでは、AnalyzeLROPoller と AnalyzeAsyncLROPoller に usage プロパティが追加され、課金やトークン消費の詳細を表す UsageDetails を公開する変更として説明されています。(GitHub)

この変更が重要なのは、Content Understanding の分析処理が「非同期の長時間実行操作」であるためです。SDKでは begin_analyze() や begin_analyze_binary() で処理を開始し、poller の .result() で完了を待つ流れになります。1.1.0では、完了後の poller から usage を取得できるため、分析結果と利用量を同じ実装フローで扱えます。(Microsoft Learn)

観点1.1.0で楽になること実務での効果
実装poller から usage を直接取得できるRESTレスポンスの手動解析や別ログ連携が減る
移行1.0.x系からは大きな書き換えなしで利用量取得を追加しやすい既存の分析コードに利用量ログを後付けしやすい
自動化operation ID と usage を同時に記録しやすいCI/CD、バッチ処理、監視基盤で分析単位の制御がしやすい
コスト管理ページ数、音声・動画時間、トークン消費を処理単位で確認できる想定外に重い入力やアナライザー設定を検知しやすい

まず押さえるべき前提:SDKは「結果取得」だけでなく運用自動化の入口になる

Azure AI Content Understanding は、文書、画像、音声、動画から構造化データやMarkdown、フィールド値、要約などを抽出するマルチモーダルAIサービスです。公式ドキュメントでは、PDFやOffice文書のテキスト・表・レイアウト抽出、音声の文字起こし、動画分析、プリビルトアナライザー、カスタムアナライザー、分類などの用途が挙げられています。(Microsoft Learn)

Python SDKは、REST APIを直接呼び出す代わりに、型付きモデル、長時間実行操作のポーリング、Azure認証、リトライなどを提供します。Microsoftの更新情報でも、Content Understanding のSDKは Python、.NET、Java、JavaScript/TypeScript 向けに提供され、公式SDKの利用が推奨されています。(Microsoft Learn)

開発者が今回の1.1.0で注目すべき点は、「抽出精度が上がったか」ではなく、本番運用で必要になるメトリクス取得がSDKレベルで扱いやすくなったかです。

たとえば、次のような処理では usage があるだけで設計が変わります。

ユースケース1.1.0以前に面倒だったこと1.1.0での改善
RAG用のPDF取り込み1ファイルごとのページ消費やトークン消費を把握しづらいpoller.usage をログ化して重い文書を特定できる
請求書・領収書の自動抽出入力件数だけでは実際の処理量が見えにくいページ数やトークンをジョブ単位で集計できる
音声・動画分析ファイル数では負荷を見誤りやすいaudio_hours や video_hours を監視に使える
DevOpsパイプラインテスト投入データが過剰でも気づきにくいusageしきい値を超えたらジョブを失敗させられる

インストールとバージョン確認

Azure AI Content Understanding SDK for Python 1.1.0 は Python 3.9以降が必要です。Microsoft LearnとPyPIでは、SDK 1.1.0 が API service version 2025-11-01 に対応することが示されています。(Microsoft Learn)

既存プロジェクトでは、まず依存関係を明示的に固定しておくのがおすすめです。

python -m pip install "azure-ai-contentunderstanding==1.1.0"
python -m pip install azure-identity

非同期APIを使う場合は、SDK本体に aiohttp が同梱されていないため、別途インストールします。

python -m pip install aiohttp

ローカル開発では .env にエンドポイントを置くケースが多いですが、本番ではKey Vault、マネージドID、CI/CDのシークレット管理などに寄せるべきです。公式ドキュメントでも、APIキー認証はテスト用途向けで、本番では DefaultAzureCredential などのより安全な認証が推奨されています。(Microsoft Learn)

export CONTENTUNDERSTANDING_ENDPOINT="https://<your-resource-name>.services.ai.azure.com/"

実装例:分析結果と usage を同じ処理で取得する

Azure AI Content Understanding Python SDK 1.1.0 では、分析完了後に poller.usage を参照します。重要なのは、usage は AnalysisResult ではなく poller側のプロパティ だという点です。

以下は、prebuilt-documentSearch でPDFを分析し、Markdownと利用量をログに出す最小構成の例です。

import json
import os

from azure.ai.contentunderstanding import ContentUnderstandingClient
from azure.ai.contentunderstanding.models import AnalysisInput
from azure.identity import DefaultAzureCredential


def main() -> None:
    endpoint = os.environ["CONTENTUNDERSTANDING_ENDPOINT"]

    client = ContentUnderstandingClient(
        endpoint=endpoint,
        credential=DefaultAzureCredential(),
    )

    poller = client.begin_analyze(
        analyzer_id="prebuilt-documentSearch",
        inputs=[
            AnalysisInput(
                url="https://example.com/sample.pdf",
                name="sample.pdf",
                mime_type="application/pdf",
            )
        ],
    )

    result = poller.result()

    content = result.contents[0]
    print(content.markdown[:1000] if content.markdown else "")

    usage = poller.usage
    if usage is None:
        print("usage is not available")
        return

    usage_log = {
        "operation_id": poller.operation_id,
        "analyzer_id": result.analyzer_id,
        "document_pages_minimal": usage.document_pages_minimal or 0,
        "document_pages_basic": usage.document_pages_basic or 0,
        "document_pages_standard": usage.document_pages_standard or 0,
        "audio_hours": usage.audio_hours or 0,
        "video_hours": usage.video_hours or 0,
        "contextualization_tokens": usage.contextualization_tokens or 0,
        "tokens": usage.tokens or {},
    }

    print(json.dumps(usage_log, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    main()

UsageDetails には、文書ページ数、音声処理時間、動画処理時間、コンテキスト化トークン、LLM・Embeddingトークンの内訳などが含まれます。文書ページ数は documentPagesMinimal、documentPagesBasic、documentPagesStandard のように処理レベル別に表現され、テキストやHTMLなど明示的なページを持たない入力では、3000 UTF-16文字を1ページとして数える仕様が説明されています。(Microsoft Learn)

非同期処理で usage を取る実装例

大量ファイルを扱うバッチ、キュー処理、Web APIバックエンドでは非同期APIを使う場面が多くなります。1.1.0では非同期版の AnalyzeAsyncLROPoller にも usage が追加されています。(GitHub)

import asyncio
import json
import os

from azure.ai.contentunderstanding.aio import ContentUnderstandingClient
from azure.ai.contentunderstanding.models import AnalysisInput
from azure.identity.aio import DefaultAzureCredential


async def analyze_one(file_url: str) -> dict:
    endpoint = os.environ["CONTENTUNDERSTANDING_ENDPOINT"]
    credential = DefaultAzureCredential()

    async with ContentUnderstandingClient(
        endpoint=endpoint,
        credential=credential,
    ) as client:
        poller = await client.begin_analyze(
            analyzer_id="prebuilt-documentSearch",
            inputs=[
                AnalysisInput(
                    url=file_url,
                    name="input.pdf",
                    mime_type="application/pdf",
                )
            ],
        )

        result = await poller.result()
        usage = poller.usage

        return {
            "operation_id": poller.operation_id,
            "analyzer_id": result.analyzer_id,
            "content_count": len(result.contents),
            "document_pages_standard": usage.document_pages_standard if usage else None,
            "contextualization_tokens": usage.contextualization_tokens if usage else None,
            "tokens": usage.tokens if usage else None,
        }


async def main() -> None:
    usage_log = await analyze_one("https://example.com/sample.pdf")
    print(json.dumps(usage_log, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    asyncio.run(main())

非同期処理では、分析結果の保存、利用量ログの保存、後続キュー投入を分けて設計すると運用しやすくなります。特にDevOpsチームは、operation_id、入力ファイル名、アナライザーID、実行環境、GitのコミットSHA、処理時間、usage を同じログレコードに残しておくと、後から「どのリリースで利用量が増えたか」を追跡できます。

usage で自動化しやすくなること

usage の価値は、単に画面に表示することではありません。開発・運用の自動化に組み込める点にあります。

バッチ処理で「重すぎる入力」を検知する

RAG向けの文書取り込みでは、1つの巨大PDFやOCRが重い資料が混ざるだけで、バッチ全体の処理時間や利用量が膨らみます。usage を保存しておけば、ページ数やトークン消費が大きいファイルを後から特定できます。

def build_usage_metrics(operation_id: str, usage) -> dict:
    token_total = sum((usage.tokens or {}).values()) if usage else 0

    return {
        "operation_id": operation_id,
        "document_pages_minimal": usage.document_pages_minimal or 0,
        "document_pages_basic": usage.document_pages_basic or 0,
        "document_pages_standard": usage.document_pages_standard or 0,
        "contextualization_tokens": usage.contextualization_tokens or 0,
        "token_total": token_total,
    }

このメトリクスをLog Analytics、Application Insights、Datadog、OpenTelemetry Collectorなどに送ると、アプリケーションログとAI処理の利用量を同じ文脈で見られます。

CI/CDで利用量の回帰を検知する

SDKのアップデート、アナライザー設定の変更、前処理ロジックの変更によって、同じテストデータでも利用量が増えることがあります。テスト用の固定PDFを用意し、usage の上限を超えたらCIを失敗させると、意図しない設定変更を早期に検知できます。

def assert_usage_within_budget(usage) -> None:
    if usage is None:
        raise AssertionError("UsageDetails is not available")

    token_total = sum((usage.tokens or {}).values())
    pages = (
        (usage.document_pages_minimal or 0)
        + (usage.document_pages_basic or 0)
        + (usage.document_pages_standard or 0)
    )

    if pages > 50:
        raise AssertionError(f"Too many processed pages: {pages}")

    if token_total > 200_000:
        raise AssertionError(f"Too many tokens consumed: {token_total}")

ここでのしきい値は課金額そのものではなく、運用上のガードレールです。実際の請求額は価格、リージョン、契約、サービス設定によって変わるため、usage は「処理単位の利用量メトリクス」として扱い、金額管理はAzureのコスト管理と合わせて確認するのが安全です。

入力範囲を制限して無駄な分析を減らす

begin_analyze_binary() では content_range を使って分析範囲を指定できます。文書では1始まりのページ番号、音声・動画ではミリ秒単位の範囲として扱われます。(GitHub)

from pathlib import Path

from azure.ai.contentunderstanding import ContentUnderstandingClient
from azure.identity import DefaultAzureCredential


endpoint = os.environ["CONTENTUNDERSTANDING_ENDPOINT"]
client = ContentUnderstandingClient(endpoint=endpoint, credential=DefaultAzureCredential())

pdf_bytes = Path("invoice.pdf").read_bytes()

poller = client.begin_analyze_binary(
    analyzer_id="prebuilt-invoice",
    binary_input=pdf_bytes,
    content_type="application/pdf",
    content_range="1-3",
)

result = poller.result()
usage = poller.usage

請求書や申込書のように、必要な情報が先頭数ページに集まっている業務では、ページ範囲を制限するだけで不要な処理を避けられる場合があります。ただし、フッター、明細、契約条件、添付書類などが後半ページにある業務では、安易な範囲指定で抽出漏れが起きます。まず検証用データで、抽出精度と利用量のバランスを確認してください。

移行判断:1.0.x利用者は上げやすいが、プレビュー利用者は注意

Azure AI Content Understanding Python SDK 1.1.0 は、1.0.x系から見ると usage の追加が中心です。既存の begin_analyze()、begin_analyze_binary()、result.contents の処理を大きく変える必要はなく、完了後に poller.usage を読む処理を追加するのが基本です。

一方、プレビュー版 1.0.0b1 から移行する場合は、GA版で型名や引数名が変更されています。リリース履歴では、AnalyzeInput が AnalysisInput、AnalyzeResult が AnalysisResult、MediaContent が AnalysisContent、MediaContentKind が AnalysisContentKind に変更されたことや、input_range が content_range に変わったことが記載されています。(GitHub)

現在の利用状況移行方針確認ポイント
1.0.0 / 1.0.1を利用中1.1.0へ更新し、poller.usage を追加既存テスト、型チェック、ログ出力の追加
1.0.0b1を利用中まずGA版の型名・引数名へ移行AnalysisInput、AnalysisResult、content_range など
REST APIを直接呼んでいるSDK化を検討手動ポーリング、認証、リトライ、型変換を減らせる
本番で大量バッチを実行中段階的にロールアウト利用量ログを比較し、しきい値監視を追加

移行時のおすすめ手順は次の通りです。

手順作業失敗しやすいポイント
依存関係を固定azure-ai-contentunderstanding==1.1.0 を指定暗黙アップデートで環境差分が出る
既存分析コードを実行代表的な入力で回帰テスト抽出結果だけでなく警告と処理時間も見る
usage ログを追加operation ID、analyzer ID、ページ数、トークンを保存usage が None のケースを考慮しない
しきい値を設定ページ数、トークン、音声・動画時間を監視初回から厳しすぎる値にして運用が止まる
本番へ段階展開小さなジョブから適用既存ログ形式を急に変えて監視が壊れる

実装前に確認したいリソース設定

SDKを入れただけでは Content Understanding は使えません。Microsoft Foundryリソース、権限、モデル配置、エンドポイント設定が必要です。公式ドキュメントでは、Content UnderstandingをサポートするリージョンにMicrosoft Foundryリソースを作成し、必要に応じてモデルをデプロイし、既定のモデルマッピングを構成する流れが説明されています。(Microsoft Learn)

特に詰まりやすいのは権限です。リソースの所有者であっても、API呼び出しやモデルデプロイ設定のために Cognitive Services User ロールの付与が必要とされています。(Microsoft Learn)

チェック項目確認内容
エンドポイントhttps://<resource-name>.services.ai.azure.com/ 形式のFoundryリソースエンドポイントを使っているか
認証本番では DefaultAzureCredential、マネージドID、サービスプリンシパルを優先しているか
権限実行ユーザーまたはサービスプリンシパルに Cognitive Services User が付与されているか
モデル配置利用するアナライザーに必要なモデルがデプロイされているか
既定マッピング複数リソースを使う場合、各Foundryリソースでモデルマッピングを設定しているか
非同期依存関係async API利用時に aiohttp を追加しているか

なお、プリビルトアナライザーの要件は種類によって変わります。たとえば、Read/Layout系の更新では、Foundryリソースにモデルが未設定でも動作できる旨が案内されています。一方で、ドキュメント検索、請求書、領収書、カスタムアナライザーなどではモデル配置やマッピングが必要になるケースがあります。対象アナライザーごとの要件を確認してから実装してください。(Microsoft Learn)

usage をログ設計に組み込むときの項目例

usage を取得できるようになったら、次はどの粒度で保存するかを決めます。おすすめは「分析1回につき1レコード」です。

ログ項目例目的
operation_idpoller.operation_id障害調査、結果ファイル取得、問い合わせ時の追跡
analyzer_idprebuilt-documentSearch利用量増加がどのアナライザー由来か見る
input_nameinvoice-001.pdf重い入力ファイルの特定
content_range1-3範囲指定の効果検証
document_pages_standard12文書処理量の把握
audio_hours / video_hours0.5音声・動画処理量の把握
contextualization_tokens12345コンテキスト生成や根拠付けの処理量把握
tokens{...}LLM・Embedding利用量の集計
duration_ms8450パフォーマンス監視
app_version2026.04.23-1リリース差分の比較

注意したいのは、ログに入力本文や抽出した個人情報をそのまま入れないことです。usage は運用メトリクスとして扱い、本文、フィールド値、Markdown、画像URL、SAS URLなどは必要最小限にしてください。特に請求書、本人確認書類、契約書、医療・金融系のデータを扱う場合、ログ基盤に流す情報はアプリ本体以上に慎重に設計する必要があります。

失敗しやすいポイントと対策

usage を .result() の前に読んでしまう

usage は完了後の分析操作から取得する情報です。SDKの実装上も、完了していない場合は None を返すようになっています。(GitHub)

poller = client.begin_analyze(
    analyzer_id="prebuilt-documentSearch",
    inputs=[AnalysisInput(url="https://example.com/sample.pdf")],
)

print(poller.usage)  # まだ完了していないため None の可能性が高い

result = poller.result()
print(poller.usage)  # 完了後に確認する

result.usage と書いてしまう

1.1.0で追加されたのは poller の usage です。AnalysisResult 側に利用量が入ると考えて実装すると、属性エラーや None 処理漏れにつながります。

result = poller.result()

# 非推奨の考え方
# usage = result.usage

# 1.1.0で見るべき場所
usage = poller.usage

usage が常に返る前提で実装する

APIや分析条件によっては、usage が取得できないケースも考慮すべきです。ログ保存や監視で usage is None をエラー扱いにするか、警告扱いにするかは用途で分けましょう。

本番バッチでは、初期段階は警告ログに留め、数週間の実データを見てから必須化するのが現実的です。

モデルデプロイ名の不一致

「Model deployment not found」や「Default model deployment not configured」のようなエラーは、モデルを配置していない、既定マッピングをしていない、環境変数のデプロイ名が実際の名前と違う、といった原因で起きやすいです。公式ドキュメントでも、必要モデルの配置、デフォルトモデルデプロイの設定、デプロイ名一致の確認がトラブルシューティング項目として挙げられています。(Microsoft Learn)

APIキーを本番の標準にしてしまう

APIキー認証は簡単ですが、漏えい時の影響が大きく、ローテーションや権限分離も難しくなります。検証環境ではAPIキーでも始められますが、本番では DefaultAzureCredential、マネージドID、サービスプリンシパルを使い、RBACでアクセスを絞る設計に寄せましょう。公式ドキュメントでもAPIキーはテスト用途向けとして注意喚起されています。(Microsoft Learn)

REST API直接実装からSDKへ寄せる判断基準

すでにREST APIで Content Understanding を呼んでいるチームは、すぐにSDKへ全面移行すべきとは限りません。ただし、次の条件に当てはまるならSDK化のメリットが大きくなります。

SDK移行を検討すべき状況理由
手動でポーリング処理を書いているSDKのLRO pollerで実装を単純化できる
レスポンスJSONの型変換が増えているAnalysisResult や UsageDetails の型付きモデルを使える
Entra ID認証やマネージドIDを使いたいAzure SDKの認証フローに乗せやすい
利用量ログを標準化したいpoller.operation_id と poller.usage を同じ場所で扱える
複数言語チームで同じ設計にしたいAzure SDKの設計ガイドラインに沿った実装に寄せやすい

一方で、既存のREST実装が安定しており、独自の再試行、監査ログ、プロキシ制御、署名付きURL管理まで作り込んでいる場合は、まず一部のバッチや新規機能からSDKを試すのが安全です。移行の目的を「SDKを使うこと」ではなく、「運用コードを減らし、利用量を可視化すること」に置くと判断を誤りにくくなります。

1.1.0を導入すべきチーム

Azure AI Content Understanding Python SDK 1.1.0 は、次のようなチームほど導入価値があります。

チーム導入価値
Developers分析結果と利用量を同じコードで扱えるため、実装とテストがしやすい
Platform engineers共通SDKラッパーに usage ログを組み込み、全サービスで標準化できる
DevOps teamsCI/CDやバッチ監視で、ページ数・トークン・音声動画時間をしきい値管理できる
RAG基盤チーム文書取り込み時の重いファイル、過剰なトークン消費、設定変更の影響を追跡できる
コンプライアンス重視のチームoperation ID単位で監査ログを整理しやすくなる

特に、RAG向けの文書取り込みや請求書・契約書の抽出処理は、入力データのばらつきが大きくなりがちです。ファイル数だけを見ていても実際の処理負荷は分かりません。usage をログ化しておくことで、「どの入力が重いのか」「どのアナライザー設定で増えたのか」「どのリリースから変化したのか」を後から説明できます。

導入後にやるべき次のアクション

Azure AI Content Understanding SDK for Python 1.1.0 の更新は、既存コードを大きく変えるものではありません。しかし、usage を活用すると、実装・移行・自動化の設計が一段実務寄りになります。

まずは次の順番で進めるのが現実的です。

優先度アクション
高依存関係を azure-ai-contentunderstanding==1.1.0 に固定する
高代表的な入力で既存の分析結果が変わらないか確認する
高poller.operation_id と poller.usage をログに保存する
中ページ数、トークン、音声・動画時間のしきい値を決める
中CI/CDやバッチ処理で利用量の回帰チェックを入れる
低将来的なSDK更新に備え、共通ラッパー化する

今回のリリースで見るべき本質は、「usageプロパティが増えた」という小さな差分ではなく、Content Understandingを本番ワークロードに組み込む際の観測性が上がったことです。既存の分析コードに poller.usage のログを追加し、まずは処理単位の利用量を見える化してください。そのデータが、移行判断、アナライザー選定、前処理の改善、コスト管理のすべての土台になります。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次