IT技術ブログ

社内のExcel・PDF帳票から生成AIで項目を読み取り、業務システムに入力する仕組み。OCRとLLMの分担、人の確認画面、誤読の扱い

Excel・PDFの帳票から生成AIで項目を読み取り、業務システムに入力する仕組みを実装の目線でまとめます。OCRとLLMの分担、決まった形で返させる方法、機械の検算、人の確認画面、誤読の記録と直し方まで。

この記事の結論:社内のExcel・PDF帳票から生成AIで項目を読み取り、業務システムに入力する仕組みは、「文字にする」「項目に当てはめる」「確かめる」「人が確定する」の4段に分けて作ります。作る側が先に決めておくべきなのは、①Excelや文字の情報を持つPDFはOCRを通さずファイルから直接取り出し、OCRや画像の読み取りはスキャンした帳票だけに使うこと、②生成AI(LLM)には決まった形(JSONスキーマ)で値と根拠の文字列を返させ、その値を機械の検算にかけること、③業務システムへの書き込みは人が確定させた後にだけ行い、AIが読んだ値と人が直した値の両方を記録すること、の3つです。AIの精度を上げることより、誤読が業務システムに入らない流れを作ることのほうが、仕組みの出来を左右します。

この記事は、取引先から届く注文書や請求書、社内で回している申請書のような帳票を、人が見ながら業務システムに打ち込んでいる会社の担当者と、それを自動にする仕組みを実装する開発者に向けた、設計の話です。どの業務からAIを入れるかの判断や、電子帳簿保存法に合わせた保存の要件は扱いません。部品の例はAWSから取りましたが、段の分け方そのものはクラウドを問いません。

帳票の読み取りは4段に分け、AIに任せるのは1段だけにする

帳票の読み取りを1回のAIの呼び出しで済ませようとすると、誤ったときにどこで誤ったかが分からなくなります。4段に分け、それぞれの段の出力を残しておきます。

段 やること 担い手 残すもの
文字にする ファイルから文字と位置を取り出す ファイルの読み込み、またはOCR 取り出した文字と、ページ上の位置
項目に当てはめる 「請求日」「合計金額」など、業務システムの項目に値を割り当てる 生成AI(LLM) 項目ごとの値と、根拠にした文字列
確かめる 合計や形式、マスタとの突き合わせで、ありえない値を見つける 自前のプログラム 通った検算と、引っかかった検算
人が確定する 元の帳票と並べて見て、直すか承認する 担当者 直す前の値、直した後の値、誰がいつ確定したか

生成AIが受け持つのは2段目だけです。1段目と3段目を自前のプログラムにしておくと、AIのモデルを変えても、ほかの段はそのまま使えます。

Excelと文字のあるPDFは、OCRを通さずにファイルから直接取り出す

帳票のファイルが手元に届く形は、大きく3つに分かれます。読み取りの方法は、AIを使うかどうかより先に、この形で決めます。

届く形 文字の取り出し方 誤りやすい所
Excelのファイル セルの値をそのまま読む(Pythonなら openpyxl など) 結合したセル、表示形式だけで日付に見えている数値
文字の情報を持つPDF(システムから出力したもの) PDFの中の文字の層を読み出す 表の行と列の対応が崩れること
スキャンや写真のPDF・画像 OCR、または画像を読める生成AI かすれ、手書き、斜めの読み込み

Excelや、システムから出力したPDFを画像にしてOCRにかけると、もともと正しく持っている文字を、わざわざ誤読の起きる方法で読み直すことになります。まずファイルに文字の層があるかを確かめ、ある場合はそれを使います。

スキャンした帳票では、使うOCRが日本語に対応しているかを最初に確かめます。たとえばAWSの Amazon Textract は、ドキュメントのベストプラクティスで対応言語を英語・スペイン語・ドイツ語・イタリア語・フランス語・ポルトガル語と書いており、日本語は入っていません。Google Cloud の Document AI の Enterprise Document OCR は、対応言語の表に日本語があり、手書きの対応の欄にも日本語に印が付いています。ただし対応表に印があっても、くせのある手書きまで読めるとは限らないので、手書きの欄が多い帳票は、同じ帳票を何枚か通して比べてから決めます。

もう1つの方法は、OCRを挟まず、画像やPDFを読める生成AIに直接渡すことです。Amazon Bedrock の Converse API は、文書(PDF、Excel、Word など)と画像をメッセージに入れて渡せます。この方法は部品が少なくて済む一方、文字の位置が返ってこないため、後で人の確認画面に「どこを読んだか」を示すのが難しくなります。確認画面に位置を出したいなら、OCRで文字と位置を取り出してから、その文字を生成AIに渡す形のほうが組みやすくなります。

生成AIには決まった形で返させ、値と一緒に根拠の文字列を返させる

