食材の納品書を読み取って、店舗別の仕入原価の台帳と、単価が動いた品目の記録にする
店舗に届いた食材の納品書を写真で送るだけで、明細の表を読み取り、品名・数量・単価を店舗別の仕入原価の台帳に書き込みます。あわせて、前回の納品から単価が動いた品目を記録します。
- 生成AI
- ChatGPT/Claude/Gemini
- AIサービス
- AWS Textract/Azure AI/Google Document AI
- 連携・自動化
- Google Apps Script/Make/Power Automate
- 対象業界
- 介護/宿泊/小売/飲食
- 対象部門
- 経理/購買
- 対象業務
- データ入力・転記/台帳・マスタ管理
- 主な課題
- データ分析に時間がかかる/入力作業が多い/確認ミスが多い
- AIで行う処理
- 読み取り(OCR)
- 主な効果
- 入力漏れ削減/判断支援/工数削減
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 本格構成
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 店長が納品書を受け取り、数量を確かめて印を押す。欠品や返品があれば手書きで訂正する
- 週に2回、店舗が納品書の写しを本部へ送る(紙の束、またはスキャンしたPDF)
- 本部の担当者が1枚ずつ見て、日付・店舗・仕入先・品名・数量・単位・単価・金額を表計算に入力する
- 品名を食材の一覧と見比べ、どの食材に当たるかを選ぶ
- 気になった品目は、前回の単価を台帳でさかのぼって見比べる
- 月末に請求書が届いたら、台帳の合計と突き合わせる
- 店舗ごとの仕入の合計を売上で割り、原価率を出す
- 人店長が納品書を受け取り、数量を確かめて印を押す。訂正があれば手書きで書き込む
- 人店長がスマートフォンで納品書を撮り、店舗ごとの受付フォルダに保存する
- 自動15分ごとに Apps Script が受付フォルダを見て、新しいファイルを Azure AI Document Intelligence のレイアウトモデルに送る
- 自動レイアウトモデルが明細の表、日付・仕入先などの項目、手書きの行の印を、読み取りの信頼度とともに返す
- 自動Gemini API が表の列を見分け、品名を食材の一覧に当てはめ、訂正の書き込みがある行に印を付ける
- 自動Apps Script が数量×単価と金額を検算し、単位を食材の一覧の入数で読み替える
- 自動前回の納品の単価と比べ、区分ごとの幅を超えた品目を単価の変動の記録に書く
- 自動台帳に書き込み、確認が要る行に印を付ける
- 人本部の担当者が、確認が要る行だけを納品書の画像と見比べて直す
- 人単価の変動の記録を週に1回見て、仕入先に確かめるものを決める
各工程の詳しい説明を読む
- 店長が納品書を受け取り、数量を確かめて印を押す。欠品や返品があれば手書きで訂正する
- 週に2回、店舗が納品書の写しを本部へ送る(紙の束、またはスキャンしたPDF)
- 本部の担当者が1枚ずつ見て、日付・店舗・仕入先・品名・数量・単位・単価・金額を表計算に入力する
- 品名を食材の一覧と見比べ、どの食材に当たるかを選ぶ
- 気になった品目は、前回の単価を台帳でさかのぼって見比べる
- 月末に請求書が届いたら、台帳の合計と突き合わせる
- 店舗ごとの仕入の合計を売上で割り、原価率を出す
(a)入力が終わらない。 1,200枚を3名で入力すると、それだけで月100時間になります。納品書が本部に届くのが週2回なので、入力はいつも数日遅れです。 原価率が出るのは月末の締めの後です。
(b)品名の当てはめが人によって違う。 「新玉ねぎ」を「玉ねぎ」に入れる人と、別の食材として登録する人がいます。当てはめがぶれると、店舗をまたいで玉ねぎの仕入量を比べられません。
(c)値上がりに気づくのが遅れる。 前回の単価を見比べるのは「気になった品目」だけです。乾物や調味料のように普段動かない品目ほど、少しの値上げが見過ごされます。 気づくのは、月末の原価率が上がった後です。
(d)手書きの訂正を読み落とす。 数量を書き直した行を、印刷された元の数量で入力してしまい、請求書と合わずに納品書の束を見直すことになります。
- 【人】 店長が納品書を受け取り、数量を確かめて印を押す。訂正があれば手書きで書き込む
- 【人】 店長がスマートフォンで納品書を撮り、店舗ごとの受付フォルダに保存する
- 【自動】 15分ごとに Apps Script が受付フォルダを見て、新しいファイルを Azure AI Document Intelligence のレイアウトモデルに送る
- 【自動】 レイアウトモデルが明細の表、日付・仕入先などの項目、手書きの行の印を、読み取りの信頼度とともに返す
- 【自動】 Gemini API が表の列を見分け、品名を食材の一覧に当てはめ、訂正の書き込みがある行に印を付ける
- 【自動】 Apps Script が数量×単価と金額を検算し、単位を食材の一覧の入数で読み替える
- 【自動】 前回の納品の単価と比べ、区分ごとの幅を超えた品目を単価の変動の記録に書く
- 【自動】 台帳に書き込み、確認が要る行に印を付ける
- 【人】 本部の担当者が、確認が要る行だけを納品書の画像と見比べて直す
- 【人】 単価の変動の記録を週に1回見て、仕入先に確かめるものを決める
9番目が、この設計の分かれ目です。 人が見るのは全行ではありません。信頼度が低い行、検算が合わない行、訂正の印がある行、食材に当てはまらなかった行だけです。 全行を見直す設計にすると、入力が確認に置き換わるだけで時間は減りません。
6番目の計算を、AIではなく Apps Script に置いているのも意図してのことです。 AIに「ケースをkgに直して」と頼むと、入数を推測して計算します。計算は、食材の一覧に書かれた入数だけを使う規則で行います。
02今回想定するシステム構成
納品書(紙)── 店長がスマートフォンで撮影 ▼【トリガー】15分ごとの時間主導型トリガー Google ドライブ(店舗ごとの受付フォルダ) │ Apps Script が新しいファイルを取り出す ▼ Azure AI Document Intelligence(レイアウトモデル prebuilt-layout) │ 明細の表(行・列の番号と見出しの印が付いたセル) │ 日付・仕入先などのキーと値、手書きの行の印、読み取りの信頼度 ▼ Gemini API ── 列の見分けと、品名の食材の一覧への当てはめ │ ① 列の役割(品名・規格・数量・単位・単価・金額) │ ② 食材コードの候補 ③ 訂正の書き込みがある行 ▼ Apps Script ── 検算、単位の読み替え、前回の単価との比較 ▼ Google スプレッドシート(仕入原価の台帳/単価の変動の記録) ▼ 【人が確認の要る行だけ見る】──▶ 会計システムへの計上/仕入先への確認
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| OCR | Azure AI Document Intelligence(レイアウトモデル) | Google Document AI、AWS Textract(英文の書類に限る) |
| 生成AI | Gemini API(列の見分けと、品名の食材の一覧への当てはめ) | Claude API、OpenAI API |
| 連携 | Google Apps Script(受付フォルダの見張り、検算、単価の比較、台帳への書き込み) | Power Automate、Make |
| 保管 | Google ドライブ(店舗ごとの受付フォルダと処理済みフォルダ) | Microsoft OneDrive、SharePoint |
| 台帳 | Google スプレッドシート(仕入原価の台帳、単価の変動の記録、食材の一覧) | Microsoft Excel(オンライン) |
会計システムは、この構成からは書き換えません。 計上は今までどおり担当者が行います。
AWS Textract は、この構成では使いません。 AWS のドキュメントでは、対応する言語が英語、フランス語、ドイツ語、イタリア語、ポルトガル語、スペイン語とされ、手書きの認識は英語のみ、縦書きにも対応していません。日本語の納品書は対象に入りません。
読み取りは Azure AI Document Intelligence のレイアウトモデル(prebuilt-layout)で行います。 テキスト、表、選択マーク、文書の構造を取り出すモデルで、日本語は印刷の文字にも手書きの文字にも対応しています。 v4.0 では、クエリに features=keyValuePairs を付けると、キーと値の組も一緒に取れます。
レイアウトモデルが返す表は、行数・列数と、セルの一覧です。 各セルには行と列の番号、中身の文字列が入り、見出しと認識されたセルには columnHeader の印が付きます。 行や列をまたぐセルの数も返ります。
手書きの行にも印が付きます。 応答の styles に、その行が手書きのスタイルかどうかが信頼度とともに入ります。納品書の手書きの訂正を見つけるのに、この印を使います。
入力は PDF と画像(JPEG/JPG、PNG、BMP、TIFF、HEIF)で、文字の高さは1024×768の画像で12ピクセル以上が必要です。
03どうやって実装するのか
処理の起点を決める
店長が納品書を撮って店舗ごとの受付フォルダに保存したことを、15分ごとに見に行きます。 Apps Script の時間主導型トリガーは、毎分から月1回までの間隔で動かせます。15分ごとにしているのは、昼の仕込みと夜の営業の前に、その日の分が台帳に入っていれば足りるからです。
フォルダは店舗ごとに分けます。 ファイル名に店舗名を入れさせる運用は崩れます。どのフォルダに入ったかで店舗を決めれば、店長が決めることは「撮って保存する」だけです。
処理したファイルは、店舗ごとの処理済みフォルダへ移します。移すのは、台帳への書き込みまで成功したときだけです。 受付フォルダに残っている数が、そのまま未処理の数になります。
時間主導型トリガーは、作成した人のアカウントで動きます。作成は、購買の業務用のアカウントで行います。 担当者の個人のアカウントで作ると、その人が異動したときに止まります。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 納品書の画像 | スマートフォンの写真(JPEG)またはスキャンしたPDF | 店舗ごとの受付フォルダ |
| 読み取り結果 | 明細の表、日付・仕入先などのキーと値、手書きの行の印、読み取りの信頼度 | Azure AI Document Intelligence のレイアウトモデル |
| 食材の一覧 | 食材コード、正式な品名、言い換え、規格、基準の単位、入数、時価の品目か | Google スプレッドシート |
| 仕入先の一覧 | 仕入先コード、名称、系統(青果・鮮魚など)、納品書の列の並びの癖 | Google スプレッドシート |
| 前回の単価 | 同じ店舗・同じ仕入先・同じ食材の、直近の納品の単価 | 仕入原価の台帳 |
質を決めるのは、食材の一覧の「言い換え」と「入数」の列です。 「新玉ねぎ」「玉葱」「オニオン」を同じ食材に当てはめられるのは、言い換えが書かれているからです。「1箱」を何kgと読むかも、入数が書かれていなければ決められません。
仕入先の一覧に「列の並びの癖」を持たせるのも効きます。 精肉店は「数量」の列に重さを、酒販店は「入数×ケース数」を書く、といった癖です。この一言を Gemini API への指示に添えるだけで、列の見分けの誤りが減ります。
データの取得方法を決める
Apps Script から Document Intelligence の REST API を呼びます。 受付フォルダのファイルを取り出し、prebuilt-layout に features=keyValuePairs を付けて分析を依頼し、結果のJSONを受け取ります。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 表の行数・列数とセル | tables[] の rowCount・columnCount・cells[] | 明細の行と列 |
| セルの位置と中身 | 各セルの rowIndex・columnIndex・content、見出しなら kind: columnHeader | 列の見出しと明細の値 |
| キーと値の組 | features=keyValuePairs を付けた結果 | 納品日、仕入先名、伝票番号 |
| 手書きの行 | styles の手書きの印と、その信頼度・範囲(spans) | 訂正の書き込みの候補 |
| 信頼度 | 単語ごとの confidence | 確認が要る行の判定 |
信頼度は、セルではなく単語に付いています。 セルの spans と単語の位置を突き合わせ、セルに含まれる単語の信頼度のうち、いちばん低いものをそのセルの信頼度とします。平均にすると、1文字だけ読み違えた単価が埋もれます。
手書きの印も、同じく位置で突き合わせます。 styles が指す範囲に明細のセルが含まれていれば、その行を「手書きの書き込みあり」とします。Gemini API に渡す前に、この印を行に付けておきます。
食材の一覧と前回の単価は、スプレッドシートから読むだけです。 前回の単価は、店舗・仕入先・食材コードの3つで引きます。店舗を条件から外すと、別の店舗の単価と比べてしまいます。 同じ食材でも、店舗の規模で仕入の単価が違うことがあるからです。
AIへ渡す前に整形する
- 形式と寸法の確認 … PDFまたは画像で、50×50から10,000×10,000ピクセルの間であることを確かめます
- 向きの補正 … 横向きに撮った写真は回転させます。表の文字が傾いていると、表として認識されにくくなります
- 1枚に複数の納品書が写っていないかの確認 … 並べて撮ったものは撮り直してもらいます
- 重複の検知 … 同じ店舗・同じ仕入先・同じ伝票番号のものがあれば、2回目を処理しません
- 写りの確認 … 影やピンぼけで文字が読めない写真は、読み取りの信頼度が全体に低く出ます。平均が基準を下回ったら、店長へ撮り直しを求めます
- 仕入先の特定 … 仕入先名の項目を仕入先の一覧と照らし、列の並びの癖を取り出します
5番目を軽く見ないでください。 店舗のバックヤードは暗く、納品書は折れていることが多いです。写りが悪いまま読み取った台帳を人が直すより、その場で撮り直してもらうほうが早く終わります。 撮り直しの依頼は、処理の直後に店舗へ返すので、納品書がまだ手元にあるうちに届きます。
4番目の伝票番号は、写真を2回撮って保存したときの二重計上を止めます。
AIに処理させる
Gemini API にさせるのは3つです。表の列の役割を見分けること、品名を食材の一覧に当てはめること、訂正の書き込みがある行を見つけることです。
| 見るもの | させること | 判断できないときの扱い |
|---|---|---|
| 表の見出しと列 | 各列が品名・規格・数量・単位・単価・金額のどれかを決める | 見出しが無い列は unknown |
| 品名 | 食材の一覧から食材コードの候補を最大3つ、根拠とともに選ぶ | 当てはまらなければ no_match |
| 数量と単位 | 読み取った文字を、数量と単位に分ける(「2.35kg」→ 2.35 と kg) | 分けられなければ unparsed |
| 訂正の書き込み | 手書きの印がある行と、同じ行に数字が2つある行、「欠」「返」の文字がある行に印を付ける | 疑わしければ correction_suspected |
| 行の種類 | 明細の行か、小計・消費税・値引き・配送料の行かを分ける | 分からなければ unknown_row |
いちばん大事なのは、4行目の訂正の書き込みです。 印刷された数量と手書きの数量が同じ行にあるとき、どちらを採るかをAIに決めさせません。 印を付けて人に回し、担当者が画像を見て決めます。欠品や返品は、原価の数字にそのまま効くからです。
| させないこと | 理由 |
|---|---|
| 数量×単価の計算、合計の検算 | Apps Script の規則で行う。AIの計算は結果が安定しない |
| 単位の読み替え(ケース→kg) | 食材の一覧の入数だけを使う。入数を推測させない |
| 読み取った数字の書き換え | 桁を直す、それらしい単価に近づけることをさせない |
| 訂正のどちらを採るかの判断 | 画像を見て人が決める |
| 単価が高いか安いかの評価 | 比べるのは Apps Script。AIに相場を語らせない |
3行目がいちばん起きやすい失敗です。 単価が「1,28O」のように読み取られていると、AIは「1,280」に直して返そうとします。直した値が正しくても、読み取りの誤りがあったという事実が消え、同じ仕入先で次に起きたときに気づけません。 数字は読み取ったとおりに返させ、直すのは人です。
指示内容を固定する
あなたは飲食チェーンの本部で、仕入の台帳を作る担当です。
OCRが読み取った納品書の表を、台帳の形にそろえてください。
読み取り結果に書かれていることだけを使ってください。推測で埋めないでください。
【やること】
1. 表の各列の役割を決めてください:
item_name / spec / quantity / unit / unit_price / amount / unknown
2. 明細の各行について、品名を下の食材の一覧から当てはめてください。
候補を最大3つ、一致の根拠(正式名・言い換えのどれと一致したか)とともに返してください。
当てはまらなければ no_match にしてください。
3. 数量の文字を、数値と単位に分けてください。
4. 行の種類を、item / subtotal / tax / discount / delivery_fee / unknown_row から選んでください。
【厳守事項】
- 数字は読み取り結果のとおりに返してください。
桁を直す、「O」を「0」に直す、それらしい値に近づけることをしないでください。
読み取りが数字として解釈できなければ、raw にそのまま入れ、value は null にしてください。
- 計算をしないでください。数量×単価や合計を求めないでください。
- 単位を読み替えないでください。「1箱」は 1 と 箱 のまま返してください。
- 手書きの印(handwritten)が付いた行、同じ行に数字が2つある行、「欠」「返」の文字がある行は、
correction_suspected を true にし、見つかった文字をすべて correction_text に入れてください。
どちらの数字が正しいかを選ばないでください。
- 単価が高い・安いといった評価を書かないでください。
- 納品書でない書類と判断した場合は、document_type に種類を書き、処理をしないでください。
【仕入先】{supplier_name}(系統:{supplier_category})
【この仕入先の列の癖】{supplier_layout_note}
【食材の一覧(この系統のもの)】{item_master}
【読み取り結果の表】{table_cells}
【読み取りの信頼度と手書きの印(行ごと)】{row_flags}
「Oを0に直さない」まで具体的に書くのは、書かないと必ず直すからです。 AIは読み取りの誤りを親切に正そうとします。正しく直っても、誤りがあったことが台帳から消えるのが問題です。
食材の一覧を「この系統のもの」に絞って渡すのも意図してのことです。 全食材を渡すと、鮮魚の納品書の「かます」を乾物の「かますご」に当てはめる、といった取り違えが増えます。仕入先の系統で候補を先に絞ります。
出力形式を固定する
Gemini API の構造化出力で、スキーマを渡してJSONで受け取ります。 構文上正しいJSONが返り、スキーマでは enum で値の選択肢を縛れます。
{
"document_type": "delivery_note",
"columns": [ { "index": 0, "role": "item_name" } ],
"rows": [
{
"row_index": 0,
"row_type": "item | subtotal | tax | discount | delivery_fee | unknown_row",
"item_name_raw": "",
"item_candidates": [ { "item_code": "", "matched_by": "name | alias", "rank": 1 } ],
"quantity": { "raw": "", "value": null, "unit": "" },
"unit_price": { "raw": "", "value": null },
"amount": { "raw": "", "value": null },
"correction_suspected": false,
"correction_text": ""
}
]
}
1つ目の理由は、raw と value を分けて持てることです。 読み取った文字は raw に残り、数値として解釈できたときだけ value に入ります。value が null の行は、そのまま確認が要る行になります。 人が画像を見るときも、何と読み取られたかが分かります。
2つ目は、row_type で明細以外の行を外せることです。 小計・消費税・値引き・配送料の行を明細として台帳に入れると、原価が二重に数えられます。 値引きと配送料は、台帳の別の列に入れます。
受け取った後、Apps Script が次の規則で確認の要否を決めます。 Gemini API のドキュメントでも、構文が正しくても値はアプリケーションの側で確かめるよう書かれています。
| 規則 | 確認に回す条件 |
|---|---|
| 読み取りの信頼度 | 行のセルのどれかが基準を下回る |
| 検算 | 数量×単価と金額の差が1円を超える |
| 当てはめ | no_match、または1位と2位の候補の系統が違う |
| 訂正 | correction_suspected が true |
| 単位 | 食材の一覧の基準の単位と違い、入数が一覧に無い |
| 合計 | 明細の金額の合計と、納品書の合計が合わない |
2行目の検算を、AIではなくここで行うのが要です。 検算が合わない行は、読み取りの誤りか納品書の誤りのどちらかで、どちらも人が見るべき行です。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 店舗ごとの受付フォルダ | Apps Script の時間主導型トリガー | 新しいファイルを取り出す |
| Azure AI Document Intelligence | Apps Script から REST API を呼ぶ | 表、キーと値、手書きの印、信頼度を返す |
| Gemini API | Apps Script から API を呼ぶ | 列の見分けと当てはめ |
| 仕入原価の台帳 | Apps Script から書き込む | 明細の行、確認の要否、元の画像へのリンク |
| 単価の変動の記録 | Apps Script から書き込む | 前回との差が区分ごとの幅を超えた品目 |
| 店舗への連絡 | メールまたはチャット | 撮り直しの依頼 |
単価の比較の幅は、食材の一覧の区分で変えます。 時価の品目は前回との差が大きいのが普通なので、直近4週の平均との差で見ます。 定価の品目は前回と1円でも違えば記録します。乾物や調味料の少しの値上げは、この「1円でも」で拾えます。
会計システムへは書き込みません。 月末に請求書が届いたら、台帳の仕入先ごとの合計と突き合わせてから、担当者が計上します。納品書と請求書の差は、返品や値引きの処理漏れが見つかる場所です。
人が確認する
本部の担当者が見るのは、第7章「出力形式」の規則で確認に回った行だけです。 台帳の行は、確認の要らないものから順に「確定」になります。
- 訂正の印がある行を先に見る … 画像を開き、印刷された数字と手書きの数字のどちらを採るかを決めます。迷ったら店長に電話で確かめます
- 検算が合わない行を見る … 読み取りの誤りなら直し、納品書の誤りなら仕入先への確認の欄に印を付けます
- 当てはまらなかった品名を見る … 新しい食材なら食材の一覧に足し、言い換えなら言い換えの列に足します
- 単価の変動の記録を週に1回見る … 定価の品目の値上げは、仕入先に通知の有無を確かめます
3番目は、この構成が月を追って楽になる理由です。 言い換えを足すほど、次から同じ品名は当てはまるようになります。最初の1か月は no_match が多く出ますが、それは食材の一覧が育っていく途中です。
目標は、1,200枚をならして1枚1.5分です。 確認に回るのが全行の1〜2割という想定で、それを大きく超える月は、写りの悪い店舗があるか、食材の一覧の言い換えが足りていません。
例外に対処する
| 起きること | 対応 |
|---|---|
| 写りが悪く、信頼度が全体に低い | 店長へ撮り直しを求める。納品書が手元にあるうちに |
| 文字が小さすぎる | 1024×768の画像で12ピクセルが下限。近づいて撮り直してもらう |
| 表として認識されない | 手書きの納品書など。その仕入先だけ人が入力する扱いにする |
| 伝票番号が読めない | 日付・仕入先・合計金額の組で重複を見る |
| 仕入先が一覧に無い | 処理を止めて担当者へ。新しい仕入先の登録が先 |
| 納品書でない書類が入る | document_type を見て、処理せず店舗へ戻す |
| API が応答しない | 受付フォルダに残す。処理済みへ移すのは成功時だけ |
| 同じ納品書を2回撮った | 伝票番号で2回目を処理しない |
上の3行が、運用の最初の月に集中します。 どれもAIの問題ではなく、撮り方と納品書の書式の問題です。 手書きの納品書しか出さない仕入先は、無理に読ませずに人の入力に残すほうが早く終わります。
記録を残す
- 元の画像と、撮った店舗・保存した日時
- Document Intelligence が返したJSONの全文
- Gemini API が返したJSONと、そのとき渡した食材の一覧の版
- 確認に回った理由と、担当者が直した内容
- 訂正のどちらを採ったかと、その根拠(画像を見た/店長に確かめた)
- 単価の変動の記録と、仕入先に確かめた結果
3つ目の「食材の一覧の版」を残すのは、言い換えを足すと当てはめの結果が変わるためです。 過去の台帳の当てはめを見直すとき、当時の一覧で何が選べたかが分からないと、誤りなのか一覧の不足なのかを切り分けられません。
04実装レベルの3段階
最小構成では枚数がさばけません。 1,200枚を1枚ずつ貼るのは、今の入力と変わりません。確かめるための段階です。 半自動化で、1枚5分が3分程度になります。 入力は自動になりますが、検算と単位の読み替えと前回との比較が人に残ります。本格構成で1.5分になり、この段階が本記事の想定です。 差が大きいのは、全品目の前回との比較が、人の手ではそもそもできていなかった作業だからです。 段階を飛ばさないでください。 半自動化の台帳を1か月見ると、no_match の多い品名と、写りの悪い店舗が分かります。食材の一覧を育ててから単価の比較を足すほうが、変動の記録に誤りが混ざりません。
05工数削減シミュレーション
導入後 1,200件 × 1.5分 ÷ 60 = 30 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 10店舗前後の飲食チェーンで、仕入先が青果・鮮魚・精肉・酒類・乾物と分かれ、納品書が紙で店舗に届く場合。本部の購買担当が納品書の写しを見て表計算に入力しており、月末まで原価率が分からない場合。鮮魚や青果など日によって単価が変わる品目が多く、値上がりに気づくのが遅れている場合。
- 仕入先の大半が受発注のシステムでつながっており、納品データを電子で受け取れている場合。店舗が1〜2店で、納品書が月に数十枚の場合。なお、仕入先との単価の交渉や、メニューの価格をどうするかの判断は、この構成では代替できません。
07最小構成で試す方法
- 先月の納品書から30枚を選ぶ(仕入先の系統をまんべんなく、うち5枚は手書きの訂正が入ったものにする)
- その30枚について、台帳にどう入力したかを確かめる
- 手元のAIサービスの画面に1枚ずつ画像を貼り付ける
- 「この納品書の明細を、品名・数量・単位・単価・金額の表にしてください。数字は書かれたとおりにし、計算しないでください。手書きの訂正がある行には印を付けてください」と指示する
- 出てきた表を、当時の台帳と突き合わせる
30枚は必ずやってください。 API やスクリプトを組む前に、「この店舗の撮り方と仕入先の書式で、表として読めるのか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 当時の台帳とほぼ同じ表になった | Document Intelligence と Apps Script の連携に進む |
| 数字を直した、計算した | 指示の書き方で直る。構成は有効 |
| 表が崩れる、訂正を見落とす | 撮り方が先。 明るい場所で、真上から、1枚ずつ撮る |
3行目が出ることは珍しくありません。 失敗ではなく、入力に時間がかかっていた理由の一部が紙の写りだったと分かったということです。 撮り方を決めて撮り直してください。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 読み取りの誤りをAIが直して返す | 数字は読み取ったとおりに返す、を指示に書く。 raw と value を分ける |
| AIが数量×単価を計算する | 計算を禁じ、検算は Apps Script で行う |
| 手書きの訂正を読み落とす | 訂正の印を付けさせ、どちらを採るかは人が決める |
| 小計や消費税を明細として入れる | row_type で分け、明細以外の行を外す |
| 「1箱」を何kgと読むかが決まらない | 食材の一覧に入数を持たせる。 無ければ確認に回す |
| 品名の当てはめが系統をまたいで誤る | 食材の一覧を仕入先の系統で絞って渡す |
| 時価の品目で変動の記録があふれる | 時価の品目は直近4週の平均と比べる |
| 1文字の読み違いが平均の信頼度に埋もれる | セルの信頼度は、含まれる単語の最低値で見る |
| 手書きの訂正を位置で拾えない | styles の範囲とセルの spans を突き合わせる |
| 日本語の納品書が読めない OCR を選ぶ | 対応言語を先に確かめる。 AWS Textract は日本語に対応していない |
| 担当者の個人のアカウントでトリガーを作る | 業務用のアカウントで作る。異動で止まる |
上の2行が、この構成の失敗のほとんどです。 どちらも「AIに任せた数字が、読み取った事実と違う」という同じ問題です。読み取った値と計算した値を分けているかどうかで、台帳が信用できるかが決まります。
下から2行目は、選定の段階で起きます。 製品の名前だけで決めると、日本語の書類が読めないことに後から気づきます。製品の対応言語の一覧を最初に見てください。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 仕入先の名称、納品の品目と数量、仕入の単価、店舗ごとの仕入の合計です。個人情報はほとんど含みませんが、単価は仕入先との取り決めで、競合に知られたくない情報です。
- 外部へ渡す範囲を、読み取りと当てはめに必要なものに限る … Gemini API に渡すのは読み取った表と、系統で絞った食材の一覧です。画像や、店舗ごとの売上は渡しません
- 単価の変動の記録を、見る人を限る … 仕入先ごとの単価の推移がまとまった表です。購買と経理の担当だけが開けるようにします
- この構成は、単価の交渉やメニューの価格の判断を代替しません … 変動の記録は材料です。仕入先に何を言うか、価格をどうするかは、購買と経営が決めることです
- 訂正の判断を記録に残す … 手書きの訂正のどちらを採ったかは、請求書との差が出たときに根拠になります。人が決めた理由まで残します
- Document Intelligence と Gemini API の処理の場所を確かめる … Azure のリソースをどのリージョンに作るかで、データを処理する地域が決まります。 社内の規程と照らして選びます
誤りが起きた場合のリスクは、届いていない品の原価を載せることと、値上げを見過ごすことの2つです。 前者は手書きの訂正を読み落とすと起き、後者はAIが数字を直して返すと起きます。どちらも「読み取ったとおりに返させ、判断は人と規則が行う」という線で防ぐので、そこだけは設計で守ります。
10まず何から始めるか
1週目:食材の一覧に3つの列を足す
食材の一覧に、言い換え、入数、時価の品目かの3列を足します。全品目を一度に埋める必要はありません。仕入の金額の多い上位100品目から埋めます。 この100品目で、月の仕入の大半が占められます。
2週目:30枚で試す
先月の納品書から30枚を選び、手元のAIサービスに貼り付けて明細の表にさせます。当時の台帳と突き合わせ、数字を直していないか、訂正を見落としていないかを最優先で見ます。
3週目:撮り方と受付フォルダを決める
店舗ごとの受付フォルダを作り、明るい場所で、真上から、1枚ずつ撮る決まりを1枚の紙にして店長に配ります。あわせて、仕入先の一覧に列の並びの癖を書きます。
4週目:読み取りから台帳までをつなぐ
Azure に Document Intelligence のリソースを作り、Apps Script から受付フォルダの画像を読み取らせ、Gemini API で当てはめて台帳に書き込むところまで作ります。この時点では検算と単価の比較を作らず、当てはめの結果だけを見ます。
2か月目: 検算、単位の読み替え、確認の要否の規則を足します。no_match の品名を毎日食材の一覧に足します。3か月目以降: 前回の単価との比較と、単価の変動の記録を足し、1枚5分が何分になったかを実測します。no_match が1割を切り、月末の請求書との差が返品と値引きの処理漏れだけになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
レイアウトモデル(prebuilt-layout)がテキスト、表、選択マーク、構造を取り出すこと。入力が PDF と画像(JPEG/JPG、PNG、BMP、TIFF、HEIF)で、画像が50×50〜10,000×10,000ピクセル、文字の高さが1024×768で12ピクセル以上であること。Free レベルでは PDF・TIFF の最初の2ページのみ。表が rowCount・columnCount・cells(行・列の番号、columnHeader の印)で返ること。手書きの行が styles に信頼度とともに示されること。単語ごとに confidence があること。v4.0 で features=keyValuePairs によりキーと値の組が取れること | Microsoft Learn: ドキュメント レイアウト分析 | 2026-09-29 |
レイアウトモデルが日本語(ja)の印刷の文字と手書きの文字に対応すること | Microsoft Learn: 読み取りとレイアウトの言語サポート | 2026-09-29 |
| AWS Textract の対応言語が英語、フランス語、ドイツ語、イタリア語、ポルトガル語、スペイン語であること。手書きの認識は英語のみで、縦書きに対応しないこと | AWS: Set Quotas in Amazon Textract | 2026-09-29 |
出力の形式にJSONを指定してスキーマを渡し、構文上正しいJSONを受け取れること。enum で値を縛れること。値はアプリケーションの側で検証するよう書かれていること | Google AI for Developers: Structured output | 2026-09-29 |
| 時間主導型トリガーが毎分から月1回までの間隔で動くこと。作成した人のアカウントで動くこと | Google for Developers: Installable Triggers | 2026-09-29 |
仕入先との単価の取り決めを外部のサービスで扱ってよいかは、自社の規程と契約の条件で確かめてください。 本記事は公開されている仕様で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0304)についてのご相談はこちらから。
