AppSheetのAI Taskで請求書からデータ抽出

2025年4月9日より、AppSheet Enterprise Plusの機能として「AI Task」と呼ばれるオートメーションの新機能が公開されました。これまで、Google Apps Script + Gemini APIで実現していたような機能をAppSheetのみで実現可能になったもので、4月25日にも正式にブログでリリース情報が出ています。

今回はこの新機能であるAI Taskで一体何ができるのか?を解析してみたいと思います。

今回利用するツール等

以前、簡単なPDFをGemini APIを使った手法でOCR読み取りをして、スプレッドシートに反映する手法を作成したことがあります。Google Apps Scriptで構築する必要がある点と、プロンプトでかなり変わるのでそこそこプログラミング経験が必要になります。

今回はこの部分がAI Taskで担当して簡単に実現しようというのが今回の取組です。現在のAIタスクはファイルから情報分解とカテゴライズの2種類をGeminiを使って処理をやらせることが可能です。

AppSheetでアップしたPDFをGeminiでOCR

事前準備

AppSheet Enterprise Plusについて

今回のAI Task機能はAppSheet Enterprise Plusのライセンスがなければ利用できない上位プランの特典です。しかし、AppSheetライセンスはGoogle Workspaceとは異なり、1本単位で購入し割り当てることが可能です。CoreライセンスもついていないEducationであっても別途追加することが可能です。

また、利用者全員に割り当てる必要は無く、開発者且つプロジェクトのオーナーにだけ割り当てれば、他のユーザや開発者はその結果作られた機能を利用できますので、1本月額$20ですが導入のハードルは低いのでまずは1本から導入してみると良いのではないかと思います。

AppSheet Enterprise Plusについての詳細な情報は以下の2つのエントリーを参照してください。

Google WorkspaceでAppSheetを使いDXを加速化させる

AppSheetを社内運用する場合のイロハ

プレビュー機能をオンにする

本機能は現時点ではプレビュー版の扱いであるため、事前にプロジェクトに於いてプレビュー機能のオンを行う必要があります。以下の手順で対象プロジェクトにて行いましょう。

  1. 対象プロジェクトを開く
  2. 左サイドバーより、Settings→Generalを開く
  3. Preview new featuresのスイッチをオンにする
  4. 右上のSAVEボタンをクリックして保存する

図:プレビュー機能をオンにする

制限事項

AppSheet Enterprise Plusの機能になりますが、生成AIの機能でもあるので無制限に読み取りをして作業ができるわけではありません。クレジットと呼ばれるものが1ライセンス1000クレジット/月付与され、この枠内で利用する必要があります。但しこのクレジットは余っても次月繰越は出来ません

クレジット枠を増やすにはAppSheet Enterprise Plusのライセンスを追加するしか無いので、上手く利用する必要があります。

クレジットの利用はAI Taskの実行数に応じて消費されることとなり、消費されている状況についてはAudit History自動化モニターを使って確認することが可能です。AppSheet管理コンソールからも確認可能で、以下の手順で監視可能です(管理者権限が必要です)。

  1. AppSheetのメイン画面を開く
  2. 右上のアカウントアイコンをクリック→Admin Consoleをクリック
  3. 左サイドバーのReports→Gemini Usageをクリックする

公式ドキュメントはこちら。Google Workspaceの管理コンソール上から対象者に対してAppSheet管理者のロールの割当が必要になるので、AppSheet Enterprise Plusのライセンス割当だけだと確認は出来ません。

※この情報は2時間ごとに更新されるので、リアルタイム情報ではありません。

図:AI Taskの使用状況レポート

設定方法

テーブル設計

今回のアプリは非常にシンプルな設計で、ファイルのアップロード画面を用意し読み取った情報をレコードに追記する形にしています。故にフォーム画面はファイルアップのフィールドのみを表示している状況にしてあります。今回はPDFからの情報抽出を目的としているので、ファイルアップのFile型列を事前に用意し、請求書の外側の部分を請求書テーブルとして用意します(中にある明細部分はとりあえずここでは除外しておく)。

図:File型の列が必要になります

オートメーションの作成

