【ChatGPT(FunctionCalling)+AI Vision】手書き請求書の構造データ化

はじめに

今までKSCブログではChatGPTの基本的な使い方についてご紹介してきましたが、
今回はもう少し踏み込んで、周辺サービスと連携した活用方法をご紹介します。

数年前までは実現できなかったことが、非常に簡単に実現できるようになっていますので、
是非最後まで御覧頂きたいと思います。

FunctionCalling機能を活用

今回はChatGPTのFunctionCalling機能を活用します。
FunctionCallingとは、ChatGPTが知らなかったり、実現できないことを、外部の関数を実行して解決する仕組みです。
以下がイメージです。

ChatGPTにプロンプトと一緒に、自前で用意した関数の定義情報を提供します。
そうすると、ChatGPTは提供された関数定義から「どの関数」を「どの引数」で実行するべきかを判断してくれます。
単純ですが、「判断してくれる」点と「引数を作成してくれる」点が非常に強力です。
この機能を活用して、手書き請求書を構造化されたデータにしてみます。

実現イメージ

流れは以下のようなイメージです。

①アプリは、Azure AI Visionを使って手書き請求書をテキスト化します
②アプリは、「データ出力してください」というお願いと、OCR結果テキストと、
 データを出力する為の関数定義情報を渡します
③ChatGPTは、実行すべき関数の指示と、実行に必要な引数を作成し返却します
④アプリは、ChatGPTが作成した引数を使用して関数を実行します

Azure AI Visionで手書き請求書をテキスト化

以下のような手書き請求書を作成し、Azure AI Visionにテキスト化してもらいました。

Azure AI Visionは単純なテキスト情報やテキストの位置情報なども返却してくれますが、
今回は単純なテキスト情報だけを使って、ChatGPTに指示してみたいと思います。
こちらが、単純なテキスト情報です。

