メインコンテンツへスキップ
企業の調達ドキュメントがたった数個のフラットなフィールドで済むことなどほぼありません。1社のサプライヤ契約書には複数の段落や表にわたって、ベンダーの連絡先情報、納期のマイルストーン、出荷先の場所、支払条件が記載されます。 このチュートリアルでは、複雑な情報をわかりやすく構造化された出力に変換する方法を説明します。Box AI抽出 (構造化) のstructおよびtableフィールドタイプを使用してドキュメントの形式に合わせたスキーマを定義した後、抽出エージェント (強化) で抽出エンドポイントを呼び出して、下流システム、自動化、Boxメタデータに使用できる状態のデータを返します。

構築する内容

このチュートリアルの最後には、次のような機能を備えた、動作するPythonプロジェクトが完成します。
  • Boxに対する認証を実行し、Boxフォルダに保存されているサプライヤ契約書を読み取る。
  • グループ化されたベンダー詳細データにstructフィールドを使用し、繰り返しの納品スケジュールにtableフィールドを使用する抽出スキーマを定義する。
  • 抽出エージェント (強化) を使用してPOST /2.0/ai/extract_structuredエンドポイントを呼び出す。
  • レスポンスを、ERP、調達プラットフォーム、プロジェクトトラッカーにプッシュできるように調達レポートにマッピングする。

構造および表を選ぶ理由

POST /2.0/ai/extract_structuredエンドポイントは、stringfloatdateenummultiSelectなどのスカラー型に加え、2つの複雑なフィールドタイプをサポートしています。
フィールドタイプ戻り値用途
struct単一のネストされたJSONオブジェクトベンダーの正式名称、住所、連絡先情報など、属性が同じ関連のある値。
table同じスキーマを持つJSONオブジェクトの配列納期のマイルストーン、明細行、支払いスケジュールなど、繰り返し出現する行。
これらのタイプを使用すると、データが実際にどのように使用されているかを反映させることができます。抽出後に1つの長大なベンダーブロックを解析したり、納品スケジュールを単一の文字列にまとめたりするのではなく、結果をサプライヤのマスターレコードまたは調達ワークフローに直接マッピングします。
両方のフィールドタイプと、それらがサポートするサブフィールドのタイプの詳細なリファレンスについては、を参照してください。

前提条件

始める前に、以下が揃っていることを確認してください。
  • Box AI APIへのアクセスを提供する無料の
  • クライアント資格情報許可認証で構成されたBoxアプリケーション。
  • Python 3.11以上。
  • Boxにアップロードされたサプライヤ契約書。をダウンロードして、それをBoxフォルダにアップロードできます。そのファイルIDはURLで決まることに注意してください。たとえば、URLがhttps://app.box.com/file/123456789の場合、ファイルIDは123456789となります。
  • アプリで以下のスコープが有効になっていること。
    • Boxに格納されているすべてのファイルとフォルダの読み取りと書き込み
    • AIを管理する

手順

このチュートリアルでは、Box Platformの機能とBox AIエージェントをそれぞれ1つずつ使用します。
コンポーネント目的API
Box AI Extractグループ化された構造化データや繰り返し構造を持つ構造化データを契約書から取得するPOST /2.0/ai/extract_structured
抽出エージェント (強化)ネストされたフィールドや繰り返し出現するフィールドの精度を向上させるai_agent.id = enhanced_extract_agent
抽出エージェント (強化) は、あらかじめ定義されたBox AIエージェントであるため、自分で作成したり構成したりする必要はありません。これは、以下で説明する抽出関数の構築ステップで構築する抽出リクエストのai_agentパラメータのID (enhanced_extract_agent) で参照されます。詳細については、 に関するリファレンスを参照してください。
1

開発環境のセットアップ

  1. ターミナルを開き、新しいプロジェクトディレクトリを作成します。
mkdir supplier-extraction && cd supplier-extraction
  1. Pythonの仮想環境を作成してアクティブ化します。
