漁協が水揚げのときに撮った魚箱の写真から、Gemini で魚種と箱数の候補を数えて、水揚げの台帳の下書きにする
荷さばき所で船ごとに並べた魚箱を真上から撮り、その写真から箱ごとの魚種の候補と、魚種ごとの箱数の候補を数えます。漁業者の申告と食い違う箇所に印を付け、セリの前の水揚げの台帳の下書きにします。
- 生成AI
- ChatGPT/Claude/Gemini
- 連携・自動化
- Google Apps Script/Python
- 対象業界
- その他/商社
- 対象部門
- 生産
- 対象業務
- データ入力・転記/台帳・マスタ管理
- 主な課題
- 人手が足りない/入力作業が多い/確認ミスが多い
- AIで行う処理
- 画像認識
- 主な効果
- 入力漏れ削減/対応スピード向上/工数削減
- 導入難易度
- ★★★☆☆
- 実装レベル
- 本格構成
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 船が岸壁に着き、漁業者が魚箱を荷さばき所に降ろして、魚種ごとに並べる
- 漁業者が、魚種と箱数を職員に口頭で伝える
- 職員が魚箱の前で数え、魚種と箱数を野帳に書き取る
- 必要な魚種は、はかりで計量して重量を野帳に書き足す
- 職員が事務所に戻り、野帳を見てスプレッドシートの台帳に船ごとに入力する
- 台帳を印刷し、セリの担当と仲買に配る
- セリの後、買受人と値段を台帳に書き足し、請求と組合員への支払の元にする
- 人漁業者が魚箱を魚種ごとに1段で並べ、船の札を列の端に置く
- 人職員がタブレットで、列を真上から撮る。漁業者の申告(魚種と箱数)をタブレットの入力の画面で選ぶ
- 自動写真が共有のドライブの「受付」のフォルダに上がる
- 自動数分ごとに動くスクリプトが新しい写真を見つけ、魚種の一覧と一緒に Gemini API に渡す
- 自動箱ごとの魚種の候補と枠、魚種ごとの箱数の候補、見えない箱の数を受け取る
- 自動スクリプトが申告と照らし、食い違う魚種と見分けにくい魚種に印を付けて、台帳の「写真の候補」の欄に書く
- 人職員が、印の付いた船だけ魚箱の前で確かめ、台帳の確定の欄に移す
- 人計量の要る魚種は、これまでどおりはかりで計って重量を入力する
- 人台帳を印刷してセリに回す
各工程の詳しい説明を読む
- 船が岸壁に着き、漁業者が魚箱を荷さばき所に降ろして、魚種ごとに並べる
- 漁業者が、魚種と箱数を職員に口頭で伝える
- 職員が魚箱の前で数え、魚種と箱数を野帳に書き取る
- 必要な魚種は、はかりで計量して重量を野帳に書き足す
- 職員が事務所に戻り、野帳を見てスプレッドシートの台帳に船ごとに入力する
- 台帳を印刷し、セリの担当と仲買に配る
- セリの後、買受人と値段を台帳に書き足し、請求と組合員への支払の元にする
(a)数えて書き取るのに手が足りない。 30隻がほぼ同じ時間帯に戻ります。職員が船の間を走り回り、数えている間に次の船の荷が降りてきます。
(b)書き取りと入力が二度手間になる。 野帳に書いたものを、事務所でもう一度スプレッドシートに打ち直します。打ち直しのときに行を飛ばす、箱数を隣の魚種の欄に入れる、といった誤りが起きます。
(c)見分けにくい魚種を書き違える。 漁業者の口頭の申告をそのまま書くと、似た魚種が混ざっていても気付かないことがあります。 後で仲買から「これはマルアジだ」と言われ、台帳を直すことになります。
(d)混ざって置かれた箱を数え漏らす。 魚種ごとに並べる決まりでも、急ぐ日には別の魚種の箱が列に入ります。列の数だけを数えると、1箱だけ混ざった魚種が台帳から落ちます。
- 【人】 漁業者が魚箱を魚種ごとに1段で並べ、船の札を列の端に置く
- 【人】 職員がタブレットで、列を真上から撮る。漁業者の申告(魚種と箱数)をタブレットの入力の画面で選ぶ
- 【自動】 写真が共有のドライブの「受付」のフォルダに上がる
- 【自動】 数分ごとに動くスクリプトが新しい写真を見つけ、魚種の一覧と一緒に Gemini API に渡す
- 【自動】 箱ごとの魚種の候補と枠、魚種ごとの箱数の候補、見えない箱の数を受け取る
- 【自動】 スクリプトが申告と照らし、食い違う魚種と見分けにくい魚種に印を付けて、台帳の「写真の候補」の欄に書く
- 【人】 職員が、印の付いた船だけ魚箱の前で確かめ、台帳の確定の欄に移す
- 【人】 計量の要る魚種は、これまでどおりはかりで計って重量を入力する
- 【人】 台帳を印刷してセリに回す
7番目が、この設計の分かれ目です。職員は全部の船を数え直しません。 申告と写真の候補が合い、見分けにくい魚種の印も無い船は、画面で写真を見て確定の欄に移すだけにします。印の付いた船にだけ、魚箱の前で時間を使います。
8番目の計量は、この構成の外に置きます。 重量は取引と漁獲量の報告の元になる数字なので、写真から推した値を入れる欄を、台帳に作りません。
02今回想定するシステム構成
荷さばき所(漁業者が魚箱を魚種ごとに1段で並べ、船の札を置く) ▼ 職員がタブレットで真上から撮る。申告を選ぶ 共有のドライブ「受付」のフォルダ(ファイル名に船の番号と時刻) ▼【トリガー】数分ごとに動く時間主導型トリガー Google Apps Script ├── 新しい写真を探し、魚種の一覧と申告を引く ▼ Gemini API(画像の理解・構造化出力)── 写真1枚ごと │ 箱ごとの枠と魚種の候補(魚種の一覧のコード) │ 見分けにくさの区分、見えない箱の数 ▼ Google Apps Script ── 魚種ごとに箱数を足し、申告と照らす ▼ 水揚げの台帳(スプレッドシート)の「写真の候補」の欄と印 ▼ 【人】職員が印の付いた船を確かめる → 確定の欄へ → 計量 → セリ
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 処理 | Gemini API(魚箱の写真から箱ごとの魚種の候補と箱数の候補を返す) | Claude API、OpenAI API |
| 連携 | Google Apps Script(写真の検知、呼び出し、申告との照合、台帳への書き込み) | Python |
| 保管 | Google ドライブ(受付と処理済みのフォルダ) | - |
| 台帳 | Google スプレッドシート(水揚げの台帳、魚種の一覧、船の一覧) | - |
新しく足すのは、スクリプトと Gemini API の契約、タブレットでの撮り方と申告の入力の画面です。 台帳と魚種の一覧はすでにあるものです。セリと計量のやり方は変えません。
写真を見る土台は、Gemini API の画像の理解です。 公式の案内では、対応する形式は PNG、JPEG、WEBP、HEIC、HEIF で、画像を直接入れる場合はリクエスト全体が20MBまでです。物の位置を枠で返させる例があり、枠は [ymin, xmin, ymax, xmax] の順で0〜1000に正規化されます。箱ごとに枠を返させれば、箱数は枠の数を数えるだけで出ます。
出力は構造化出力で受けます。 /v1beta/interactions に送り、response_format で mime_type を application/json にし、schema にスキーマを入れます。enum で値を決まった文字列に絞れ、魚種の候補を魚種の一覧のコードに限れます。 公式の案内は、値はアプリ側で検証するよう書いています。
つなぎは Google Apps Script です。 時間主導型のトリガーは、1分ごとから月1回までの間隔で動かせます。ただし1回の実行は6分まで、トリガーの合計の実行時間は Google Workspace のアカウントで1日6時間までです。1回の実行で写真を数枚ずつ処理し、残りは次の回に回します。
03どうやって実装するのか
処理の起点を決める
時間主導型のトリガーで、数分ごとに「受付」のフォルダを見に行きます。 Google Apps Script のインストール型のトリガーには、スプレッドシートの編集やフォームの送信などの種類がありますが、フォルダにファイルが増えたことを起点にする種類はありません。 数分ごとに見に行き、新しい写真があれば処理します。
間隔は2〜3分にします。 公式の案内では、時間主導型のトリガーは1分ごとまで縮められますが、実行の時刻は少しずれることがあるとされています。水揚げの時間帯だけ短い間隔で動かし、昼から翌朝までは止めます。トリガーの合計の実行時間の上限に余裕を残すためです。
処理が終わった写真は「処理済み」のフォルダへ移します。 移すのは、台帳に書き込めたときだけにします。「受付」に残っている写真の数が、そのまま未処理の数になります。 職員は画面でその数を見て、セリに間に合うかを判断します。
撮り直しの写真は、同じ船の番号で上げ直します。 スクリプトは、同じ船の番号の後から上がった写真を新しいものとして扱い、台帳の「写真の候補」の欄を書き直します。 職員が確定の欄に移した後なら、書き直さずに「撮り直しあり」の印だけを付けます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 魚箱の写真 | 船ごとの列を真上から撮った写真。ファイル名に船の番号と時刻 | 共有のドライブ「受付」 |
| 漁業者の申告 | 魚種と箱数。職員がタブレットで選ぶ | 申告の入力の画面(スプレッドシートの別のシート) |
| 魚種の一覧 | 魚種のコード、名前、見た目の特徴の短い説明、見分けにくい組の印、その季節に揚がるか | 魚種の一覧のシート |
| 船の一覧 | 船の番号、船の名前、漁法 | 船の一覧のシート |
| 箱の種類 | 使う魚箱の色と大きさの種類 | スクリプトに持たせる |
質を決めるのは、魚種の一覧の「その季節に揚がるか」と「見分けにくい組」の欄です。 季節に揚がらない魚種を候補から外しておくと、似た魚種の取り違えがその分だけ減ります。 見分けにくい組の印は、AIの候補がその組のどちらかになったときに、職員に回す印として使います。
漁法も渡します。 定置網と底びき網では揚がる魚種が違います。漁法をヒントにすると、底びき網の船の写真で回遊魚の候補が出にくくなります。 ただし、ヒントと違う魚種が写っていれば、それを候補として返させます。
データの取得方法を決める
写真は、ドライブのフォルダから新しい順に取ります。 スクリプトは「受付」のフォルダのファイルを一覧にし、まだ処理していないものを数枚ずつ取ります。1回の実行は6分までなので、1回に処理する写真の枚数を決めておき、時間が足りなければ次の回に回します。
Gemini API へは、写真1枚ごとに1回呼びます。 1隻の水揚げが長い列になって2〜3枚に分けて撮った場合も、写真ごとに呼んでから、スクリプトで船ごとに足し合わせます。 写真の重なりで同じ箱を2回数えないよう、撮り方の側で列の切れ目に船の札か目印を置きます。
申告と魚種の一覧は、スプレッドシートから読みます。 魚種の一覧は、その季節に揚がる魚種だけに絞ってから指示の文に入れます。60種を全部入れるより、季節の20〜30種に絞るほうが、候補の取り違えが減ります。
有料の利用枠で使い、store を false にします。 Gemini API の規約では、有料のサービスではプロンプトと応答が製品の改善に使われないとされています。Interactions API は既定でやり取りを保存し(有料の枠で55日)、保存しないときは store=false を付けると案内されています。
AIへ渡す前に整形する
- 形式と向き … タブレットの写真が HEIC なら、そのまま対応形式です。向きの情報で回転しているだけの写真は、画素を回転させます。 向きが合っていないと、枠がずれます
- 縮小 … 長い辺を2,000ピクセル程度に縮めます。箱の中の魚の模様が見える大きさは残します
- 船の札の確認 … ファイル名の船の番号と、写真に写った船の札が合っているかは、職員が撮るときに確かめます。スクリプトは、ファイル名に船の番号が無い写真を処理しません
- 魚種の一覧の絞り込み … その季節に揚がる魚種と、その船の漁法で揚がる魚種に絞ります
- 申告の付け足し … 申告は指示の文に入れません。スクリプトの側だけが持ちます
- 大きさの確認 … 写真と指示の文を合わせて20MBを超えないかを見ます
5番目を軽く見ないでください。 申告を指示の文に入れると、AIの数が申告に寄ります。 「アジ12箱」と書いてあれば、11箱しか写っていなくても12と返しやすくなります。申告と照らすのはスクリプトの仕事で、AIには写真だけを数えさせます。
AIに処理させる
させるのは、写真の中の魚箱を1つずつ枠で返し、箱ごとに魚種の候補を付け、隠れて見えない箱の数を返すことだけです。 魚種の候補は、渡した魚種の一覧のコードから選ばせます。
| 返すもの | 中身 | 判断できないときの扱い |
|---|---|---|
| 箱の枠 | 写真に写った魚箱ごとの枠 | 箱の端が写真の外にはみ出していれば partial を付ける |
| 魚種の候補 | 箱ごとに、魚種の一覧のコードを1つ | 見分けがつかなければ unknown |
| 見分けの確かさ | clear / similar_species / covered | 氷やシートで魚が見えなければ covered |
| 見えない箱 | 積み重なりや影で、数えられない箱がありそうな範囲 | 範囲がはっきりしなければ写真ごと「見えない範囲あり」 |
| 一覧に無い魚 | 一覧のどれにも当たらない魚が入った箱 | not_in_list として枠だけを返す |
右端の列の考え方は、迷ったら職員に見せる側に倒すことです。 魚種が分からない箱は unknown、氷で見えない箱は covered として返させ、数えた箱から落とさないようにします。 箱数の候補は、unknown と covered も含めた枠の数で出します。
| させないこと | 理由 |
|---|---|
| 重量の推定 | 取引と漁獲量の報告の元は、はかりで計った重量 |
| 規格(大きさの区分)の決定 | 選別のしかたは漁協と漁業者の決まり。写真の見た目で決めない |
| 鮮度や品質の評価 | 値段に直結する。セリと仲買の目で決まる |
| 申告が正しいかの判定 | 照合はスクリプト。正しいかは職員が魚箱の前で確かめる |
| 漁獲量の報告の数値 | 報告は計量の値と職員の確認から作る |
| 写っている人についての記述 | 台帳に要らない |
2行目がいちばん起きやすい失敗です。 箱の中の魚の大きさが写真で見えると、AIは「中サイズ」「小型」と書きたがります。規格は値段の区分なので、写真の見た目の大きさで台帳に入ると、セリの値付けが崩れます。 返すのは魚種の候補と箱の数までにします。
特に厳格な管理の対象になる魚種も、この構成の外に置きます。 漁業法は、特別管理特定水産資源を採捕した者に、個体の数と漁獲量の報告に加えて、個体ごとの重量などの記録の作成と保存を求めています。こうした魚種は、写真の候補を作らず、これまでどおり1尾ずつ計量して記録します。
指示内容を固定する
あなたは漁協の産地市場で、水揚げの台帳づくりを手伝う係です。
写真は、1隻の船の魚箱を荷さばき所に並べて、真上から撮ったものです。
【この船の漁法】{定置網/小型底びき網/刺網}(ヒントです。違う魚種が写っていれば、それを返してください)
【魚種の一覧】{コード:名前:見た目の特徴}(この中から選んでください)
【見分けにくい組】{マアジとマルアジ、ブリとヒラマサ ...}
【やること】
1. 写真に写っている魚箱を1つずつ探し、枠を [ymin, xmin, ymax, xmax] の順で、
0〜1000 に正規化して返す。写真の端で切れている箱には partial を付ける。
2. 箱ごとに、中の魚の魚種を魚種の一覧のコードから1つ選ぶ。
3. 箱ごとに、clear(見分けられる)/similar_species(見分けにくい組の
どちらか迷う)/covered(氷やシートで魚が見えない)を付ける。
4. 積み重なりや影で数えられない箱がありそうな範囲を返す。
【厳守事項】
- 魚種が分からない箱は unknown にして、箱の枠は必ず返してください。
分からない箱を数から外さないでください。
- 魚種の一覧に無い魚が入った箱は not_in_list にしてください。
一覧の似た魚種に当てはめないでください。
- 重量、大きさの区分(規格)、鮮度、品質を書かないでください。
- 箱の数を合計しないでください。箱ごとの枠と候補だけを返してください。
- 写っている人については何も書かないでください。
「分からない箱を数から外さない」を書かないと、unknown の箱が消えます。 AIは確かな候補だけを返そうとして、氷で覆われた箱を飛ばすことがあります。箱数の候補が申告より少なく出て、職員が数え直すことになります。
「箱の数を合計しない」も同じ理由です。 合計を書かせると、枠の数と合計が合わないことがあります。数は枠を数えるスクリプトの側で出し、AIの書いた数字には頼りません。
出力形式を固定する
写真ごとに、次の形の JSON で受け取ります。 species、certainty は enum で決まった文字列に絞ります。species の enum には、その日の魚種の一覧のコードと unknown、not_in_list を入れます。
{
"photo_id": "B12_0612",
"boxes": [
{ "box_2d": [110, 40, 260, 180], "species": "AJI01", "certainty": "clear", "partial": false },
{ "box_2d": [110, 190, 260, 330], "species": "unknown", "certainty": "covered", "partial": false }
],
"hidden_areas": [
{ "area": "右下の角", "reason": "stacked | shadow | out_of_frame" }
]
}
1つ目の理由は、箱数をスクリプトが数えられることです。 スクリプトは boxes を species ごとに数え、船ごとに写真をまたいで足し合わせます。unknown と covered は「魚種未確認」の行として台帳に別に出します。
2つ目は、certainty で職員の確認の順番を決められることです。 similar_species と covered を含む船を確認の一覧の上に出し、clear だけで申告とも合う船は、写真を見て確定の欄に移すだけにします。
3つ目は、hidden_areas で撮り直しの頼み方が具体的になることです。 「右下の角が積み重なり」と出れば、職員はその角の箱を下ろして撮り直します。
スクリプトが台帳に書く行は、次の形です。
| 船 | 魚種 | 写真の候補(箱) | 申告(箱) | 印 | 確定(箱) |
|---|---|---|---|---|---|
| 12 | マアジ | 11 | 12 | 申告と違う | (職員が入れる) |
| 12 | マルアジ | 1 | 0 | 見分けにくい組 | (職員が入れる) |
| 12 | 魚種未確認 | 1 | - | 氷で見えない | (職員が入れる) |
response_format の schema には、次のように値を絞った形を入れます(抜粋)。
{
"type": "object",
"properties": {
"photo_id": { "type": "string" },
"boxes": { "type": "array", "items": { "type": "object",
"properties": {
"box_2d": { "type": "array", "items": { "type": "integer" }, "minItems": 4, "maxItems": 4 },
"species": { "type": "string", "enum": ["AJI01", "MARUAJI01", "SABA01", "unknown", "not_in_list"] },
"certainty": { "type": "string", "enum": ["clear", "similar_species", "covered"] },
"partial": { "type": "boolean" }
},
"required": ["box_2d", "species", "certainty", "partial"] } },
"hidden_areas": { "type": "array" }
},
"required": ["photo_id", "boxes", "hidden_areas"]
} システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 共有のドライブ | Google Apps Script のドライブの操作 | 受付の写真を読み、処理済みへ移す |
| 申告の入力の画面 | スプレッドシートの読み取り | 船ごとの魚種と箱数の申告 |
| 魚種の一覧・船の一覧 | スプレッドシートの読み取り | 季節と漁法で魚種を絞る |
| Gemini API | URL の取得(/v1beta/interactions、store=false) | 箱の枠、魚種の候補、見分けの確かさ、見えない範囲 |
| 水揚げの台帳 | スプレッドシートへの書き込み | 「写真の候補」の欄と印だけ。確定の欄には書かない |
台帳の確定の欄には、スクリプトから何も書きません。 確定の欄は職員だけが入れる欄にし、トリガーを作るアカウントを台帳の持ち主と分け、確定の欄の保護の編集者に入れないでおきます。 写真の候補が確定の欄に入る経路を、仕組みの側で断ちます。
セリの記録と請求の仕組みには、確定の欄だけがつながります。 写真の候補の欄は、確認の材料としてだけ使います。
人が確認する
- 印の付いた船を先に見る … 申告と違う、見分けにくい組、魚種未確認、見えない範囲ありの船です。魚箱の前に行き、その魚種の箱だけを数え直します
- 見分けにくい組は、魚を見て決める … 写真では決めず、箱の中の魚を見て決めます。迷えば漁業者に聞きます
- 印の無い船は、写真を見て確定の欄に移す … 写真の枠と候補を画面で流し見て、確定の欄に入れます
- 直した内容を記録する … 写真の候補から変えた魚種と箱数、その理由を残します
2番目を写真で済ませないのは、見分けにくい組が値段の違う魚種だからです。 取り違えると、仲買への請求と組合員への支払が両方ずれます。写真は見分けにくい箱の場所を教えるもので、決めるのは魚を見た職員です。
目標は、600件をならして1件2分です。 印の無い船は流し見て数十秒、印の付いた船は魚箱の前で数分かかります。印の付く船が半分を超えるなら、魚種の一覧の季節の絞り込みか、並べ方の決まりが崩れています。
例外に対処する
| 起きること | 対応 |
|---|---|
| 魚箱が積み重なって並べられない | hidden_areas に出る。1段に並べ直して撮るか、その船は野帳で数える |
| 氷やシートで魚が見えない | covered として数に入る。職員が魚箱の前で魚種を確かめる |
| 1隻の列が長く、写真が数枚に分かれる | 列の切れ目に目印を置いて撮り、スクリプトで足し合わせる |
| ファイル名に船の番号が無い | 処理せず、職員に戻す |
| 魚種の一覧に無い魚 | not_in_list の箱として台帳に出す。新しい魚種なら一覧に足す |
| 1回の実行が6分を超えそう | 処理する枚数を減らし、残りを次の回に回す |
JSON の値が enum に無い | その写真の結果を台帳に書かず、職員に回す |
| 大漁で写真が受付に溜まる | 職員が画面で未処理の数を見て、間に合わない船は野帳で数える |
上から3行目までが大半を占めます。 どれもAIの精度の問題ではなく、荷さばき所の並べ方と撮り方の問題です。 並べ方の決まりを漁業者と一緒に作るほうが、指示の文をいじるより効きます。
記録を残す
- 船の番号と日付ごとの写真と、Gemini API が返した JSON の全文
- そのとき指示に入れた魚種の一覧(季節と漁法で絞った後のもの)
- 申告、写真の候補、確定の値の3つを並べた記録
- 職員が写真の候補から変えた魚種と箱数と、その理由
- 撮り直しの有無と、
hidden_areasの出方
3つ目で3つの値を並べて残すのは、後から台帳の数字を説明できるようにするためです。 仲買や組合員から数を問われたとき、申告がいくつで、写真にはいくつ写っていて、職員がいくつと決めたかをたどれます。
4つ目が、魚種の一覧と並べ方の決まりを直す材料です。 同じ組の取り違えが続けば、一覧の見た目の特徴の説明を書き足します。
04実装レベルの3段階
最小構成では件数がさばけません。 1日30隻を手で渡す時間はありません。確かめるための段階です。 半自動化で、1件6分が4分程度になります。 数え上げは自動になりますが、申告との照合と、台帳への書き写しが残ります。本格構成で2分になり、この段階が本記事の想定です。 差が大きいのは、照合と台帳の欄への書き込みが、1隻ずつの手作業だからです。 段階を飛ばさないでください。 半自動化の一覧を1か月見ると、取り違えやすい魚種の組と、並べ方の崩れやすい漁法が分かります。そこを直してから本格構成に進むほうが、印の付く船が減ります。
05工数削減シミュレーション
導入後 600件 × 2分 ÷ 60 = 20 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 定置網や小型の底びき網、刺網の船が毎朝まとまって水揚げし、産地市場の職員が荷さばき所で魚箱を数えて水揚げの台帳に書き、セリや入札の前に台帳を仕上げている漁協。魚種が多く、職員が船ごとに魚種と箱数を手で書き取って、事務所でスプレッドシートに入力し直している場合。セリの開始の時刻に台帳が間に合わず、数え直しや書き写しの誤りが後から見つかる場合。
- 水揚げが1〜2魚種に限られ、箱数より重量の計量が中心の場合。大型の魚を1尾ずつ計量して記録する水揚げが中心の場合。荷さばき所で魚箱を平らに並べる場所が無く、積み重ねたまま取引する場合。なお、重量の確定、規格や鮮度の評価、漁獲量の報告に使う数値の確定、資源管理に関わる判断は、この構成では代替できません。
07最小構成で試す方法
- 先週の市の日から3日を選び、その日の船ごとの魚箱の写真を、職員が試しに撮っておく(うち1日は、魚種の多い日にする)
- その日の野帳と台帳を、正解として手元に置く
- Gemini API の有料の利用枠で、写真を1枚ずつ渡す
- 「写真の魚箱を1つずつ枠で示し、箱ごとに魚種の一覧から魚種を選んでください。分からない箱は unknown にして、数から外さないでください。重量や規格は書かないでください」と指示する
- 箱の枠を数え、台帳の箱数と魚種を突き合わせる
3日分は必ずやってください。 スクリプトを組む前に、「自社の荷さばき所の並べ方で、箱を数えられるのか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
箱数がほぼ合い、ずれた箱に unknown や covered が付いている | スクリプトと台帳の欄の作成に進む |
| 規格や鮮度を書いた | 指示の書き方で直る。構成は有効 |
| 積み重なりで多くの箱が数えられない | 並べ方の決まりが先。 AIの問題ではない |
3行目が出ることは珍しくありません。 失敗ではなく、職員が魚箱の前で数え直していた理由が1つ分かったということです。 1段で並べる場所が足りないなら、荷さばき所の区画の割り方を漁業者と相談します。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| AIの数が申告に寄る | 申告を指示に入れない。 照合はスクリプトで行う |
| 分からない箱が数から消える | unknown と covered で必ず枠を返させる |
| 写真から規格や重量を書く | 指示で禁じる。 台帳にその欄を作らない |
| 見分けにくい魚種を写真で決める | 印を付けて職員に回す。魚を見て決める |
| 季節外の魚種と取り違える | 魚種の一覧を季節と漁法で絞る |
| フォルダの変化で動くと思っていた | トリガーに無い。時間主導型で数分ごとに見に行く |
| 1回の実行が6分を超える | 1回の枚数を決め、残りを次の回に回す |
| 写真の候補が確定の欄に入る | トリガーのアカウントを、確定の欄の保護の編集者に入れない |
| 写真の重なりで同じ箱を2回数える | 列の切れ目に目印を置いて撮る |
上の2行が、この構成の失敗のほとんどです。 どちらも、写真に写っている数とは別の数が台帳に出る失敗です。写真だけを数えさせ、分からない箱も数に残すかどうかで、職員の数え直しが減るかが決まります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 船ごとの水揚げの魚種と箱数、組合員の船の番号です。写真には漁業者や職員の姿、船の名前が写り込むことがあります。水揚げの量は、組合員ごとの収入に直結する情報です。
- 有料の利用枠で、保存させない … 規約では、有料のサービスではプロンプトと応答が製品の改善に使われないとされています。Interactions API の
storeをfalseにします。禁止された使い方の検知などのために限られた期間記録されることは書かれています - 組合員の情報を渡さない … AIには写真と魚種の一覧だけを渡します。船の番号と組合員の名前の対応は、スプレッドシートの側だけに置きます
- 人を書かせない … 指示の文で、写っている人について書かせません
- 取引と報告の数字を AI に寄せない … 漁業法は、特定水産資源を採捕した者に漁獲量などの報告を求めています。報告と取引の数字は、計量の値と職員が確定した欄から作ります
- スクリプトのアカウントの権限を絞る … 書き込めるのは「写真の候補」の欄だけにします。インストール型のトリガーは作った人のアカウントで動くので、退職や異動のときの引き継ぎを決めておきます
誤りが起きた場合のリスクは、見分けにくい魚種を取り違えたまま請求と支払が進むことと、隠れた箱を数え漏らして組合員の水揚げが少なく記録されることの2つです。 前者は見分けにくい組を写真で決めると起き、後者は unknown の箱を数から外すと起きます。どちらも、候補と確定の欄を分け、分からない箱を残す設計で防げます。
10まず何から始めるか
1週目:並べ方と撮り方の決まりを作る
漁業者の代表と、魚種ごとに1段で並べる、列の端に船の札を置く、長い列は切れ目に目印を置くという決まりを作ります。職員が真上から撮る位置を、荷さばき所の柱などの目印で決めます。
2週目:3日分で試す
試しに撮った3日分の写真を Gemini API に渡し、箱数と魚種を台帳と突き合わせます。分からない箱が数から消えていないか、規格や重量を書いていないかを最優先で見ます。
3週目:魚種の一覧を整える
魚種の一覧に、その季節に揚がるか、見た目の特徴の短い説明、見分けにくい組の印の欄を足します。2週目に取り違えた組を見分けにくい組に入れます。
4週目:受付のフォルダから一覧までをつなぐ
時間主導型のトリガーで受付のフォルダを見に行き、船ごとの箱数の候補を一覧に書き出すところまで作ります。この時点では台帳に書き込まず、職員が一覧と野帳を見比べます。
2か月目: 申告の入力の画面と、台帳の「写真の候補」の欄と印を足します。職員が直した魚種と箱数の理由を毎週数えます。3か月目以降: 野帳をやめ、1件6分が何分になったかを実測します。直した理由が並べ方の決まりと魚種の一覧に反映され、セリの前に台帳がそろうようになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
対応する画像の形式が PNG、JPEG、WEBP、HEIC、HEIF であること。画像を直接入れる場合にリクエスト全体が20MBまでであること。物の位置を枠で返させる例があり、枠が [ymin, xmin, ymax, xmax] の順で0〜1000に正規化されること。画像のトークンの換算(768×768の区画ごとに258トークン) | Gemini API: Image understanding | 2026-10-15 |
構造化出力が /v1beta/interactions に response_format で mime_type を application/json にし、schema にスキーマを入れて送る形であること。enum、minItems、maxItems が使えること。値はアプリ側で検証するよう書かれていること | Gemini API: Structured output | 2026-10-15 |
Interactions API が既定でやり取りを保存し、有料の枠で55日保持すること。store=false で保存しないようにできること | Gemini API: Interactions | 2026-10-15 |
| 有料のサービスではプロンプトと応答が製品の改善に使われないこと。禁止された使い方の検知などのために限られた期間記録されること。18歳以上であることが利用の条件であること | Gemini API Additional Terms of Service | 2026-10-15 |
| インストール型のトリガーの種類(時間主導型、スプレッドシートの開く・編集・変更、フォームの送信、カレンダー)。時間主導型が1分ごとから月1回までで動き、時刻が少しずれることがあること。インストール型のトリガーは作った人のアカウントで動くこと | Apps Script: Installable triggers | 2026-10-15 |
| 1回の実行時間が6分まで。トリガーの合計の実行時間が一般のアカウントで1日90分、Google Workspace のアカウントで1日6時間まで。URL の取得の1回あたりの送信の大きさが50MBまで | Apps Script: Quotas for Google Services | 2026-10-15 |
| 特定水産資源を採捕した者が、農林水産省令で定める期間内に漁獲量その他の事項を農林水産大臣または都道府県知事に報告しなければならないこと(第26条・第30条)。特別管理特定水産資源では、個体の数と漁獲量の報告に加え、船舶等の名称と個体ごとの重量などの記録を作成・保存しなければならないこと | e-Gov 法令API: 漁業法 | 2026-10-15 |
漁獲量の報告の方法と期限、対象の魚種は、都道府県の規則と最新の省令・告示に沿って確かめてください。 本記事は公開の資料で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1687)についてのご相談はこちらから。
