AI_EXTRACTでドキュメントから情報を抽出する

AI_EXTRACTは、自然言語で質問するか、抽出する情報を記述することで、テキストやドキュメントファイルから、エンティティ、リスト、テーブルなどの構造化情報を抽出できるCortex AI関数です。他の関数と組み合わせて、さまざまなユースケースに対応したカスタムドキュメント処理パイプラインを作成できます( Cortex AI 関数:ドキュメント をご参照ください)。

AI_EXTRACTは複数の言語のさまざまな形式のドキュメントを処理し、テキストの多い段落と、ロゴ、手書きテキスト(署名など)、テーブル、チェックマークなどのグラフィカルな形式のコンテンツの両方から情報を抽出できます。AI_EXTRACTは以下の構造化された形式で情報を抽出できます。

  • エンティティ:自然言語で質問するか、抽出する情報(都市、通り、またはZIPコードなど)。

  • リスト(または配列):JSONスキーマを提供して、銀行の明細書にあるすべての口座所有者の名前や、ドキュメントにあるすべての住所のリストなど、ドキュメントに存在する情報の配列またはリストを抽出できます。

  • テーブル:JSONスキーマを提供し、テーブルのタイトルと抽出する必要のある列のリストを指定して、ドキュメントに存在する表形式のデータを抽出します。

AI_EXTRACTは、複数のドキュメントを同時に処理することにより、ワークロードに合わせて自動的にスケーリングされます。ドキュメントは、不要なデータ移動を回避するために、オブジェクトストレージから直接処理できます。

注釈

AI_EXTRACT は現在、カスタム ネットワークポリシー と互換性がありません。

Tip

サポートされている言語、利用可能なリージョン、コストなど、AI_EXTRACTについて詳しくは、:doc:`/sql-reference/functions/ai_extract`を参照してください。

抽出品質

AI_EXTRACTは、高精度の抽出を実現する独自のビジョンベースの大規模言語モデル(LLM)である arctic-extract を使用します。次のテーブルは、さまざまな標準的なベンチマークでのモデルのスコアを、比較のために他の一般的なモデルのスコアと合わせて示しています。

視覚的な質問応答(VQA)

オファー

DocVQAスコア

人間の評価

0.9811

Snowflake Arctic-Extract

0.9433

Azure OpenAI GPT-o3

0.9339

Google Gemini 2.5-Pro

0.9316

Google Anthropic Claude 4 Sonnet

0.9119

Azure Document Intelligence + GPT-o3

0.8853

Google Document AI + Gemini

0.8497

Azure OpenAI GPT-o3

0.9339

AWS Textract

0.8313

テキストのみの質問応答(SQuAD v2)

オファー

ANLS

完全一致

Snowflake Arctic-Extract

81.18

78.74

Anthropic Claude 4 Sonnet

80.54

77.10

Meta LLaMA 3.1 405B

80.37

76.56

Meta LLaMA 4 Scout

74.30

70.70

OpenAI GPT 4.1

70.71

66.81

Meta LLaMA 3.1 8B

59.13

54.48

情報を抽出するための質問の最適化

AI_EXTRACTで作業するときは、自然言語を使用して、ドキュメントについて質問します。正確な回答を返す質問をするには、以下のガイドラインに従ってください:

  • わかりやすい英語を使ってください。

  • それぞれの質問について、期待される回答を把握しておきます。

  • 例えば、ドキュメントに複数の日付(発行日や署名日など)が記載されている場合、詳細を記載せずに「日付は何ですか?」と尋ねないでください。

  • 各質問で質問する値は1つにします。

  • AI_EXTRACT がこちらの意図を推測したり、特定の領域について幅広い知識を持っていることは期待しないでください。

例として次のドキュメントについて考えてみましょう。この売買契約書には、オファーの有効期限、買い手と売り手の名前、含まれる品目などの情報が含まれます。

ドキュメント例(コンドミニアムの売買契約書)。

次のテーブルは、AI_EXTRACTに尋ねることができる質問と、予想される回答の例です。

質問例

回答

この契約書の日付はいつですか?

'October 6, 2023'

マンションの購入者は誰ですか?

'John Davis', 'Jane Davis'

ユニットにはどのような家電製品が含まれていますか?

'stove/range', 'refrigerator', 'washer', 'dishwasher', 'attached television(s)', 'microwave'

フラットに含まれないものは何ですか?

'dryer', 'security system', 'satellite dish', 'wood stove', 'fireplace insert', 'hot tub', 'attached speaker(s)', 'generator'

フラットに乾燥機はありますか?

'No'

この売買契約書にはどのような補足書類が添付されていますか?

'22A (Financing)', '2AA (Appraisal)', '22FSBO (Owner Sale)'

販売者のファックス番号を教えてください。

なし

契約書に購入者の署名はありますか?

'No'

MLS番号は何ですか?

'59844680'

物件の住所は何ですか?