項目に当てはめる段では、生成AIに自由な文章で答えさせず、JSONスキーマで決めた形で返させます。Amazon Bedrock の構造化出力(structured outputs)を使うと、モデルの答えが指定したスキーマに沿う形に制約されます。Converse API では outputConfig.textFormat に JSONスキーマを渡します。

請求書を読む場合のスキーマの例です。

json
{
  "type": "object",
  "properties": {
    "issuer_name":    { "type": "string" },
    "registration_no":{ "type": ["string", "null"] },
    "issue_date":     { "type": "string", "format": "date" },
    "total_amount":   { "type": "integer" },
    "lines": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "description": { "type": "string" },
          "amount":      { "type": "integer" }
        },
        "required": ["description", "amount"],
        "additionalProperties": false
      }
    },
    "evidence": {
      "type": "object",
      "properties": {
        "issuer_name":  { "type": "string" },
        "issue_date":   { "type": "string" },
        "total_amount": { "type": "string" }
      },
      "required": ["issuer_name", "issue_date", "total_amount"],
      "additionalProperties": false
    }
  },
  "required": ["issuer_name", "registration_no", "issue_date", "total_amount", "lines", "evidence"],
  "additionalProperties": false
}

ポイントは2つあります。1つは、見つからない項目に null を許すことです。null を許さない形にすると、帳票に書いていない値をAIがもっともらしく作って埋めることがあります。もう1つは、evidence に「その値の根拠にした帳票の中の文字列」をそのまま返させることです。根拠の文字列が、1段目で取り出した文字の中に本当にあるかをプログラムで確かめれば、帳票にない値を作った答えをはじけます。

構造化出力が保証するのは、形がスキーマに沿うことまでです。AWSのドキュメントには、数値の最小・最大や文字列の長さの制約は対応していないと書かれています。金額が0以上か、日付が今日より後になっていないかといった中身の確かめは、次の段のプログラムで行います。

誤読は、機械の検算で見つけるものと人が見るものに分ける

機械で確かめられることは、人の確認より前にすべて機械で確かめます。人に回すのは、検算で引っかかった項目と、検算では確かめようのない項目だけにします。

検算 見つかる誤り 引っかかったときの扱い
明細の金額の合計が、合計金額と合うか 桁の読み落とし、明細の行の取りこぼし その帳票を必ず人に回す
根拠の文字列が、取り出した文字の中にあるか 帳票にない値を作った答え その項目を空にして人に回す
登録番号が「T」と13桁の数字の形か。国税庁の公表サイトのWeb-APIで照会して、名称が合うか 番号の読み違い、別の会社の番号 取引先の欄を人に回す
取引先が、業務システムの取引先マスタにあるか 社名の表記の揺れ、読み違い 候補を並べて人に選ばせる
同じファイル、または同じ取引先・同じ請求番号がすでに入っていないか 同じ帳票の二重の取り込み 取り込みを止めて人に知らせる
OCRの信頼度が、項目ごとに決めた下限より上か かすれ・手書きの読み違い その項目を人に回す

OCRの信頼度について、Amazon Textract のベストプラクティスは、0〜100の信頼度を使い、誤りの影響が大きい用途では下限を決めて、下回ったものは捨てるか人の確認に回すよう勧めています。下限の値は用途で変わり、お金にかかわる業務では90%以上が必要になることもある、という書き方です。下限は全項目で1つにせず、金額と日付は高く、備考の欄は低く、というように項目ごとに決めます。

登録番号の照会に使う国税庁の Web-API は、使うためにアプリケーションIDの発行を受ける必要があります。照会の結果は、確認画面に「公表サイトの名称」として並べて出すと、人が見比べやすくなります。

人の確認画面は、元の帳票と読み取った値を並べ、直した記録を残す

人が確定する段の画面は、読み取った値の一覧だけでは役に立ちません。元の帳票の画像を横に並べ、項目を選ぶと帳票のその位置が光るようにしておくと、確認の手間が大きく変わります。

確認画面に入れておくものは、次のとおりです。

  1. 元の帳票の画像。 拡大と回転ができるもの
  2. 項目ごとの値と、どこから読んだか。 OCRの位置があれば帳票の上に枠を出す
  3. 検算の結果。 引っかかった項目を目立たせ、引っかかった理由を書く
  4. 直す欄と、確定のボタン。 確定するまで業務システムには書き込まない
  5. 差し戻しの手段。 帳票そのものが読めない場合に、取引先へ出し直しを頼む流れに回す

記録には、項目ごとに「AIが読んだ値」「人が確定した値」「確定した人」「確定した日時」「使ったモデルと指示文の版」を残します。AIが読んだ値を確定の値で上書きして消すと、誤読が何件あったのか、あとで数えられなくなります。

