飲食店の紙の予約台帳に手書きした予約を読み取って予約のデータにそろえ、重複と席数の超過と連絡先の書き漏れを拾う
レジ横の紙の予約台帳を撮った写真から、手書きの予約を1件ずつ読み取り、日時・人数・名前・連絡先・要望をそろえて店の予約一覧に入れます。あわせて、二重の予約、時間帯の席数の超過、電話番号の書き漏れを拾い、店長に確かめる一覧を出します。
- 生成AI
- ChatGPT/Claude/Gemini
- AIサービス
- Azure AI/Google Document AI
- 連携・自動化
- Google Apps Script/Python
- 対象業界
- 宿泊/飲食
- 対象部門
- 営業
- 対象業務
- データ入力・転記/内容確認・チェック
- 主な課題
- 人手が足りない/入力作業が多い/確認ミスが多い
- AIで行う処理
- 読み取り(OCR)
- 主な効果
- 入力漏れ削減/工数削減/機会損失防止
- 導入難易度
- ★☆☆☆☆
- 実装レベル
- 本格構成
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 電話や店頭で予約を受けた担当が、台帳のその日のページに時間・名前・人数・電話番号・要望を書く
- 閉店後、店長か社員が台帳をめくり、その日に書き足された予約を探す
- 共有の予約一覧に1件ずつ打ち込む。名前はカタカナ、時間は24時間表記にそろえる
- ネット予約の一覧と見比べ、同じ客が電話とネットの両方で予約していないかを見る
- 時間帯ごとの人数を足し、席数を超えていないか、個室が重なっていないかを見る
- 電話番号が無い、桁が足りない予約に付箋を貼り、翌日に受けた担当へ聞く
- アレルギーや記念日の要望を、厨房向けの連絡票に書き写す
- 人電話や店頭で予約を受けた担当が、これまでどおり台帳に書く
- 人昼の営業の終わりと閉店時に、その回に書き足したページを店のタブレットで撮る
- 自動写真の保存をきっかけにプログラムが動き、ページの日付と店を写真の名前から決める
- 自動OCRがページを表として読み、行ごとのセルの文字と読み取りの信頼度を返す
- 自動生成AIが行ごとに、時間・名前・人数・電話番号・要望を予約の形にそろえる
- 自動前回までに取り込んだ予約と突き合わせ、新しく書き足された行だけを残す
- 自動ネット予約との重複、時間帯の席数の超過、電話番号の欠けと桁の不足を規則で調べる
- 自動問題の無い予約は予約一覧に「台帳から」の印を付けて入れ、問題のあるものは確認の一覧に出す
- 人店長が確認の一覧だけを開き、台帳の写真と見比べて直す
- 人電話番号が無い予約は、受けた担当にその日のうちに聞く
各工程の詳しい説明を読む
- 電話や店頭で予約を受けた担当が、台帳のその日のページに時間・名前・人数・電話番号・要望を書く
- 閉店後、店長か社員が台帳をめくり、その日に書き足された予約を探す
- 共有の予約一覧に1件ずつ打ち込む。名前はカタカナ、時間は24時間表記にそろえる
- ネット予約の一覧と見比べ、同じ客が電話とネットの両方で予約していないかを見る
- 時間帯ごとの人数を足し、席数を超えていないか、個室が重なっていないかを見る
- 電話番号が無い、桁が足りない予約に付箋を貼り、翌日に受けた担当へ聞く
- アレルギーや記念日の要望を、厨房向けの連絡票に書き写す
(a)打ち直しが閉店後の疲れた時間に来る。 2番目から7番目までが、1日の最後にまとめて来ます。丁寧にやるほど帰りが遅くなるので、忙しい日から順に4番目と5番目が省かれます。
(b)二重の予約が当日に分かる。 同じ幹事が、電話で予約したあと念のためネットでも予約を入れる。電話の予約が一覧に入るのが翌日の昼なら、その間にネットの予約が入り、どちらも生きたまま当日を迎えます。 当日に8名の席を2つ用意し、片方が空いたままになります。
(c)席数の超過は、紙の上では見えない。 台帳の1ページには、時間の順に書かれているとは限りません。18時の予約の下に19時半、その下に18時半が書き足されます。同じ時間帯に何名が入っているかは、足し算をしないと分かりません。 電話を受けながらその足し算をする余裕はありません。
(d)電話番号の書き忘れが当日まで残る。 「タナカ様 4名 19時」とだけ書かれた予約は、時間を過ぎても来ないときに連絡のしようがありません。書き忘れに気づくのが打ち直しのときなら、まだ受けた担当に聞けます。それが翌日の昼に回ると、聞いても覚えていません。
- 【人】 電話や店頭で予約を受けた担当が、これまでどおり台帳に書く
- 【人】 昼の営業の終わりと閉店時に、その回に書き足したページを店のタブレットで撮る
- 【自動】 写真の保存をきっかけにプログラムが動き、ページの日付と店を写真の名前から決める
- 【自動】 OCRがページを表として読み、行ごとのセルの文字と読み取りの信頼度を返す
- 【自動】 生成AIが行ごとに、時間・名前・人数・電話番号・要望を予約の形にそろえる
- 【自動】 前回までに取り込んだ予約と突き合わせ、新しく書き足された行だけを残す
- 【自動】 ネット予約との重複、時間帯の席数の超過、電話番号の欠けと桁の不足を規則で調べる
- 【自動】 問題の無い予約は予約一覧に「台帳から」の印を付けて入れ、問題のあるものは確認の一覧に出す
- 【人】 店長が確認の一覧だけを開き、台帳の写真と見比べて直す
- 【人】 電話番号が無い予約は、受けた担当にその日のうちに聞く
9番目が、この設計の分かれ目です。人が見るのは全件ではありません。 書かれたとおりに読めて、重複も超過も無い予約は、そのまま一覧に入ります。店長が開くのは、確認の一覧に出た行と、その行の写真だけです。 全件を人が見直す設計にすると、打ち直しが見直しに変わるだけで、60.0時間はほとんど減りません。
2番目を1日2回にしているのは、(b)の二重予約を早く見つけるためです。昼の撮影で取り込んでおけば、夕方に入ったネット予約と突き合わせられます。
02今回想定するシステム構成
紙の予約台帳(店ごと・日付ごとのページ) │ 昼の営業の終わりと閉店時に、書き足したページを撮影 ▼【トリガー】共有フォルダへの写真の保存 Python ── 写真の名前から店と日付を決める、形式と向きの確認 ▼ Google Document AI(Form Parser) │ 表のセル(行と列)、全文、読み取りの信頼度を返す ▼ Claude API ── 行ごとに予約の形へそろえる │ 時間/名前/人数/電話番号/要望/受けた担当 ▼ Python ── 前回までの取り込みと照合して新しい行だけを残す │ ネット予約との重複、時間帯の席数、電話番号の桁を調べる ▼ 予約一覧(問題の無い行は「台帳から」の印を付けて追加) ▼ 確認の一覧 ──▶【店長が写真と見比べて直す】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| OCR | Google Document AI(Form Parser) | Azure AI Document Intelligence |
| 生成AI | Claude API(行ごとの予約の項目そろえ) | OpenAI API、Gemini API |
| 連携 | Python(写真の受け取り、前回との照合、重複と席数の判定) | Google Apps Script |
| 保管 | 共有のスプレッドシート(予約一覧と確認の一覧) | 予約管理のシステム |
予約一覧とネット予約の書き出しは、新しく足すものではありません。 足すのは、台帳を撮る手順と、写真を読んで一覧に入れる小さなプログラムです。最初の準備は、台帳の様式を作り直すことです(第7章の前処理)。
土台は Document AI の Form Parser です。 公式のプロセッサ一覧では、OCRのテキストに加えてキーと値のペア、チェックボックス、表を抽出するとされ、言語の一覧で日本語(ja)は手書きに対応する言語として示されています。台帳は罫線で区切った表なので、行と列のセルとして読めることが、この題材にいちばん効きます。 1行が1件の予約になるからです。
Form Parser の表の扱いには、はっきりした制約があります。 公式の説明では、表の抽出は行や列をまたぐセルの無い、ふつうの表だけを認識するとされ、返るセルの rowSpan と colSpan は常に1です。時間の欄を2行分つなげて書く、要望を隣の欄まではみ出して書く、という台帳の使い方は、そのままでは表として読めません。 様式と書き方の取り決めを先に決める理由が、ここにあります。
Form Parser は、電話番号や日時のような11種類の一般的な項目も見分けます。 公式のページでは、電子メール、電話番号、URL、日時、住所、人名、組織名、数量、価格、ID、ページ番号が挙げられています。電話番号の欄の値が電話番号らしい形をしているかを、OCRの段階で一度確かめられます。
処理する場所は選べますが、日本はありません。 プロセッサ一覧の Form Parser の対応リージョンは、us、eu、シンガポール(asia-southeast1)、インド(asia-south1)、オーストラリア(australia-southeast1)などで、日本のリージョンは一覧にありません。 台帳には客の名前と電話番号が書かれているので、国外で処理してよいかを導入前に会社として決めます(第13章)。
03どうやって実装するのか
処理の起点を決める
共有フォルダに台帳の写真が保存されたことを起点にします。 撮るのは1日2回、昼の営業が終わった時と、閉店した時です。撮るたびに、Python のプログラムが1分おきにフォルダを見て、新しい写真を処理します。
撮るのは、その回に書き足したページだけです。台帳をめくりながら、書き足したページの角に付箋を貼っておき、撮影のときに付箋のページだけを撮ります。撮り終えたら付箋をはがします。全ページを毎回撮ると、照合の手間が増えるだけで得るものがありません。
写真の名前は、タブレットの撮影アプリで「店番号_予約日」を選んでから撮る形にします。予約日をページの見出しから読ませないのは、見出しの日付が手書きのことが多いからです。 日付を読み違えると、その日の予約が丸ごと別の日に入ります。処理が終わった写真は処理済みのフォルダへ移します。移すのは成功したときだけにし、元のフォルダに残った数が未処理の数になるようにします。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 台帳の写真 | 1ページ分。店番号、予約日、撮影日時 | 共有フォルダ |
| 読み取り結果 | 表のセル(行・列)、全文、セルごとの信頼度、電話番号などの一般的な項目 | Google Document AI |
| 取り込み済みの予約 | その店・その日について前回までに取り込んだ行 | 予約一覧 |
| ネット予約 | 予約日、時間、名前、人数、電話番号 | グルメサイトの管理画面から書き出した一覧 |
| 店の席の情報 | 時間帯の区切り、席数、個室の名前と定員、1組の上限人数 | 店の席の一覧(スプレッドシート) |
| 担当の一覧 | ホールの担当の名前と略称 | 店のスタッフの一覧 |
質を決めるのは、店の席の情報です。 「18時台に何名まで入れるか」が決まっていないと、超過は判定できません。席数をそのまま上限にすると、テーブルの組み合わせで入らない人数を見落とします。 4名席が5つある店に3名の予約が5組入れば、人数は15名でも席は埋まっています。上限は人数と組数の両方で持ちます。
担当の一覧を渡すのは、台帳の「受付」の欄に略称や名字の1文字しか書かれないからです。 「ヤ」「山」「山田」が同じ人だと分からないと、電話番号の書き忘れを誰に聞けばよいかが決まりません。
データの取得方法を決める
読み取りは、Python から Form Parser のプロセッサを呼ぶだけです。オンラインの処理は1回の要求で最大15ページで、台帳の写真は1ページずつ送るので上限に届きません。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 表のセル | 各ページの tables の headerRows/bodyRows の cells | 1行を1件の予約として扱う |
| 全文 | 応答の text と、各セルの textAnchor | セルの文字を取り出す |
| 信頼度 | 各要素の layout の confidence | 読めたセルと読めなかったセルの区別 |
| 位置 | layout の boundingPoly | 確認の画面で、写真の該当の行に枠を出す |
| 一般的な項目 | 電話番号(phone)、日時(date_time)、人名(person) | 電話番号の欄の値の形の確かめ |
表の見出しの行で、列の意味を決めます。 headerRows のセルに「時間」「お名前」「人数」「電話」「ご要望」「受付」と書かれていれば、その列番号を覚えておき、bodyRows の各セルを列の意味で読みます。見出しの文字は印刷なので、手書きの欄より読み取りが安定します。
ネット予約は、毎朝と夕方にグルメサイトの管理画面から書き出した一覧を使います。書き出しの方法はサイトごとに違うため、この部分は利用環境に応じた個別実装になります。 書き出しのAPIがあるサイトもあれば、管理画面から一覧をダウンロードするしかないサイトもあります。
AIへ渡す前に整形する
- 台帳の様式を作り直す … 時間・お名前・人数・電話・ご要望・受付の6列の罫線を印刷した様式にします。セルを結合した欄を作りません
- 書き方を決める … 1件は1行に書き、要望が長いときは隣の欄にはみ出さず、ページ下の「メモ」欄に行番号を付けて書きます
- 形式の確認 … 公式の対応形式は PDF、GIF、TIFF、JPEG、PNG、BMP、WebP などです。タブレットの写真は JPEG で保存し、撮影後に圧縮し直さない設定にします
- 解像度の確認 … 公式のページでは、スキャンは最低200dpiが望ましく、300dpi以上が一般に最もよいとされています。写真では、ページの4隅が画面いっぱいに入る距離で撮ります
- 向きと傾きの確認 … 横向きの写真は回転させ、4隅が写っていない写真は撮り直しに回します
- 見開きの片側を切る … 見開きで撮った写真は、写真の名前の日付のページだけを残します
- 重複の確認 … 同じ店・同じ予約日の写真が同じ回に2枚あれば、新しいほうを使います
1番目と2番目を省くと、この構成は動きません。 公式の説明では、Form Parser の表の抽出は行や列をまたぐセルの無い表だけを認識します。いまの台帳に「18時」を2行分の大きな文字で書く習慣があれば、その2行は表として読まれません。様式を作り直すのは、AIのためというより、表として読める紙にするためです。
4番目は、撮影の手順として最初に決めます。 レジ横の暗い場所で急いで撮ると、影が入り、ページが傾きます。読み取りの信頼度が低い写真の多くは、撮り方の問題です。
AIに処理させる
させるのは、表の1行を1件の予約の形にそろえることだけです。 行ごとのセルの文字を受け取り、時間・名前・人数・電話番号・要望・受けた担当の6つに直して返させます。重複と超過の判定はさせません。
| 項目 | そろえ方 | 判断できないときの扱い |
|---|---|---|
| 時間 | 「6時半」「18:30」「18半」を24時間表記の時刻に直す | 午前か午後か決まらなければ ambiguous |
| 名前 | 書かれた名前をカタカナにそろえ、敬称を外す | 読めなければ unreadable |
| 人数 | 「大人4子2」「4+2」を大人と子どもの数に分ける | 合計しか読めなければ合計だけ入れる |
| 電話番号 | 数字とハイフンだけを写す | 空欄なら blank、読めなければ unreadable |
| 要望 | アレルギー、記念日、子ども椅子、個室、コースに分ける | 分けられなければ other にして原文を残す |
| 受けた担当 | 担当の一覧の略称から名前を決める | 一覧に無ければ原文のまま |
右端の列が、この構成でいちばん大事な区別です。 電話番号の blank は受けた人が書かなかったということ、unreadable は文字はあるが確定できないということです。前者は受けた担当に聞くもの、後者は台帳を見直せば済むものです。
分ける材料は、セルの信頼度と、セルに文字が検出されたかどうかです。 公式のページでは、Form Parser は値の入っていないキーと値の組を確実には読み取れないとされています。空欄の判定を、キーと値のペアに頼らず、表のセルに文字が検出されたかどうかで行うのはこのためです。
| させないこと | 理由 |
|---|---|
| 電話番号の桁を補う | 10桁に足りない番号を、それらしい番号に直さない |
| 名前の漢字を当てる | 「サトウ」を「佐藤」に直すと、別の客と取り違える |
| 重複かどうかの判断 | 規則で決め、店長が確かめる |
| 予約を受けてよいかの判断 | 席の振り方は店長の仕事 |
| 要望の中身の評価 | 「えびNG」を「甲殻類アレルギー」に広げない |
いちばん起きやすい失敗は、電話番号の補完です。 「090-12-5678」のように桁が足りない番号を渡すと、それらしい11桁に直して返すことがあります。直された番号は、客にかけてもつながりません。 桁が足りないこと自体が、受けた担当に聞くべき合図です。
指示内容を固定する
あなたは飲食店の予約係の補助として、紙の予約台帳の1ページを
予約の一覧に写す立場です。OCRが返した表のセルだけを見て、
1行を1件の予約の形にそろえてください。推測で埋めないでください。
【列の意味】
time(時間)/name(お名前)/party(人数)/phone(電話)/
request(ご要望)/staff(受付)
【そろえ方】
- time は 24時間表記の HH:MM にしてください。「6時半」のように
午前か午後か決まらない書き方は、店の営業時間の内側で解釈し、
それでも決まらなければ time_status を ambiguous にしてください。
- name は書かれた名前をカタカナにそろえ、「様」「さん」を外してください。
漢字が書かれていても、読みが一つに決まらないときは原文のまま
name_raw に入れ、name_kana を空にしてください。
- party は大人と子どもに分けてください。分けられなければ total だけ入れます。
- phone は数字とハイフンだけを写してください。
- request は allergy/celebration/child_seat/private_room/course/other
のどれかに分け、原文を request_raw にそのまま残してください。
【厳守事項】
- 電話番号の桁を補わないでください。足りなくても、読めたとおりに写してください。
- 空欄のセルは値を書かずに status を blank にしてください。
- 文字はあるが読めないセルは「(判読不能)」とし、status を unreadable にしてください。
空欄と読めないセルを混ぜないでください。
- 名前に漢字を当てないでください。
- アレルギーの記載を広げたり、言い換えたりしないでください。
「えびNG」は「えびNG」のまま request_raw に写してください。
- 二重の予約かどうか、受けてよい予約かどうかを書かないでください。
- 取り消し線が引かれた行は、cancelled を true にしてください。
消された内容を読み取ろうとしないでください。
- ページ下のメモ欄の「3行目:…」のような書き足しは、その行の
request_raw に足してください。
【店の営業時間】{business_hours}
【担当の一覧】{staff_list}
【表のセル(行ごと・列ごと、信頼度つき)】{table_cells}
「取り消し線の行」を指示に入れているのは、台帳の取消がたいてい線で消すだけだからです。 何も言わなければ、消された予約もそのまま1件として返ります。取消の印を付けさせ、予約一覧の側で、すでに入っている同じ行を取消に変えます。
「午前か午後か」を店の営業時間で決めさせるのは、台帳の「6時」がほぼ18時だからです。 ただしランチ営業のある店では、「11時半」と「1時」のどちらも昼です。営業時間を渡し、それでも決まらないものだけを ambiguous にします。
出力形式を固定する
次の形のJSONで受け取ります。 Claude API の構造化出力(output_config.format に JSON スキーマを渡す方式)を使い、形を固定します。
{
"store_id": "",
"reservation_date": "",
"rows": [
{
"row_no": 0,
"time": "", "time_status": "ok | ambiguous | blank | unreadable",
"name_kana": "", "name_raw": "",
"party": { "adult": 0, "child": 0, "total": 0 },
"phone": "", "phone_status": "ok | blank | unreadable",
"request_type": ["allergy | celebration | child_seat | private_room | course | other"],
"request_raw": "",
"staff": "",
"cancelled": false,
"min_confidence": 0
}
]
}
1つ目の理由は、照合をプログラムの規則で行えることです。 前回までに取り込んだ行と、予約日・時間・名前のカナ・電話番号の4つで突き合わせます。4つとも一致すれば同じ行、時間か人数だけが違えば「書き直された行」として確認の一覧に出します。
2つ目は、確認の一覧に出す条件を、AIでなくプログラムが決められることです。
| 条件 | 確認の一覧に出す理由 |
|---|---|
phone_status が blank | 受けた担当に聞く。その日のうちに |
| 電話番号の桁が10桁・11桁でない | 書き間違いの疑い |
| 同じ予約日に、ネット予約と名前のカナか電話番号が一致 | 二重の予約の疑い |
| 時間帯の人数か組数が上限を超える | 席数の超過 |
| 同じ個室に重なる時間の予約が2件以上 | 個室の重なり |
time_status が ambiguous か unreadable | 時間を写真で確かめる |
min_confidence がしきい値を下回る | 写真で確かめる |
3つ目は、request_type で厨房への連絡をそのまま並べ替えられることです。 allergy と course だけを予約日の順に並べれば、厨房向けの連絡票になります。原文の request_raw を必ず添えて出します。 分類が外れていても、原文を読めば分かります。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 共有フォルダ | Python の定期の確認 | 新しい写真を見つける |
| Google Document AI | API呼び出し | 表のセル・全文・信頼度を返す |
| Claude API | API呼び出し | 行ごとに予約の形へそろえる |
| 予約一覧 | スプレッドシートへの追記 | 問題の無い行を「台帳から」の印で足す |
| 確認の一覧 | スプレッドシートへの追記 | 確認の条件に当たった行と、写真へのリンク |
| ネット予約 | 書き出した一覧の読み取り | 重複の照合に使う |
予約一覧には足すだけで、消しません。 取り消し線の行も、一覧の行を消すのではなく「取消」の印を付けます。消すのは店長が確かめてからです。 プログラムが消した予約は、誤っていたときに戻す手がかりが残りません。
グルメサイトの側には書き込みません。 二重の予約が見つかっても、ネットの予約を取り消すのは客に確かめてからです。この構成が出すのは、確かめるべき予約の一覧までです。
人が確認する
店長が開くのは確認の一覧だけです。 一覧の各行から、台帳の写真の該当の行に枠を付けて開けるようにしておきます。写真と一覧を並べ、読み取りの結果が台帳のとおりかを見ます。
- 電話番号の
blankを先に片づける … 受けた担当がまだ店にいるうちに聞きます。昼の撮影の分は夕方の営業前に、閉店の分はその場で - 二重の予約の疑いを見る … 同じ客かどうかを確かめ、同じなら客に電話して、どちらを残すかを聞きます
- 席数の超過を見る … テーブルの組み合わせで入るなら、そのまま通します
- 時間と信頼度の低い行を見る … 写真で確かめて直します
- 直したら記録する … どの項目を何から何に変えたかを残します
1番目を急ぐのは、(d)で書いたとおり、時間がたつと受けた担当も覚えていないからです。 一覧に出たその日のうちに聞けば、たいていは「メモ用紙に書いた」と出てきます。
目標は、900件をならして1件1分です。 確認の一覧に出るのは2割前後という想定で、それより多い月は、撮り方が崩れているか、様式からはみ出して書く担当がいます。
例外に対処する
| 起きること | 対応 |
|---|---|
| 表として読まれない(セルが返らない) | 様式の外に書かれている。全文だけを渡し、行の判定をせずに確認の一覧へ |
| 結合したようなセル(2行分の大きな字) | 表の抽出の対象外。書き方の取り決めを担当に伝え直す |
| 写真の名前の予約日と、ページの見出しが違う | 処理を止め、撮り直しに回す |
| 同じ行の時間や人数が書き直されている | 前回の行と比べて「書き直された行」として確認へ |
| 取り消し線の行 | cancelled を付け、一覧の同じ行を取消に変える候補として確認へ |
| ページ下のメモ欄の書き足し | 行番号を手がかりに要望に足す。番号が読めなければ確認へ |
| ネット予約の一覧が古い | 書き出した日時を見て、半日より古ければ重複の判定を保留する |
| OCRが応答しない | 写真を元のフォルダに残し、次の回にやり直す |
上から2行目までが、運用の最初の1か月にいちばん多く出ます。 どれもAIの問題ではなく、台帳の書き方の問題です。 担当ごとに件数を数え、多い担当にだけ書き方を伝え直します。
記録を残す
- 台帳の写真と、店番号・予約日・撮影日時
- OCRが返したJSONの全文(表のセル、全文、信頼度)
- AIが返した行ごとの予約と、そのとき照合した取り込み済みの行とネット予約の一覧
- 確認の一覧に出した理由と、店長が直した記録(項目、変更前、変更後)
- 電話番号を受けた担当に聞いた日時と、聞けたかどうか
- 担当ごとの、様式からはみ出した行と
blankの件数
3つ目で「照合した一覧」を残すのは、二重の予約の疑いを後から説明するためです。 同じ客の2件のうち、どちらを残したかで揉めたとき、その時点でどちらが先に入っていたかを示せます。
04実装レベルの3段階
最小構成は、確かめるための段階です。 出てきた表を手で一覧に写すので、件数はさばけません。 半自動化で、1件4分が2分程度になります。 読み取りは自動になりますが、新しい行を探すことと、重複と席数の確認が手で残ります。本格構成で1分になり、この段階が本記事の想定です。 差が大きいのは、前回の取り込みとの照合と、時間帯ごとの足し算が、1件ずつの手作業だからです。 段階を飛ばさないでください。 半自動化の一覧を2週間見ると、様式からはみ出して書く担当と、読み取りの信頼度が低い撮り方が先に分かります。そこを直してから照合を足すほうが、「書き直された行」の空振りが減ります。
05工数削減シミュレーション
導入後 900件 × 1分 ÷ 60 = 15 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 電話や店頭で受けた予約を、レジ横の紙の予約台帳に手で書いている飲食店。ネット予約は別の一覧で持っており、閉店後に店長や社員が台帳の予約を一覧へ打ち直している場合。同じ客の予約を電話とネットで二重に受けた、時間帯の席数を超えて受けた、電話番号を書き忘れて当日の連絡が取れなかった、ということが月に何度か起きている場合。台帳の様式を、罫線で区切った表の形に作り直せる場合。
- 予約をすべて予約管理のシステムやタブレットで受けており、紙の台帳が残っていない店。1日の予約が数件で、店長が頭の中で席を把握できている店。客の名前と電話番号を国外のリージョンで処理することを会社として認められない場合。なお、どの予約を断るか、どの席に通すかの判断は、この構成では代替できません。
07最小構成で試す方法
- 先週の台帳から、予約が多かった日のページを5枚選ぶ
- スマートフォンで、明るい場所で真上から撮る
- 手元の生成AIのサービスの画面に1枚ずつ貼り付ける
- 「この予約台帳の写真を1行ずつ読み、時間・名前(カタカナ)・人数・電話番号・要望を表にしてください。電話番号が空欄の行と、読めない行を分けてください。電話番号の桁を補わないでください」と指示する
- 出てきた表を、予約一覧に打ち込んだ内容と突き合わせる
5枚は必ずやってください。 プログラムを組む前に、「この台帳の書き方で、表として読めるのか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 予約一覧とほぼ同じ表が出た | Form Parser とプログラムの連携に進む |
| 電話番号の桁を補った、名前に漢字を当てた | 指示の書き方で直る。構成は有効 |
| 行がずれる、2件が1件にまとまる | 台帳の様式が先。 AIの問題ではない |
3行目が出ることは珍しくありません。 罫線の入った様式に変えて1週間書いてもらい、同じことをやり直してください。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 行がずれる、2件が1件にまとまる | 表の抽出は行や列をまたぐセルの無い表だけ。 様式から結合した欄をなくす |
| 撮るたびに予約が増える | 前回の取り込みと4項目で照合し、新しい行だけを足す |
| 電話番号の空欄が「読めない」に紛れる | 空欄はセルに文字が無いこと、読めないは信頼度で分ける |
| 電話番号の桁が補われる | 補完を禁じ、桁数の確かめはプログラムで行う |
| 「6時」が朝の6時になる | 営業時間を渡し、決まらないものは ambiguous |
| 取り消した予約が生きたまま残る | 取り消し線の行に印を付けさせ、一覧の行を取消に変える |
| 席数の超過を人数だけで見る | 人数と組数の両方を上限に持つ |
| ネット予約の一覧が古くて重複を見落とす | 書き出した日時を見て、古ければ判定を保留する |
| 名前に漢字を当てて別の客と混ざる | カタカナにそろえ、漢字は原文のまま残す |
| 予約日を見出しから読んで別の日に入る | 予約日は写真の名前で決める |
| 撮影が閉店時だけになる | 昼の撮影を決まった作業にする。二重予約を早く拾うため |
| 確認の一覧を店長が見ない | 一覧に出る件数を毎週数え、2割を大きく超えたら様式と撮り方を見直す |
上の4行が、この構成の失敗のほとんどです。 どれも「紙に書かれた行を、そのとおりの数だけ、そのとおりの中身で取り込む」という同じことから来ています。表として読める紙にすることと、前回との照合を作ることの2つで、ほぼ防げます。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 客の名前、電話番号、来店の日時と人数、そしてアレルギーや記念日のような要望です。
- 国外で処理してよいかを先に決める … Form Parser の対応リージョンに日本はありません。客の名前と電話番号が国外のリージョンで処理されることを、会社として認めるかを導入前に決めます。 認められない場合は、日本のリージョンで処理できる別のOCRを検討します
- 生成AIに渡すのは表のセルだけにする … 写真そのものではなく、Form Parser が返したセルの文字を渡します。予約一覧の全件やネット予約の一覧は渡しません。 照合はプログラムの側で行います
- アレルギーの記載を言い換えさせない … 「えびNG」を「甲殻類アレルギー」に広げると、厨房が出してよい食材を外します。逆に狭めると事故になります。厨房へは原文を必ず添えて渡します
- 確定は人が行う … 二重の予約の取り消し、席数を超えた予約の扱いは、客に確かめたうえで店長が決めます。この構成はグルメサイトにも客にも何も送りません
- 写真を残す期間を決める … 台帳の写真には、その日の全員の名前と電話番号が写っています。予約日が過ぎて一定の期間がたったら消す、という期間を先に決めます
- タブレットを店に置きっぱなしにしない … 撮影したタブレットには写真が残ります。撮影アプリから共有フォルダへ送ったら、端末の側は消す設定にします
誤りが起きた場合のリスクは、予約が一覧から落ちることと、二重の予約を見落とすことの2つです。 前者は表として読めない行を黙って捨てると起き、後者はネット予約の一覧が古いまま照合すると起きます。どちらも、確認の一覧に「読めなかった行」と「判定を保留した行」を必ず出すことで防ぎます。
10まず何から始めるか
1週目:台帳の様式を作り直す
時間・お名前・人数・電話・ご要望・受付の6列の罫線を印刷した様式を作り、1店舗で使い始めます。結合した欄を作らないことと、1件を1行に書くことを、ホールの担当に伝えます。
2週目:5ページで試す
新しい様式で書いたページを5枚撮り、手元の生成AIの画面に貼り付けて表にさせます。電話番号の桁を補っていないか、空欄と読めない欄が分かれているかを最優先で見ます。
3週目:席の情報をそろえる
時間帯の区切り、時間帯ごとの人数と組数の上限、個室の名前と定員を一覧にします。ここが決まらないうちに超過の判定を作ると、毎日のように空振りの行が並びます。
4週目:撮影から確認の一覧までをつなぐ
Python で共有フォルダを見て Form Parser を呼び、行ごとの予約を確認の一覧に書き出すところまで作ります。この時点では予約一覧に書き込まず、確認の一覧だけを店長が見ます。
2か月目: 前回の取り込みとの照合と、ネット予約との重複、席数の判定を足し、問題の無い行を予約一覧に入れます。3か月目以降: 残りの2店舗に広げ、1件4分が何分になったかを実測します。確認の一覧に出る件数が2割前後で落ち着き、閉店後の打ち直しがなくなった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
Form Parser がOCRのテキストに加えてキーと値のペア、チェックボックス、表、一般的な項目を抽出すること。言語の一覧で日本語(ja)が手書きに対応する言語として示されていること。オンラインの処理が1回の要求で最大15ページであること。対応リージョンが us、eu、asia-southeast1、asia-south1、australia-southeast1 などで、日本が含まれていないこと | Google Cloud: Processor list | 2026-10-08 |
| 表の抽出が行や列をまたぐセルの無い表を対象とすること。電子メール、電話番号、URL、日時、住所、人名、組織名、数量、価格、ID、ページ番号の11の一般的な項目を抽出すること。値の入っていないキーと値の組を確実には読み取れないこと | Google Cloud: Form Parser | 2026-10-08 |
表が tables の headerRows/bodyRows の cells で返り、Form Parser では rowSpan と colSpan が常に1であること。各要素の layout に textAnchor、confidence、boundingPoly が入ること | Google Cloud: Handle the processing response | 2026-10-08 |
| 対応形式が PDF、GIF、TIFF、JPEG、PNG、BMP、WebP などであること。JPEG のような非可逆の形式でファイルを小さくすると精度が落ちうること。スキャンは最低200dpiが望ましく300dpi以上が一般に最もよいこと | Google Cloud: Supported files | 2026-10-08 |
output_config.format に JSON スキーマを渡して応答の形を固定できること。列挙の値の大文字・小文字は保証されないこと。max_tokens で打ち切られたときはスキーマに合わない出力になりうること | Claude API: Structured outputs | 2026-10-08 |
どの予約を断るか、どの席に通すか、アレルギーの申し出にどう応えるかは、店長と料理長が決めてください。 本記事は各製品の公式ページで確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1057)についてのご相談はこちらから。