'604 Bishop Crossing Land, Fort Lauderdale, Broward County, FL, 33338'

テーブル抽出のベストプラクティス

このセクションでは、AI_EXTRACTでテーブル抽出を操作する際のベストプラクティスを提供します。

特定の種類のドキュメントには1つのスキーマを使用する

各抽出ワークロードには同じ種類のドキュメントが含まれている必要があり、抽出するデータはほとんどのテーブルで類似している必要があります。ソースドキュメントの列数がドキュメントごとに異なっていても、すべてのドキュメントに抽出する列のサブセットが定義されており、共通の列の名前と場所が同じか類似している場合は、それらの共通の列を抽出できます。

たとえば、請求書にはさまざまなデータを含む異なる数の列がある場合がありますが、すべてのテーブルに同じ最初の3列がある場合 --- Item DescriptionQuantityPrice ---そのデータを抽出できます。

自然言語を使用して列名を定義する

ドキュメントから列名をコピーすると、完全に同じ名前にすることができます。たとえば、列名を product_codeREPORT_DATE ではなく、Product CodeReport Date にしてください。

空の行をスキップする

微調整データセットを作成するときは、回答のない(返される回答が``None``になる)行をスキップします。

ドキュメントに表示される順序で列を定義します

精度を改善させるために、ドキュメントに表示されるのと同じ順序で列を定義します。通常、列は左から右、または 転置されたテーブル の場合は上から下になります。順序を異なる方法で定義することを選択した場合は、トレーニングが必要になる可能性があります。

ただし、``Invoice Number``や``Invoice Date``など、複数の行で値が同じになる列の場合は、先頭にこれらの列を追加します。例:

  • Invoice Number

  • Invoice Date

  • Item Code

  • Item Name

  • Quantity

ドキュメントの大文字と小文字を使用して値を定義する

可能であれば、ドキュメントの大文字と小文字を使用して値を定義します。ドキュメント内で大文字と小文字が異なる場合は、大文字を使用します。

説明フィールドを使用する

AI_EXTRACTの応答形式の``description``フィールドはオプションです。ほとんどの場合、入力する必要はありません。ただし、ドキュメントに複数の類似したテーブルがある場合、モデルは不正確な回答をする可能性があります。回答が予想と異なるソーステーブルから取得される場合や、モデルがテーブルを見つけられない場合は、``description``フィールドを使用してみてください。テーブルのタイトルや番号など、モデルが正しいテーブルを識別するのに役立つ情報を追加します。

テーブルのレイアウトを説明するセクション列を追加する

テーブルが複数の名前付きセクションに分割されている場合は、セクション列を追加します。これにより、モデルはレイアウトをより適切に理解し、精度を改善させることができます。たとえば、列に SectionItem section、または Item category という名前を付けることができます。セクションに2番目のレベルのネストがある場合は、SectionSubsection の2つの列を追加できます。

値をグループ化するには、追加の列を作成します

既存のテーブルに列を追加して、値をグループ化できます。このようにして、ドキュメント全体の結果を1つのテーブルに結合することができます。例:

請求書番号

アイテムの詳細

アイテム価格

数量

A

アイテムA1

10.00

1

A

アイテムA2

20.00

1

A

アイテムA3

30.00

1

B

アイテムB1

15.00

1

B

アイテムB2

25.00

1

B

アイテムB3

35.00

1

最初の列の値は、対応するアイテムに対して繰り返されていることに注意してください。

列名をドキュメント間で区別できるようにする

列を意味的に区別するようにしてください。col1val1item1 のような名前は使用しないでください。

特に行名がドキュメント間で相違しないか、わずかに異なり、限られた値の集合内に収まっている場合は、転置の方がうまく機能する場合もあります。

指定された列セットでトレーニングすると、結果が改善する可能性があります。

階層ヘッダーを扱う場合、親名をプレフィックスとして使用します

階層ヘッダーを持つテーブルから情報を抽出するには、各親名をプレフィックスとして使用してヘッダーパスを結合します。たとえば、次のテーブルの場合、列を次のように定義します。

  • Category A Type X Column 1

  • Category A Type Y Column 2

  • Category A Type Y Column 3

  • Category B Column 4

  • Category B Column 5

カテゴリAおよびカテゴリBという名前のヘッダーを持つテーブル。カテゴリAにはサブヘッダーが含まれています。型Xおよび型Y。

必要に応じてテーブルを転置する

ドキュメントのテーブルの最初の列の値を出力テーブルの列名として使用することで、転置されたテーブルから情報を抽出することができます。

たとえば、次のテーブルの場合、列に名前を付けます。

  • Type A: Item 1

  • Type A: Item 2

  • Type B: Item 3

  • Type B: Item 4

転置できるテーブルの例。

この例には、 階層ヘッダー が含まれていることに注意してください。

大きなテーブルの場合、ドキュメントを分割します