python3 -m venv .venv
source .venv/bin/activate
アクティブ化すると、ターミナルのプロンプトの先頭に(.venv)と表示されます。これにより、仮想環境内で作業していることがわかります。
新しいターミナルウィンドウやタブを開くたびに、プロジェクトディレクトリからsource .venv/bin/activateを実行して、仮想環境を再アクティブ化します。コマンドの実行中にModuleNotFoundErrorが表示される場合、通常、venvがアクティブ化されていないことを意味します。
  1. 必要なパッケージをインストールします。
pip install box-sdk-gen python-dotenv
  1. 資格情報を保存するための.envファイルを作成し、以下の内容を追加します。プレースホルダの値を、Box開発者コンソールで確認した実際の資格情報で置き換えます。
BOX_CLIENT_ID=your_client_id
BOX_CLIENT_SECRET=your_client_secret
BOX_ENTERPRISE_ID=your_enterprise_id
AGREEMENT_FILE_ID=your_file_id
.envファイルはバージョン管理システムにコミットさせないでください。.env.gitignoreに追加します。
2

Boxクライアントの認証

box_client.pyという名前のファイルを作成して次のコードを追加します。これにより、SDKを通じてBox AIを呼び出す際に使用する、認証済みのクライアントが作成されます。
import os
from dotenv import load_dotenv
from box_sdk_gen import BoxClient, BoxCCGAuth, CCGConfig

load_dotenv()

def get_box_client() -> BoxClient:
    config = CCGConfig(
        client_id=os.getenv("BOX_CLIENT_ID"),
        client_secret=os.getenv("BOX_CLIENT_SECRET"),
        enterprise_id=os.getenv("BOX_ENTERPRISE_ID"),
    )
    auth = BoxCCGAuth(config=config)
    return BoxClient(auth=auth)
エンドユーザーが関与しないサーバー間の自動化には、クライアント資格情報許可をお勧めします。その他の認証オプションについては、 を参照してください。
CCGアプリケーションは、コンテンツへのアクセス権限が自動的には付与されない別個のサービスアカウントユーザーとして動作します。サービスアカウントのメールアドレス (開発者コンソールの [一般設定] で確認可能) を、契約書が保管されているフォルダのコラボレータとして招待します。アクセス権限がない場合は、APIコールで404 Not foundが返されます。
3

抽出スキーマの定義

schema.pyという名前のファイルを作成して以下のコードを追加します。このスキーマでは、2つの複雑なフィールドを使用して契約書を記述しています。
  • vendorは、関連するベンダーの詳細を1つのネストされたオブジェクトにグループ化するstructフィールドです。
  • delivery_scheduleは、マイルストーンごとに1行を返すtableフィールドです。
上記の複雑なフィールドはそれぞれ、そのサブフィールドを定義するfields配列を必要とします。サブフィールドではスカラー型のみがサポートされます。ネストされたstructまたはtable型は使用できません。
from box_sdk_gen import CreateAiExtractStructuredFields

EXTRACTION_FIELDS = [
    CreateAiExtractStructuredFields(
        key="agreement_effective_date",
        display_name="Effective date",
        type="date",
        prompt="The date the agreement takes effect.",
    ),
    CreateAiExtractStructuredFields(
        key="payment_terms",
        display_name="Payment terms",
        type="string",
        prompt="The payment terms, for example Net 30.",
    ),
    CreateAiExtractStructuredFields(
        key="vendor",
        display_name="Vendor",
        type="struct",
        prompt="The vendor or supplier issuing the agreement.",
        fields=[
            CreateAiExtractStructuredFields(key="legal_name", type="string", display_name="Legal name"),
            CreateAiExtractStructuredFields(key="address", type="string", display_name="Address"),
            CreateAiExtractStructuredFields(key="country", type="string", display_name="Country"),
            CreateAiExtractStructuredFields(key="contact_person", type="string", display_name="Contact person"),
            CreateAiExtractStructuredFields(key="email", type="string", display_name="Email"),
            CreateAiExtractStructuredFields(key="phone", type="string", display_name="Phone"),
        ],
    ),
    CreateAiExtractStructuredFields(
        key="delivery_schedule",
        display_name="Delivery schedule",
        type="table",
        prompt="Each delivery milestone defined in the agreement.",
        fields=[
            CreateAiExtractStructuredFields(key="phase", type="string", display_name="Phase"),
            CreateAiExtractStructuredFields(key="items", type="string", display_name="Items"),
            CreateAiExtractStructuredFields(key="delivery_date", type="date", display_name="Delivery date"),
            CreateAiExtractStructuredFields(key="destination", type="string", display_name="Destination"),
            CreateAiExtractStructuredFields(key="status", type="string", display_name="Status"),
        ],
    ),
]
表の抽出は、視覚的にフォーマットされた表に限定されません。tableタイプは、グリッド、キー/値ペア、フォームレイアウト、単なる文のいずれとして表示されている場合でも、繰り返しデータを抽出します。
4