次にこの請求書テーブルに対してファイルがアップされたら作動するオートメーションを作成します。

  1. イベントは請求書テーブルに対するAddのみで応答するようにします。
  2. Add Stepをクリックしてステップを追加する
  3. 右パネルでステップはAI Taskをクリックして変更する
  4. AI TaskはExtractを選択する
  5. Input ColumnはFile型フィールドのものが自動で選択されているハズです。
  6. Outputは読み取った情報をそのままテーブルに追加するので、Save to Tableにします。
  7. AI Taskが自動的に列名に応じて取ってきてくれるので、取ってきた情報をどの列に入れるのか?をAddボタンで追加していく。

とりあえずこれで、ファイルをアップしてテストしてみると結果がわかります。

1フィールド文字数は最大1000文字までなので、備考欄にたくさん文字がある場合は工夫が必要。読み取った値の列にInitial Valueが設定されていても、Addで追加してる列の場合には読み取り値が自動で上書きされるので要注意。

図:AI Taskのタスク設定

図:読み取り列の指定

実行結果

上記の設定のまま、ファイルアップロードをして動かしてみました。たったこれだけで果たして請求書サンプルから読み取って、データ抽出できるのだろうか?とやってみました。

ファイルにPDFを入れて、Saveボタンを押すだけ。あとは自動的にオートメーションのAI Taskが読み取ってフィールドに適した値を抽出して入れてくれます。非常に精度が良いと思います。但し、インボイス番号の部分が別の書類IDが取れてしまったりしたので、

請求書といったものだけでなく、様々な書類や画像などでも行けるので、レシートといったものであったり専用の申込書の類などのデータもいけるので手動でスプレッドシートに転記といったミスもあり得る作業を自動化した上で精度を上げることが可能です。

図:読み取り結果

Additional Instraction

前述の仕組みでほとんどの値はバッチリ取れていますが、インボイス番号列だけがオカシナ値を拾ってきてしまっていました。これをどうにか制御したい。ということで利用するのがAI Taskの項目の一番下にある「Additional Instraction」。要するに追加プロンプトです。

色々と実験してみましたが、以下の処置をしてみた所バッチリ値を取ってきてくれるようになりました。

  • インボイス番号という列名をinvoicenumという名称に変更しました。
  • Additional Instractionに日本語だと上手く通用しなかったので、「invoicenum列は、Tから始まる14文字の値を取得する必要があります。」を英語に翻訳したワードを入れました。
    The " invoicenum" field must begin with the letter T and contain 14 characters.
  • この状態でアップロードをしてみる

すると、きちんとインボイス番号についてはinvoicenumという列名にしたことで、しっかりとTから始まる14文字のワードを見つけ出してピックアップできるようになりました

※invoicenum列はDisplay Nameで「インボイス番号」とでも変更しておけばUI上は問題ない。

図:細かい制御を指示することも可能

図:無事にインボイス番号が取れた

テスト実行

作成したフローを一時的にテストをして、どんな値が取れているのか?デバッグすることが可能です。一回アップロードをしておいてから実行すると良いでしょう。

  1. AI Taskのイベントをクリックする
  2. 右上の歯車アイコンの隣にある「Testing」というボタンをクリックする
  3. Select rowをクリックしてどの行のデータを使うかを選択する。
  4. Resultの下のRun test againをクリックする
  5. するとResultにどの列にどんな値が入ってくるのか?を検証することが可能です。

図:AI Taskの実行テスト

明細の取得は可能か?

概要

さて前述の段階で、請求書の外側の部分のデータについては見事にデータを取得して取り込むことができるようになりました。しかし、日本の請求書というのはその中に「明細」という名のサブフォームが存在するのが常識。このデータを取得できなければ、次の作業である会計ソフトへの入力については手作業という、中途半端な状況です。

前述のオートメーションだと請求書の外側は取れても、問題は明細テーブルは別に存在する上に複数行あるので、これを何とかする必要があります。

図:この明細部分の情報が必要

挑戦してみたけれど・・・

結論から言うと、AI Taskで明細部分の取得そのものは可能です。もっと素直で手軽な方法が無いか?とも思ってチャレンジしてみましたが、最後の一手で上手くいかず。故に自分の場合は、GASでデータ抽出関係は装備するのが素直かなぁと感じています(AppSheetはループ処理や複数行一括挿入といった基礎的な部分で機能が実装されておらず非力なので苦しい)。