****************************************
請 求 書 株式会社システムコンサルタント 御中 No. 112345 請求日2023/11/21 下記のとおり、御請求申し上げます。 サンプル株式会社 件名 システム構築プロジェクト 〒100-0001 支払期限 2023/12/31 東京都千代田区千代田1-1-1 振込先 サンプル銀行 1234567 サンプルビル3階 サンプル(カ TEL : 03-0000-0000 担当:サンプル太郎 合計 27,987,332(税込) 登録番号:T1234567890123 摘要 数量 単位 1-1 単価 税率 金額 ようけんていぎ 1 10, 000,000 10% 10,000,000 外部設計 1 む 12,345 698 8% 12,345 678 内部設計 1 340,000 10% 340,000 製造 式式 1 1,000,000 8% 1,000,000 テスト 12 1 式 2,000,000 10% 2,000,000 ※は軽減税率対象 小計 25 685,678 税率別内訳 税抜金額 消費税額 消費税 2,301,654 10%対象 12:340,000 1.234,000 合計 27 987 332 軽減8%対象 13.345,678 1.069,654 0%対象 備考
****************************************

ごちゃごちゃしていてよくわからない上に、
「12:340,000」とか「1.234,000」はOCRあるあるの間違いですね。
忖度せずこのまま使います。

関数定義情報の作成

今回は単純にログ出力するだけの関数にします。関数情報を以下の通り定義しました。
長いですが、要は請求データを受け取って出力しますよということが書かれています。
引数の型までしっかり指定することで、ChatGPTが引数を正しく作成してくれるようになるわけです。

    "functions": [  
        {
        "name": "outputBillData",
        "description": "請求書情報を出力します",
        "parameters": {
            "type": "object",
            "properties": {
                "billing_company_name": {
                    "type": "string",
                    "description": "請求先企業名"
                },
                "billing_source_company_name": {
                    "type": "string",
                    "description": "請求元企業名"
                },
                "billing_source_tel": {
                    "type": "string",
                    "description": "電話番号"
                },
                "billing_source_address": {
                    "type": "string",
                    "description": "住所"
                },
                "billing_source_tekikakuNo": {
                    "type": "string",
                    "description": "適格請求書登録番号"
                },
                "title": {
                    "type": "string",
                    "description": "請求書件名"
                },
                "payment_deadline": {
                    "type": "string",
                    "description": "支払期限"
                },
                "payee": {
                    "type": "string",
                    "description": "支払先"
                },
                "total": {
                    "type": "number",
                    "description": "税込合計金額"
                },
                "billing_statement": {
                    "type": "array",
                    "description": "請求書の明細項目の配列",
                    "items": {
                    	"type": "object",
                        "description": "請求書の明細項目、商品名、数量、金額等がセットされる",
                    	"properties": {
			                "item_name": {
			                    "type": "string",
			                    "description": "商品名"
			                },
			                "item_quantity": {
			                    "type": "string",
			                    "description": "数量"
			                },
			                "item_unit": {
			                    "type": "string",
			                    "description": "単位"
			                },
			                "item_unit_price": {
			                    "type": "number",
			                    "description": "単価"
			                },
			                "item_tax_rate": {
			                    "type": "number",
			                    "description": "税率"
			                },
			                "item_price": {
			                    "type": "number",
			                    "description": "金額"
			                }
                    	
                    	}
                    }
                },
                "sub_total": {
                    "type": "number",
                    "description": "税抜き商品合計"
                },
                "tax_total": {
                    "type": "number",
                    "description": "税金合計"
                },
                "tax_10per_item": {
                    "type": "number",
                    "description": "10%税金対象となる商品金額合計"
                },
                "tax_10per": {
                    "type": "number",
                    "description": "10%税金対象となる商品の税金額合計"
                },
                "tax_8per_item": {
                    "type": "number",
                    "description": "8%税金対象となる商品金額合計"
                },
                "tax_8per": {
                    "type": "number",
                    "description": "8%税金対象となる商品の税金額合計"
                }
                
            },
            "required": ["total"]
        }
    }
]

プロンプト、OCR結果、関数情報をChatGPTに渡す

いよいよ、ChatGPTにお願いしてみます。

【プロンプト】
以下の情報は、手書きの請求書をOCRで読み取ったデータです。
精度が悪い部分もありますが、補正しつつ、請求書情報を出力してください。
~省略 OCRテキスト情報と関数定義情報~

そうすると、ChatGPTは「outputBillData」関数を「この引数」で呼び出してと返却してきました。
関数実行結果がこちらです。

{
  "billing_company_name": "株式会社システムコンサルタント",
  "billing_source_company_name": "サンプル株式会社",
  "billing_source_tel": "03-0000-0000",
  "billing_source_address": "〒100-0001 東京都千代田区千代田1-1-1 サンプルビル3階",
  "billing_source_tekikakuNo": "T1234567890123",
  "title": "システム構築プロジェクト",
  "payment_deadline": "2023/12/31",
  "payee": "サンプル銀行 1234567",
  "total": 27987332,
  "billing_statement": [
    {
      "item_name": "要件定義",
      "item_quantity": "1",
      "item_unit": "-",
      "item_unit_price": 10000000,
      "item_tax_rate": 10,
      "item_price": 10000000
    },
    {
      "item_name": "外部設計",
      "item_quantity": "1",
      "item_unit": "-",
      "item_unit_price": 12345678,
      "item_tax_rate": 8,
      "item_price": 12345678
    },
    {
      "item_name": "内部設計",
      "item_quantity": "1",
      "item_unit": "-",
      "item_unit_price": 340000,
      "item_tax_rate": 10,
      "item_price": 340000
    },
    {
      "item_name": "製造",
      "item_quantity": "1",
      "item_unit": "-",
      "item_unit_price": 1000000,
      "item_tax_rate": 8,
      "item_price": 1000000
    },
    {
      "item_name": "テスト",
      "item_quantity": "1",
      "item_unit": "-",
      "item_unit_price": 2000000,
      "item_tax_rate": 10,
      "item_price": 2000000
    }
  ],
  "sub_total": 25685678,
  "tax_total": 2301654,
  "tax_10per_item": 12340000,
  "tax_10per": 1234000,
  "tax_8per_item": 13345678,
  "tax_8per": 1069654
}

いかがでしょうか。単純なテキストデータを、しっかりと構造化してくれています。
今回は、「OCRで精度が悪い部分があるかもしれないから、補正して」とお願いしているので、「12:340,000」とか「1.234,000」といったOCRで間違った部分も補正してくれています。
「ようけんていぎ」を「要件定義」に変換しているのはすこしやりすぎな気もしますが。

まとめ

このように、FunctionCalling機能を活用すると、ChatGPTがプロンプトの情報を解析し、構造化、引数の作成という「判断」が必要な作業を自動でこなしてくれるようになります。
正直、AIに頼らずに請求書のOCR結果の単純なテキストを構造化しろと言われてもどんなプログラムを書けばよいかわからないです。しかもどんなフォーマットの請求書にも対応できるわけですから。
少し前までは実現不可能だったこと、高コストだったことが、非常に簡単に実現できるようになっています。
是非とも貴社でもご活用いただき、新たな価値の創出に役立てていただければ幸いです。

お問合せ

ChatGPTによる業務改善をご検討されているようでしたら、是非ともご相談ください。
貴社専用のChatGPT環境構築から、プロンプト管理の為のシステムご提供、ChatGPTと連携したシステム構築まで幅広く対応させて頂きます。

株式会社システムコンサルタント 第一営業部