ゴルフ場のコンペで回収する手書きのスコアカードを読み取り、ホールごとの打数を集計表に転記して、合計の計算違いを拾い、順位表の下書きを作る
コンペで回収した手書きのスコアカードを読み取り、プレーヤーごと・ホールごとの打数を集計表に転記します。記入された OUT・IN・合計とホールの打数の足し算が合わないカードを拾い、順位表の下書きを作ります。
- 生成AI
- ChatGPT/Claude
- AIサービス
- Azure AI/Google Document AI
- 連携・自動化
- Google Apps Script/Make/Python
- 対象業界
- その他/宿泊
- 対象部門
- カスタマーサポート/営業
- 対象業務
- データ入力・転記/集計・分析
- 主な課題
- 人手が足りない/入力作業が多い/確認ミスが多い
- AIで行う処理
- 読み取り(OCR)
- 主な効果
- 入力漏れ削減/対応スピード向上/工数削減
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 半自動化
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- プレーヤーが各ホールの打数をスコアカードに書き、上がった後に OUT・IN・合計を書いて提出する
- コンペ担当がカードを回収し、組の順に並べる
- 担当者が、カードを見ながら集計表のプレーヤーの行に18ホールの打数を打ち込む
- 集計表が出した合計と、カードに書かれた合計を見比べる
- 合わないときは、カードの打数を1つずつ足し直し、プレーヤーの計算違いか、自分の打ち間違いかを確かめる
- プレーヤーの計算違いなら、幹事に伝えて扱いを決めてもらう
- 集計表の式でハンディキャップと順位を出し、順位表を印刷して幹事に渡す
- 人コンペ担当が、回収したカードをフロントの複合機でスキャンし、コンペ番号のフォルダに保存する(組ごとに1枚ずつ、上がった組から順に)
- 自動保存をきっかけにスクリプトが動き、ファイルの形式と画像の向きを確かめる
- 自動OCR(Form Parser)が、カードの表の行とセル、プレーヤーの名前の欄、それぞれの読み取りの信頼度を返す
- 自動スクリプトが、カードの書式の対応表に沿って、プレーヤーごと・ホールごとの打数と、記入された OUT・IN・合計を取り出す
- 自動ホールの打数の合計を計算し、記入された OUT・IN・合計と比べて、セルごとに状態を付ける
- 自動生成AIが、手書きの名前と組み合わせ表の名前が一致しないときだけ、対応の候補を出す
- 自動打数を集計表に書き込み、確認が要るカードを一覧にする
- 人コンペ担当が、一覧のカードだけを開き、信頼度の低いセルと合計の食い違いを紙と見比べる
- 人プレーヤーの計算違いと分かったものは、幹事に伝えて扱いを決めてもらう
- 人集計表の式で順位を出し、順位表を確かめて印刷する
各工程の詳しい説明を読む
- プレーヤーが各ホールの打数をスコアカードに書き、上がった後に OUT・IN・合計を書いて提出する
- コンペ担当がカードを回収し、組の順に並べる
- 担当者が、カードを見ながら集計表のプレーヤーの行に18ホールの打数を打ち込む
- 集計表が出した合計と、カードに書かれた合計を見比べる
- 合わないときは、カードの打数を1つずつ足し直し、プレーヤーの計算違いか、自分の打ち間違いかを確かめる
- プレーヤーの計算違いなら、幹事に伝えて扱いを決めてもらう
- 集計表の式でハンディキャップと順位を出し、順位表を印刷して幹事に渡す
(a)打ち込みが、最終組の後に集中する。 早く上がった組のカードから打ち込んでいても、最終組の数組分は表彰式の直前に残ります。急ぐほど、隣の列に打ち込む誤りが増えます。
(b)合計の食い違いの原因が分からない。 集計表の合計とカードの合計が合わないとき、それがプレーヤーの足し算の誤りか、打ち込みの誤りかは、カードを足し直すまで分かりません。 1枚で数分かかることもあります。
(c)出し直しが表彰式を遅らせる。 表彰式の直前に打ち込みの誤りが見つかると、順位を出し直して印刷し直すことになります。幹事を待たせることが、そのままゴルフ場への評価になります。
(d)手書きの数字の癖。 「1」と「7」、「4」と「9」、「6」と「0」は、急いで書いた字ほど見分けにくくなります。目で読んでも迷う字は、打ち込む人によって読み方が変わります。
- 【人】 コンペ担当が、回収したカードをフロントの複合機でスキャンし、コンペ番号のフォルダに保存する(組ごとに1枚ずつ、上がった組から順に)
- 【自動】 保存をきっかけにスクリプトが動き、ファイルの形式と画像の向きを確かめる
- 【自動】 OCR(Form Parser)が、カードの表の行とセル、プレーヤーの名前の欄、それぞれの読み取りの信頼度を返す
- 【自動】 スクリプトが、カードの書式の対応表に沿って、プレーヤーごと・ホールごとの打数と、記入された OUT・IN・合計を取り出す
- 【自動】 ホールの打数の合計を計算し、記入された OUT・IN・合計と比べて、セルごとに状態を付ける
- 【自動】 生成AIが、手書きの名前と組み合わせ表の名前が一致しないときだけ、対応の候補を出す
- 【自動】 打数を集計表に書き込み、確認が要るカードを一覧にする
- 【人】 コンペ担当が、一覧のカードだけを開き、信頼度の低いセルと合計の食い違いを紙と見比べる
- 【人】 プレーヤーの計算違いと分かったものは、幹事に伝えて扱いを決めてもらう
- 【人】 集計表の式で順位を出し、順位表を確かめて印刷する
1番目を「上がった組から順に」にするのが、表彰式に間に合わせる鍵です。 最終組を待ってまとめてスキャンすると、読み取りが速くなっても直前の集中は残ります。早い組の分は、最終組が上がるころには確認まで終わっています。
8番目で開くのは、一覧に出たカードだけです。 信頼度が高く、合計も合っているカードは、集計表の行を流し見て終わりにします。全部のカードを紙と見比べる設計にすると、30.0時間はほとんど減りません。
02今回想定するシステム構成
スコアカード(紙・手書き。1枚=1組・最大4人) │ 上がった組から順にフロントの複合機でスキャン ▼【トリガー】コンペ番号のフォルダへの保存 Google Apps Script ── 形式・向きの確認 ▼ Google Document AI(Form Parser) │ 表の行とセル/名前の欄/信頼度 ▼ Google Apps Script ── カードの書式の対応表で、人×ホールの打数に並べ直す │ ホールの合計 と 記入された OUT・IN・合計 の照合 ▼ Claude API ── 手書きの名前と組み合わせ表の対応の候補(一致しないときだけ) ▼ コンペの集計表(打数の書き込み)/確認が要るカードの一覧 ▼ 【担当者が一覧のカードだけ紙と見比べる】──▶ 集計表の式で順位 ──▶ 順位表の印刷
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| OCR | Google Document AI(Form Parser) | Azure AI Document Intelligence(レイアウトモデル) |
| 差異計算 | Google Apps Script(ホールの合計と記入された合計の照合、セルごとの状態の判定) | Python |
| 生成AI | Claude API(手書きの名前と組み合わせ表の対応の候補) | OpenAI API |
| 連携 | Google Apps Script(フォルダの監視、OCRの呼び出し、集計表への書き込み) | Make |
| 保管 | Google ドライブ(コンペ番号ごとのフォルダ)、Google スプレッドシート(集計表) | 予約のシステムの添付機能 |
集計表と組み合わせ表は、新しく足すものではありません。 打数を入れれば順位が出る今の集計表に、打数の列を外から書き込めるようにするだけです。最初の準備作業は、スコアカードの書式について、表の何行目・何列目が誰の何番ホールかの対応表を作ることです。
土台になるのは、Google Document AI の Form Parser です。 記入欄の名前と値の組、チェックボックス、表を取り出すプロセッサで、プロセッサの一覧では、対応言語の表で日本語(ja)に手書きの対応が付いています。 推奨の版は pretrained-form-parser-v2.0-2022-11-10(安定版・GA)です。スコアカードは、ほとんどが手書きの数字の表です。
表は、行や列をまたぐセルの無い単純な表だけが対象です。 返るセルの rowSpan と colSpan は常に1です。スコアカードは、「OUT」「IN」の見出しや、プレーヤーの名前の欄が結合したセルになっている書式が少なくありません。 自社で書式を決められるので、結合セルを使わない形に作り直すのがこの構成の最初の仕事になります。
生成AIの役割は小さく置きます。 手書きの名前が組み合わせ表と一致しないときに候補を出すだけで、打数には触れさせません。コンペには学生や未成年のプレーヤーが混ざることもあるため、18歳未満が関わるサービスでの利用を規約で禁じている Gemini API は代替候補から外し、生成AIには名前以外の情報を渡しません。
03どうやって実装するのか
処理の起点を決める
コンペ番号のフォルダにファイルが保存されたことを起点にします。 コンペ番号は予約の時点で決まっており、組み合わせ表と集計表もこの番号で作られています。カードの中身からコンペを推定させることはしません。 同じ日に複数のコンペがあると、取り違えます。
スクリプトは1分おきにフォルダを見て、新しいファイルを1枚ずつ流します。上がった組から順にスキャンする運用と組み合わせて、最終組の前に大半を終わらせます。
処理が終わったファイルは処理済みのフォルダへ移します。移すのは成功したときだけです。 コンペのフォルダに残っている数と、組み合わせ表の組数の差が、まだスキャンしていない組の数になります。表彰式の前に、この差が0になったかを見ます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| スコアカード | プレーヤーの名前、ホールごとの打数、OUT・IN・合計(パット数の欄がある書式も) | コンペ番号のフォルダ(スキャンした画像) |
| 読み取り結果 | 表の行とセル、名前の欄、読み取りの信頼度 | Google Document AI |
| カードの書式の対応表 | 表の行と列が、どのプレーヤーの欄・どのホールか | 自社で用意する一覧 |
| 組み合わせ表 | 組の番号、プレーヤーの名前、スタートのコース | コンペの組み合わせ表 |
| コースの情報 | ホールごとのパー | コースの情報の表 |
質を決めるのは、カードの書式の対応表です。 「表の2行目の3列目は、1人目の3番ホール」という対応が決まっていれば、読み取った数字を人×ホールに並べ直すのは機械的な作業になります。 パット数の欄がある書式は、打数の行とパット数の行を分けて対応づけます。
組の番号は、カードに印刷しておきます。 組み合わせ表から、組の番号とプレーヤーの名前をカードに印刷して配る運用にすると、名前の照合がほとんど要らなくなります。 当日の入れ替えで手書きになった名前だけが、照合の対象に残ります。
データの取得方法を決める
読み取りは、スクリプトから Form Parser のプロセッサを呼ぶだけです。画像を送ると、document の形で結果が返ります。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 表の行とセル | pages[].tables[] の headerRows と bodyRows、各セルの layout | ホールごとの打数と、OUT・IN・合計 |
| 名前の欄 | pages[].formFields[] の fieldName/fieldValue、または表の名前の列 | プレーヤーの名前 |
| 文字 | textAnchor.textSegments の startIndex/endIndex で document.text を切り出す | 各セルの数字の文字列 |
| 信頼度 | 各セルの layout の confidence | 「読み違いかもしれない」の判定 |
セルの文字は、セルの中に直接入っていません。 textAnchor.textSegments が文書全体の文字列 document.text の範囲を指しているので、スクリプトで切り出して数字に直します。 1つのセルの値が複数の区間に分かれることがあるので、順につなぎます。
1枚のカードは1ページで、同期の処理(15ページまで)で十分に収まります。 組ごとに1枚ずつ送るので、ページ数の上限を気にする必要はありません。
AIへ渡す前に整形する
- 形式の確認 … PDF、JPEG、PNG、TIFF などであることを確かめます
- 解像度の確認 … 公式のページでは、スキャンは最低200dpi、300dpi以上で最もよい結果になるとされています。手書きの小さな数字を読むので、300dpiにそろえます
- 向きの確認 … カードは横長で、裏返しや上下逆でスキャンされることがあります。印刷された見出しの位置で向きを確かめ、直します
- 書式の確認 … 印刷された見出しの文字で、どの書式のカードかを確かめ、対応表を選びます
- 組の番号の確認 … 印刷された組の番号を読み、組み合わせ表にあるかを確かめます。同じ組のカードが2枚あれば、後のものを差し替えとして扱います
- カードの裏の除外 … ローカルルールなどが印刷された裏面のページは、読み取りに回しません
3番目は、地味ですが効きます。 回収したカードの向きはそろっていません。上下逆のまま読むと、表の行と列の対応がすべてずれます。 複合機に向きをそろえる設定があれば、それも使います。
AIに処理させる
OCRの後は、ほとんどがスクリプトの仕事です。 打数を人×ホールに並べ、ホールの合計を計算し、記入された合計と比べるのは、規則で書けます。
| 確かめること | 判定の仕方 | 判断できないときの扱い |
|---|---|---|
| ホールの打数が数字か | 1文字か2文字の整数として解釈できるか | 解釈できなければ unreadable |
| 打数が範囲内か | 1以上で、ゴルフ場が決めた上限以下か | 範囲外は suspect |
| 相対の書き方でないか | 同じ人の打数がほとんど0〜2で、パーより明らかに少ないか | パーに対する差で書かれた疑いとして人へ |
| OUT の照合 | 1〜9番の合計と、記入された OUT | 合わなければ mismatch |
| IN の照合 | 10〜18番の合計と、記入された IN | 合わなければ mismatch |
| 合計の照合 | OUT と IN の合計と、記入された合計 | 合わなければ mismatch |
3行目は、紙のスコアカードならではの落とし穴です。 プレーヤーによっては、打数ではなくパーに対する差(「0」「+1」「−1」)を書きます。そのまま集計すると、その人だけ極端に少ない打数になり、優勝してしまいます。
パット数の欄がある書式では、打数とパット数の行の取り違えも見ます。 同じ人の2行のうち、打数の行の値がパット数の行の値より小さいホールがあれば、行を取り違えて書いたか、読み取りの行がずれた疑いがあります。どちらの行が打数かは、書式の対応表で決まっているので、規則で見分けられます。 パット数そのものは順位に使わないコンペが多く、集計表には打数だけを書き込みます。
生成AIにさせるのは、名前の対応の候補を出すことだけです。 手書きの名前が組み合わせ表と一致しないときに、同じ組の4人の名前と見比べて、どれに当たるかの候補を返させます。
| させないこと | 理由 |
|---|---|
| 打数の読み直しや補完 | 打数はOCRとスクリプトで扱う。AIが「それらしい数字」を入れると、誤りが消える |
| 合計の食い違いの原因の判断 | プレーヤーの誤りか読み違いかは、紙を見て人が決める |
| ハンディキャップと順位の計算 | 集計表の式で行う。方式はコンペごとに幹事が決める |
| 組の外のプレーヤーとの照合 | 同じ組の4人の中からだけ候補を出す |
指示内容を固定する
あなたはゴルフ場のコンペ担当で、スコアカードに手書きされた
プレーヤーの名前を、組み合わせ表の名前と対応づける補助をします。
以下の情報だけを使い、推測で補わないでください。
【やること】
カードの各欄に書かれた名前が、同じ組の組み合わせ表の4人のうち
誰に当たるかの候補を答えてください。
【厳守事項】
- 候補は、下に示した同じ組の名前の中からだけ選んでください。
それ以外の名前を作らないでください。
- 名字だけ、名前だけ、愛称、ひらがな書きなどで一致が確定できない場合は、
confidence を low にし、理由を reason に短く書いてください。
- 同じ名字の人が組に2人以上いて区別できない場合は、
match を null にしてください。
- 2つの欄が同じ人に当たるという答えはしないでください。
その場合は両方を match null にしてください。
- 打数、合計、順位については何も答えないでください。
- written には、カードに書かれた文字列をそのまま写してください。
【組の番号】{group_no}
【組み合わせ表の4人】{pairing_names}
【カードの名前の欄(欄の番号と読み取った文字列、信頼度)】
{written_names}
「同じ組の名前の中からだけ選ぶ」を最初に書くのは、候補を広げさせないためです。 コンペの参加者全員の名簿を渡すと、別の組の似た名前を選ぶことがあります。組の番号で範囲を4人に絞れば、照合はほぼ取り違えようがありません。
打数について答えさせない一文も入れておきます。 名前の欄と一緒に表の内容が見えると、生成AIは合計の誤りを指摘したり、直した値を書いたりしようとします。打数はこの指示の外で扱います。
出力形式を固定する
名前の対応は、構造化出力(JSON スキーマ)で受け取ります。 Claude API では output_config.format に json_schema の形でスキーマを渡します。オブジェクトには additionalProperties: false が必要です。
{
"group_no": "",
"names": [
{ "slot": 1, "written": "", "match": "", "confidence": "high | low",
"reason": "" }
]
}
打数の側は、スクリプトが次の形にそろえ、集計表に書き込む元にします。
{
"competition_no": "",
"group_no": "",
"players": [
{
"slot": 1,
"player": "",
"holes": [ { "hole": 1, "strokes": 5, "confidence": 0.0,
"status": "ok | unreadable | suspect" } ],
"out_written": 0, "out_sum": 0,
"in_written": 0, "in_sum": 0,
"total_written": 0, "total_sum": 0,
"check": "ok | mismatch | relative_suspect | needs_review"
}
]
}
1つ目の理由は、ホールの打数と記入された合計を両方残せることです。 out_sum は読み取った打数から計算した値、out_written はプレーヤーが書いた値です。両方が残っていれば、どちらが誤っているかを紙で確かめるときに迷いません。
2つ目は、check の値をスクリプトの規則で決められることです。
check | 条件 |
|---|---|
ok | すべてのホールが ok で、OUT・IN・合計がすべて一致 |
mismatch | すべてのホールが ok なのに、記入された合計と計算した合計が違う |
relative_suspect | 打数の多くが0〜2で、パーに対する差で書かれた疑いがある |
needs_review | unreadable か suspect のホールが1つでもある |
2行目と4行目の区別が、この構成でいちばん大事なところです。 mismatch は、読み取りに不安が無いのに合わないもので、プレーヤーの計算違いの可能性が高く、幹事に伝える候補です。 needs_review は読み取りに不安があるもので、紙を見ればフロントで解決します。 不安のあるセルがあるうちは mismatch にしない、という順番を規則で守ります。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| コンペ番号のフォルダ | Google Apps Script の定期実行 | 新しいファイルを検知する |
| Google Document AI | API呼び出し(同期の処理) | 表のセル・名前の欄・信頼度を返す |
| カードの書式の対応表、組み合わせ表、コースの情報 | スプレッドシートの読み取り | 人×ホールの対応、名前、パー |
| Claude API | API呼び出し(名前が一致しないときだけ) | 名前の対応の候補 |
| コンペの集計表 | 書き込み | プレーヤーの行に18ホールの打数 |
| 確認の一覧 | 書き込み | check が ok 以外のカード |
集計表に書き込むのは、打数だけです。 ハンディキャップの方式と順位の式には触れません。ok 以外のカードの打数も書き込みますが、行に印を付け、確認が済むまで順位表を印刷しないようにします。
幹事へは、この構成から何も送りません。 mismatch のカードを幹事に伝えるかどうかは、紙を見たコンペ担当が決めます。
人が確認する
needs_reviewのカードを先に見る … 信頼度の低いセルを紙と見比べ、集計表の値を直します。多くは「1」と「7」のような字の癖ですrelative_suspectのカードを確かめる … パーに対する差で書かれていれば、打数に直して入力しますmismatchのカードを確かめる … 紙のホールの打数を足し直し、読み取りが正しくプレーヤーの合計が違うと分かったものだけを幹事に伝えます- 名前の対応の
lowとnullを確かめる … 組の4人に聞くか、幹事に確かめます - 順位表を印刷する前に、上位の数人のカードを紙と見比べる … 表彰に関わる行は、
okでも念のため確かめます
5番目は、時間を減らす目的に逆らって見えるかもしれません。 しかし、上位の数人の打数の誤りは、表彰の順番そのものを変えます。ここだけは全部の数字を紙で確かめても、数分で終わります。
目標は、300枚をならして1枚2分です。 ok のカードは集計表の行を流し見て数十秒、needs_review と mismatch のカードは紙と見比べて数分かかります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 結合したセルのある古い書式のカード | 表の行がずれる。全員を needs_review にして人へ。 書式を作り直す |
| 解像度が低い・向きが違う | スキャンし直す。向きは前処理で直す |
| 組の番号が読めない、または組み合わせ表に無い | 処理せずコンペ担当へ。組を推定させない |
| 同じ組のカードが2枚ある | 後のものを差し替えとし、前の結果と差のあるセルを一覧に出す |
| 途中でやめたプレーヤー(打数の無いホールが続く) | 空のホールを unreadable にせず「未記入」として人へ。扱いは幹事が決める |
| 打数を消して書き直した跡がある | 信頼度が下がるので needs_review になる。紙で確かめる |
| 18ホールを回らないコンペ(9ホールなど) | コンペの設定で対象のホールを決め、残りを照合から外す |
| OCRや生成AIが応答しない | フォルダに残して再実行。表彰式に間に合わなければ従来どおり手で打ち込む |
最後の行は、運用の取り決めとして先に書いておきます。 表彰式は待ってくれません。読み取りが止まった日に手で打ち込めるよう、集計表は今の形のまま使える状態で残します。
記録を残す
- 元のスキャンの画像と、保存した日時、コンペ番号、組の番号
- OCRが返した JSON の全文(
tables、formFields、document.text、信頼度) - スクリプトがそろえた打数と
checkの結果、そのとき使った書式の対応表の版 - 名前の対応の出力と、担当者が決めた対応
- 担当者が直したセルと、直す前の値
- 幹事に伝えた
mismatchと、幹事の判断
5つ目の「直したセル」が、書式の改善の材料になります。 同じホールの欄で読み違いが多いなら、欄が狭いか、印刷の線が数字に重なっています。読み違えやすい字の組み合わせが分かれば、確認のときにどこを見ればよいかも分かります。
画像と結果の保存期間は、コンペの集計表と同じ扱いにします。 幹事から後日問い合わせがあったときに、元のカードと読み取りの結果を見比べられる期間を決めておきます。
04実装レベルの3段階
最小構成では、表彰式に間に合いません。 1枚ずつ画面で読み取って貼るので、手で打ち込むのと大差がありません。確かめるための段階です。 半自動化で、1枚6分が2分程度になります。 打ち込みがなくなり、合計の照合が自動になって、人が見るのは一覧のカードだけになるからです。本記事の想定はこの段階です。 本格構成で減るのは名前の照合とスキャン漏れの確認で、紙と見比べる時間は残ります。 段階を飛ばさないでください。 半自動化を1か月回すと、読み違いの多い欄と、相対の書き方をするプレーヤーの多さが分かります。書式とカードの記入の案内を直してから本格構成に進むほうが、当日の確認が減ります。
05工数削減シミュレーション
導入後 300件 × 2分 ÷ 60 = 10 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 会社や団体のコンペを月に数十件受け入れ、表彰式の前にフロントやコンペ担当がスコアカードの打数を集計表に打ち込んで順位を出しているゴルフ場。スコアカードの書式を自社で決めて印刷している場合。表彰式までの短い時間に入力が集中し、合計の書き誤りや入力の打ち間違いで順位を出し直したことがある場合。
- プレーヤーがカートのナビやスマートフォンのアプリで打数を入力しており、紙のスコアカードを集計に使っていない場合。コンペの受け入れが月に数件で、手入力でも表彰式に間に合っている場合。なお、スコアの訂正や失格などの競技上の判断はコンペの幹事が行うもので、この構成では代替できません。
07最小構成で試す方法
- 過去のコンペから30枚のカードを選ぶ(合計の書き誤りがあったカードと、字の癖の強いカードを入れる)
- Google Cloud のコンソールで Form Parser のプロセッサを作り、画面から1枚ずつ読み取らせる
- 表の行とセルが、カードの欄どおりに返るかを見る。結合セルのある部分で行や列がずれないかを確かめる
- 読み取った打数をスプレッドシートに貼り、ホールの合計と記入された合計を式で比べる
- 当時の集計表と突き合わせる
30枚は必ずやってください。 スクリプトを組む前に、「手書きの数字が表のセルとして読めるか」と「今の書式で表の形が崩れないか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 数字がほぼ読め、当時の合計の書き誤りが見つかった | 対応表とスクリプトに進む |
| 「1」と「7」などの読み違いが少しある | 想定どおり。信頼度で拾えるかを見る |
| 表の行や列がずれる | 書式が先。 結合セルを無くした書式を試し刷りして同じ手順を繰り返す |
3行目は、今の書式では起きる可能性が高い結果です。 失敗ではなく、書式を作り直す理由が確かめられたということです。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 結合したセルで表の行や列がずれる | 単純な表だけが対象。 結合セルの無い書式にする |
mismatch と needs_review が混ざる | 不安のあるセルがあるうちは mismatch にしない |
| パーに対する差で書かれた打数がそのまま集計される | 打数の多くが0〜2なら relative_suspect として人へ |
| 「1」と「7」などの読み違い | 信頼度の低いセルを一覧に出す。上位は全セルを確かめる |
| 上下逆のスキャンで全部ずれる | 印刷の見出しで向きを確かめて直す |
| 最終組の後にまとめてスキャンする | 上がった組から順にスキャンする運用にする |
| 生成AIが打数や合計に口を出す | 名前の欄だけを渡し、打数について答えさせない |
| 別の組の似た名前と取り違える | 候補を同じ組の4人に絞る |
| 途中でやめたプレーヤーの空欄が読み取り不明になる | 「未記入」として分け、扱いは幹事が決める |
| 読み取りが止まって表彰式に間に合わない | 集計表を手で打ち込める形のまま残す |
上の3行が、この構成の失敗のほとんどです。 1つ目は製品の仕様、2つ目は判定の順番、3つ目は紙のスコアカードの書き方から来るもので、どれも「集計表に入った数字が正しく見えてしまう」ことにつながります。
下から2行目は、名前の照合の範囲の話です。 範囲を組の4人に絞るだけで、生成AIの誤りの余地はほとんどなくなります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: プレーヤーの名前、所属する会社や団体、ホールごとの打数、コンペの順位です。住所や連絡先は扱いません。
- 処理される場所を確かめる … Form Parser の対応リージョンは、プロセッサの一覧の確認時点で
asia-south1、asia-southeast1、australia-southeast1、eu、europe-west2、europe-west3、northamerica-northeast1、usで、日本のリージョンはありません。 カードの画像が国外で処理されることを、社内で了承しておきます - 生成AIへ渡すのは名前だけにする … 名前の対応の候補を出すのに、打数や会社名は要りません。同じ組の4人の名前と、カードに書かれた名前だけを渡します
- 18歳未満のプレーヤーを想定する … ジュニアの参加があるコンペもあります。18歳未満が関わるサービスでの利用を規約で禁じている生成AIのサービスは避け、使う生成AIについても利用規約の年齢の条件を契約前に確かめてください
- 順位を自動で確定しない … 順位表は、担当者が上位のカードを紙と見比べてから印刷します。表彰の順番の誤りは、その場で取り返しがつきません
- 競技上の判断を代替させない … 計算違いの扱い、途中でやめたプレーヤーの扱い、失格などは、コンペの幹事が決めることです。この構成は事実を一覧にするだけです
- 画像の保存期間を決める … 問い合わせに答えられる期間を過ぎたら、カードの画像と読み取りの結果を消します
誤りが起きた場合のリスクは、打数の読み違いがそのまま順位に入ることと、読み違いをプレーヤーの計算違いとして幹事に伝えることの2つです。 前者は needs_review を流し見ると起き、後者は needs_review を mismatch に混ぜると起きます。どちらも、セルの信頼度と判定の順番で守ります。
10まず何から始めるか
1週目:30枚で試す
過去のコンペのカードから30枚を選び、Form Parser で読み取ります。表の行と列がカードの欄どおりに返るか、手書きの数字がどこまで読めるかを見ます。 結合セルの部分でずれが出たら、書式の作り直しを決めます。
2週目:書式を作り直す
結合セルの無いスコアカードを試し刷りし、同じ30枚分の打数を書き写したカードで読み取りを繰り返します。組の番号とプレーヤーの名前を印刷する欄を足し、「打数を書いてください」という案内を入れます。
3週目:対応表と照合を作る
新しい書式について、表の何行目・何列目が誰の何番ホールかの対応表を作ります。Google Apps Script で、読み取った数字を人×ホールに並べ、OUT・IN・合計を照合するところまで作ります。
4週目:フォルダから集計表までをつなぐ
フォルダを見て、読み取りと照合を流し、集計表に書き込んで確認の一覧を出すところまで作ります。この時点では手の打ち込みも並行して行い、両方の結果を比べます。
2か月目: 上がった組から順にスキャンする運用を始め、needs_review と mismatch の件数をコンペごとに数えます。3か月目以降: 名前の対応の候補を足し、手の打ち込みをやめます。1枚6分が何分になったかを実測し、表彰式の開始が遅れなくなった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
Form Parser がキーと値のペア、チェックボックス、表を取り出すこと。対応言語の表で日本語(ja)に手書きの対応が付いていること。推奨の版が pretrained-form-parser-v2.0-2022-11-10(安定版・GA)であること。同期の処理が15ページまでであること。対応リージョンが asia-south1、asia-southeast1、australia-southeast1、eu、europe-west2、europe-west3、northamerica-northeast1、us であること | Google Cloud: Processor list | 2026-10-14 |
| 表は行や列をまたぐセルの無い単純な表だけが対象であること | Google Cloud: Form Parser | 2026-10-14 |
表が pages[].tables[] の headerRows/bodyRows とセルで返り、rowSpan/colSpan が常に1であること。記入欄が formFields の fieldName/fieldValue で返ること。文字が textAnchor.textSegments の startIndex/endIndex で document.text を指すこと。layout に confidence が付くこと | Google Cloud: Handle the processing response | 2026-10-14 |
| 対応するファイル形式が PDF、TIFF、JPEG、PNG などであること。スキャンは最低200dpi、300dpi以上で最もよい結果になるとされること | Google Cloud: Supported files | 2026-10-14 |
Claude API の構造化出力が output_config.format に json_schema を渡す形であること。オブジェクトに additionalProperties: false が必要なこと | Claude Docs: Structured outputs | 2026-10-14 |
ハンディキャップの方式、計算違いや途中でやめたプレーヤーの扱いは、各コンペの幹事の取り決めに従ってください。 本記事は製品の公開仕様で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1521)についてのご相談はこちらから。