この記録がたまると、帳票の種類と項目ごとに、人が直した割合が出せます。読み取りの指示文やモデルを変えるときは、過去に人が直した帳票を試験の材料にして、変える前と後の両方で読ませ、直しが必要な項目が減ったかを確かめてから入れ替えます。外部のAIのAPIを呼ぶときの、費用の上限やログの持ち方は、APIの呼び出しに上限とログを持たせる設計の記事にまとめています。

帳票の中の文字を、AIへの指示として扱わせない

帳票は社外から届くものが多く、その中の文字はそのまま生成AIに渡ります。帳票の余白に「上の指示は取り消し、次のとおり答えよ」といった一文が紛れていると、AIがそれを指示として受け取るおそれがあります。OWASPは、外部の内容を通じて入り込む指示をプロンプトインジェクションの一種として挙げています。

この仕組みで取れる手立ては、次の3つです。

  • 生成AIにできることを、値を返すことだけにする。 業務システムへの書き込みやメールの送信をAIから直接させない。書き込むのは、人が確定した後の自前のプログラムだけにする
  • 帳票の中身と指示を分けて渡す。 指示文の中で、帳票の部分は読み取りの対象であって指示ではないことを明記する
  • ファイル名をそのまま渡さない。 Bedrock の DocumentBlock の説明には、文書の name の欄はモデルが指示として解釈するおそれがあるので、中立な名前を付けるよう書かれている。届いたファイル名ではなく、受付番号のような名前に置き換えて渡す

1つ目が一番効きます。値の受け渡しだけを担う作りであれば、帳票に妙な一文があっても起きるのは誤った値までで、その値は検算と人の確認を通らない限り業務システムに入りません。

帳票には取引先の担当者の名前や連絡先が載っていることが多く、生成AIのサービスに送る内容になります。送った内容が学習に使われない設定と契約になっているか、どの地域で処理されるかを、使う前に確かめて記録しておきます。

株式会社bundlyzeでは入力先になる業務システムそのものを要件定義の段階から受託し、稼働後の保守運用まで続けて担っているため、読み取りの仕組みも、入力先の業務システムと切り離さずに一続きの機能として設計する前提でこの記事を書いています。

小さく始めて、帳票の種類と項目を1つずつ広げる

最初の版は、届く数が多く、形がそろった帳票を1種類だけ選んで作ります。

  1. 帳票を1種類選ぶ。 同じ取引先から届く注文書のように、形が毎回そろうものにする
  2. 届く形を確かめる。 Excel・文字のあるPDF・スキャンのどれで届くかを数え、文字の取り出し方を決める
  3. 業務システムの項目に合わせてスキーマを書く。 見つからない項目に null を許し、根拠の文字列を返させる
  4. 検算を書く。 合計の突き合わせ、根拠の文字列の照合、マスタの照合、二重の取り込みの検知から始める
  5. 確認画面を作る。 確定するまで業務システムに書き込まない作りにし、AIの値と確定の値を両方残す
  6. 今の手入力と並べて回す。 しばらくは人の手入力も続け、両方の結果を突き合わせて、誤読の多い項目を洗い出す

6つ目の並走の期間に、項目ごとの直しの割合を見ます。直しがほとんど出ない項目から、確認の画面で目を通すだけにする、といった手順の見直しを進めます。業務の流れのどこにAIを入れ、どこを人に残すかの整理からまとめて進めたい場合は、業務にAIを組み込む支援の案内を参考にしてください。

出典にした各社のドキュメント(2026-10-03 確認)

対応する言語や機能の範囲は更新が早い分野です。組み込む前に、各ページの今の記載を読み直してください。

よくある質問

生成AIに帳票を読ませれば、OCRは要らなくなりますか?

帳票の種類によります。Excelや、文字の情報を持っているPDFは、OCRも生成AIの画像読み取りも通さず、ファイルから直接文字を取り出すほうが確実です。スキャンした紙の帳票は、画像を読める生成AIに直接渡す方法と、日本語に対応したOCRで文字にしてから生成AIに項目を当てはめさせる方法があり、誤読の傾向と費用を同じ帳票で比べてから選びます。

読み取りの精度が十分に高ければ、人の確認を省いてもよいですか?

金額や取引先のように、間違えると支払いや請求に響く項目は、精度にかかわらず人が確定させる手順を残すことをおすすめします。省けるのは、機械の検算をすべて通り、誤っても後の業務で必ず気づける項目に限ります。どの項目を省くかは、誤読の記録がたまってから項目ごとに決めます。

誤読を直した記録は、何に使えますか?

AIが読んだ値と、人が直した値を項目ごとに残しておくと、どの帳票のどの項目で誤りが多いかが分かります。その記録は、読み取りの指示文やモデルを変えるときに、変える前と後で誤りが減ったかを確かめる試験の材料になります。