抽出関数の構築

extract.pyという名前のファイルを作成して以下のコードを追加します。これは、SDKのcreate_ai_extract_structuredメソッドを使用してスキーマをBox AIに送信し、抽出エージェント (強化) を指定します。これにより、ネストされたフィールドや繰り返し出現するフィールドの精度が向上します。
from box_sdk_gen import AiItemBase, AiAgentReference, AiAgentReferenceTypeField
from box_client import get_box_client
from schema import EXTRACTION_FIELDS

def extract_agreement(file_id: str) -> dict:
    client = get_box_client()

    response = client.ai.create_ai_extract_structured(
        items=[AiItemBase(id=file_id)],
        fields=EXTRACTION_FIELDS,
        ai_agent=AiAgentReference(
            id="enhanced_extract_agent",
            type=AiAgentReferenceTypeField.AI_AGENT_ID,
        ),
    )

    return response.to_dict()["answer"]
抽出エージェント (強化) は厳密には必須ではありませんが、特にネストされたフィールドや繰り返し出現するフィールドが含まれている場合、より詳細なスキーマや複雑なドキュメントレイアウトにおいて結果の精度が向上します。
5

構造化された出力のマッピング

app.pyという名前のファイルを作成して以下のコードを追加します。Box AIは、vendorフィールドをネストされたオブジェクトとして返し、delivery_scheduleフィールドを行のリストとして返します。このスクリプトは、抽出を実行し、その結果を下流システムで使用できるフラットなレコードにマッピングします。
import json
import os
from dotenv import load_dotenv
from extract import extract_agreement

load_dotenv()

def to_procurement_record(answer: dict) -> dict:
    vendor = answer.get("vendor", {})
    schedule = answer.get("delivery_schedule", [])

    return {
        "vendor_name": vendor.get("legal_name"),
        "vendor_country": vendor.get("country"),
        "vendor_contact": vendor.get("contact_person"),
        "vendor_email": vendor.get("email"),
        "payment_terms": answer.get("payment_terms"),
        "effective_date": answer.get("agreement_effective_date"),
        "milestones": [
            {
                "phase": row.get("phase"),
                "due": row.get("delivery_date"),
                "destination": row.get("destination"),
                "status": row.get("status"),
            }
            for row in schedule
        ],
    }

if __name__ == "__main__":
    file_id = os.getenv("AGREEMENT_FILE_ID")

    answer = extract_agreement(file_id)
    print("Raw extraction:")
    print(json.dumps(answer, indent=2))

    record = to_procurement_record(answer)
    print("\nProcurement record:")
    print(json.dumps(record, indent=2))
この時点でプロジェクトディレクトリには、以下のファイルが含まれていることになります。
supplier-extraction/
├── .env
├── .venv/
├── app.py
├── box_client.py
├── extract.py
└── schema.py
6

抽出の実行