テーブル抽出のモデルでは、最大4096トークンの長さの回答が返されます。これは、モデルがその制限に達すると抽出を停止することを意味します。これには次のような方法でアプローチできます。

  • テーブルが複数のページにまたがっている場合は、ドキュメントを複数の1ページのドキュメントに分割し、後処理で結果を結合します。

  • テーブルが密で、1つのページからでもデータを抽出できない場合は、テーブルを列ごとに分割します。

    たとえば、テーブルに10列ある場合は、テーブルの左半分の5列と右半分の5列を使用して、2つの別々の値を定義してみてください。最良の結果を得るには、列の選択を試してみる必要がある場合があります。

ドキュメント内で名前のない列に名前を作成する

ドキュメントの最初の列に名前がない場合は、値を定義するときに自分でその名前を作成する必要があります。これは次の方法でアプローチできます。

  • テーブルのタイトルまたはタイトルの重要な部分を使用します。

  • 列内のデータを表すわかりやすい名前を作成します。例:descriptiontype of assetyearcategory

2つの異なる期間のデータを比較する

年間レポートなどの財務ドキュメントで、2023年と2024年など、2つの異なる期間のデータを比較する場合は、列の先頭に「現在」と「前回」を付けることができます。結果を改善するにはトレーニングが必要になる場合があります。

例:売買契約書から情報を抽出する

次の例では、:ref:`label-ai_extract_question_optimization`セクションで表示できるコンドミニアムの売買契約書から情報を抽出します。

エンティティを抽出する

売り手の名前とオファーの有効期限を抽出します。

SELECT AI_EXTRACT(
  file => TO_FILE('@db.schema.stage','document.pdf'),
  responseFormat => [['seller_name', 'What is the seller name?'], ['address', 'What is the offer expiration date?']]
);
Copy

結果:

{
    "error": null,
    "response": {
        "address": "12/12/2023",
        "seller_name": "Paul Doyle"
    }
}
Copy

チェックボックス情報を抽出する

ドキュメントでマークされたチェックボックスに基づいて、含まれていない項目に関する情報を抽出します。

SELECT AI_EXTRACT(
  file => TO_FILE('@db.schema.stage','document.pdf'),
  responseFormat => [['flat_items', 'What items are not included with the flat?'], ['default', 'What Default is selected?']]
);
Copy

結果:

{
    "error": null,
    "response": {
        "default": "Forfeiture of Earnest Money",
        "flat_items": "dryer, security system, satellite dish, wood stove, fireplace insert, hot tub, attached speaker(s), generator, other"
    }
}
Copy

署名ステータスを抽出する

契約が署名されているかどうかに関する情報を抽出します。

SELECT AI_EXTRACT(
    file => TO_FILE('@db.schema.stage','document.pdf'),
    responseFormat => [['signature', 'Is this document signed?']]
);
Copy

結果:

{
  "error": null,
    "response": {
        "signature": "no"
    }
}
Copy

エンティティのリストを抽出する

購入者名のリストを抽出します。

SELECT AI_EXTRACT(
    file => TO_FILE('@db.schema.files', 'report.pdf'),
    responseFormat => {
        'schema': {
        'type': 'object',
        'properties': {
            'buyer_list': {
            'description': 'What are the buyer names?',
            'type': 'array'
            }
        }
        }
    }
);
Copy

結果:

{
    "error": null,
    "response": {
        "buyer_list": [
        "John Davis",
        "Jane Davis"
        ]
    }
}
Copy

例:テーブルから情報を抽出する

この例では、次のドキュメントから情報を抽出します。

テーブル:グレンジャー因果性検定 - P値
SELECT AI_EXTRACT(
    file => TO_FILE('@db.schema.files', 'report.pdf'),
    responseFormat => {
        'schema': {
            'type': 'object',
            'properties': {
                'income_table': {
                'description': 'Table 2: Granger Causality Tests - P-values',
                'type': 'object',
                'column_ordering': ['description', 'countries','lags','z','z_approx'],
                'properties': {
                    'description': {
                        'description': 'Description',
                        'type': 'array'
                        },
                    'countries': {
                        'description': 'Countries',
                        'type': 'array'
                        },
                    'lags': {
                        'description': 'Lags',
                        'type': 'array'
                        },
                    'z': {
                        'description': 'Z',
                        'type': 'array'
                    },
                    'z_approx': {
                        'description': 'Z approx.',
                        'type': 'array'
                    }
                }
            }
        }
    }
);
Copy

結果:

{
    "error": null,
    "response": {
        "income_table": {
            "countries": [
                "33","80","29","84","34"
            ],
            "description": [
                "Commodity exporters",
                "Non-commodity exporters",
                "AE",
                "EMDE",
                "Large or market-dominant countries"
            ],
            "lags": [
                "2","1","1","1","1"
            ],
            "z": [
                "0.11","0.08","0.89","0.12","0.07"
            ],
            "z_approx": [
                "0.25","0.19","0.95","0.25","0.14"
            ]
        }
    }
}
Copy