とりあえず今回取り組んだ一歩手前までの内容をメモがてら残しておこうと思います。

作業列を用意

請求書テーブル(スプシ)に対して、明細というLongText型のフィールドを用意。ここにAI Taskで取得した明細欄の生データをそのまま格納します。

このフィールドの値をさらにList型にする為に明細分解という仮想列を追加。数式的には用意した明細列に対して、改行コードでSPLIT関数で分割します(カンマ区切りだと色々厄介なので値自体は「|」記号で区切っています。

SPLIT([明細], "\n")

明細取得のAI Task

請求書のヘッダ部分は前述の段階で完璧に取得が出来ています。そのAutomationの次のイベントを追加し、ここでもAI Taskで同じファイルに対してリクエストを投げます。

Additional Instractionでは以下のようなリクエストを投げています。数値からカンマは除外し、各項目の区切り文字は「|」で区切る。そしてList型では行末が改行コードで返ってくるので、その前にも必ず「|」を入れるようにしています。

The details field consists of four columns: "品名, 数量, 単価, 金額", and consists of multiple lines.
This data should not include commas in the 数量, 単価, 金額, and each column should be separated by "|" instead of a comma.
Please also add "|" at the end of the line as a line break code.

すると、以下のような値が改行された状態で、明細列に格納されます。

瑠璃子さん開発費用|1|50000|50000|
アプリ導入支援|2|5000|10000|
プラグイン費用|1|3500|3500|

図:データ取るところまでは出来てる

図:スプシにはこうやって入ってくる

List型のデータをどうにかする

さて、問題なのはこの明細列の値からList型にした明細分解列。この値からどうやって、明細テーブルに各値を追加するようにしたら良いのか?ここが今回ボトルネックで挫折してるポイント。1行目だけならば実は出来てるので、なんとかループ処理的なものを実装できたら行けそうな気がしないでもない。

アクションから「明細追加」という単一レコードとして構築して、行を追加するものを用意しました。設定としては

  • For a record of this table:請求書テーブル
  • Do this : 「Data : add a new row to another table using values from this row」
  • Table to add to : 明細テーブル

そして、Set these columnsでは以下のように明細分解列の値から取り出してます。行末に「|」を入れていないと4つ目が取れないので前述ではそのようにデータ構成しています。

//請求書ID
[_THISROW].[ID]

//品目
INDEX(SPLIT([明細分解], "|"), 1)

//数量
NUMBER(INDEX(SPLIT([明細分解], "|"), 2))

//単価
NUMBER(INDEX(SPLIT([明細分解], "|"), 3))

//金額
NUMBER(INDEX(SPLIT([明細分解], "|"), 4))

親の請求書テーブルのIDも取れているので、ここまではオッケー。問題は2行目以降も続けるには・・・ここが思いつかない。Geminiに聞いてみたら、「Data : execute an action on a set of rows」でこの作成したアクションを呼び出すアクションを作ればいい的な解答がきましたが、動きませんでした。

図:最初の1行だけは実は追加出来てる

図:execute an action on a set of rowsは不適合

GASを使った事例

やはり、何時間掛けてもAppSheetで簡単に構築というのは難しく、明細データを簡単に引き抜けても書き込みが難しい。ということで、Google Apps Scriptで構築してみたら1時間で構築出来ました。

AI Taskは確かに素晴らしいのですが、明細データ引き抜きだけでなく複数行データの一括書き込み、ループ処理の未実装など機能面でかなり劣っているのがこういう点で露呈してる気がする。派手な機能よりまずは基本的な機能を徹底的に実装していただきたい所存。

Google Apps ScriptとGeminiで請求書データを全部抽出する【GAS】

AppSheet APIを使った事例

今回取り組んでいませんが、AppSheetのAI Taskを利用しつつ、明細表をちょっと入り組んだやり方で挑戦してる方がいます(AppSheet APIを利用)。自分の場合複雑になるならばGoogle Apps Script使ったほうが断然楽に作れるので、その方法をオススメしますが、チャレンジしてみたい方は以下の動画からどうぞ。

善積情報さんでも、AI Taskではないですがアクションをループさせてのレコード生成などのサンプルがあります。

【Gemini in AppSheet】請求書明細を自動読み取り【AI Task】

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)