仮想環境がアクティブ化されているsupplier-extractionディレクトリを開いていることを確認したら、スクリプトを実行します。
python3 app.py
Box AIは、structフィールドを単一のネストされたオブジェクトとして返し、tableフィールドをオブジェクトのリストとして返します。出力は次のようになります。
{
  "agreement_effective_date": "2026-06-01",
  "payment_terms": "Net 45",
  "vendor": {
    "legal_name": "Nexus Industrial Solutions Ltd.",
    "address": "47 Canary Wharf, Level 12, London, E14 5AB",
    "country": "United Kingdom",
    "contact_person": "Oliver Hartmann",
    "email": "o.hartmann@nexusindustrial.co.uk",
    "phone": "+44 20 7946 0832"
  },
  "delivery_schedule": [
    {
      "phase": "Phase 1 - Infrastructure",
      "items": "Server Racks (qty 6), UPS (qty 3)",
      "delivery_date": "2026-07-15",
      "destination": "Chicago, IL",
      "status": "Scheduled"
    },
    {
      "phase": "Phase 2 - Networking",
      "items": "48-Port Switches (all), Fibre Cables (all)",
      "delivery_date": "2026-08-01",
      "destination": "Chicago, IL",
      "status": "Scheduled"
    },
    {
      "phase": "Phase 3 - Security",
      "items": "NGFW Cluster (all), Remaining Racks",
      "delivery_date": "2026-08-20",
      "destination": "San Francisco, CA",
      "status": "Pending"
    },
    {
      "phase": "Phase 4 - Services",
      "items": "Installation, Training",
      "delivery_date": "2026-09-01",
      "destination": "San Francisco, CA",
      "status": "Pending"
    }
  ]
}
その後、このスクリプトはマッピングされた調達レコードを出力します。これは、お使いのERP、調達プラットフォーム、プロジェクトトラッカーに送信できます。

トラブルシューティング

仮想環境がアクティブ化されていません。python3コマンドを実行する前に、プロジェクトディレクトリからsource .venv/bin/activateを実行してください。新しく開いたターミナルタブは、すべて個別にアクティブ化する必要があります。
以下のように、.envファイルを確認します。
  • BOX_CLIENT_IDおよびBOX_CLIENT_SECRETが、開発者コンソール > [構成] の値と一致していることを確認します。
  • BOX_ENTERPRISE_IDが自分のEnterprise IDであることを確認します。
  • アプリが開発者コンソールで承認されていて、クライアント資格情報許可を使用していることを確認します。
サービスアカウントに、そのファイルへのアクセス権限がありません。開発者コンソール > [一般設定] に記載されているサービスアカウントのメールアドレスを、契約書が保管されているフォルダのコラボレータとして招待します。
ネストされたstructおよびtableタイプは、サブフィールドとしてサポートされていません。また、structまたはtableフィールドにはfields配列を含める必要があります。サブフィールドにはスカラー型のみが使用されていることを確認し、抽出対象を明確にするために複雑なフィールドにpromptを追加してください。

本番環境へのスケーリング

契約書をBox内で検索可能およびルーティング可能にするには、フラット化されたトップレベルの値をメタデータインスタンスとしてファイルに書き戻したうえで、を使用して、ベンダー、国、または発効日でフィルタをかけます。エンドツーエンドのメタデータ書き戻しパターンについては、を参照してください。
スクリプトを手動で実行せず、契約書のフォルダにWebhookを登録して、アップロードが行われるたびに抽出が開始されるようにします。受信したリクエストを実稼働環境で検証する方法については、を参照してください。
フィールドレベルのpromptを抽出のガイドとして追加し、表が密集している複数ページの契約書に対して抽出エージェント (強化) を引き続き使用します。複数のドキュメント間でスキーマの一貫性を維持には、フィールドをインラインではなくで定義してください。

次の手順

請求書の取り込み自動化

フォルダに新しい請求書がないか監視し、フィールドを抽出して検索可能なメタデータとして書き戻します。

APIリファレンスの抽出

抽出 (構造化) のための詳細なAPI仕様を確認します。
最終更新日 2026年7月8日