Media > AI活用ユースケース > カスタマーサポート > 繰り返し注文する取引先の次の注文時期を購買履歴から見込んで、声をかける先と文面を用意する

繰り返し注文する取引先の次の注文時期を購買履歴から見込んで、声をかける先と文面を用意する

実装ステータス:構成例 技術的に実現可能な構成として設計したもの。自社未検証

定期的に同じ品目を買う取引先について、受注履歴から次の注文が来るはずの日を計算し、いつもより遅れている先だけを抜き出します。抜き出した先には、営業メモから事情を読み取ったうえで連絡文の下書きを用意します。

サマリー
生成AI
ChatGPT/Claude/Gemini
連携・自動化
Google Apps Script/Power Automate/Python
対象業界
商社/小売
対象部門
カスタマーサポート/営業
対象業務
書類作成/集計・分析
主な課題
データ分析に時間がかかる/営業フォローが追いつかない/期限・対応漏れが起きる
AIで行う処理
予測
主な効果
判断支援/工数削減/機会損失防止
導入難易度
★★☆☆☆
実装レベル
半自動化
費用感
API連携(中)
人間の確認
条件付き
現在工数
30h/月
AI導入後
7.5h/月
想定削減
75%
年間削減
270h
モデル条件による試算値です。実在企業の実績ではありません。

01導入前 / 導入後の業務フロー

導入前(Before)
  1. 月初に内勤営業が販売管理システムから直近1年の受注履歴をCSVで出し、スプレッドシートに貼る
  2. 取引先ごとに並べ替え、主な品目の前回注文日を目で追う
  3. 「いつもならもう注文が来ている」と感じた先に印を付ける
  4. 印を付けた先の営業メモを開き、最近の訪問や電話の記録を読む
  5. 連絡すべきと判断した先について、メールの文面を1通ずつ書くか、電話の要点をメモする
  6. 連絡の結果を営業メモに書き足す
導入後(After)
  1. 人週に1回、販売管理システムから受注履歴のCSVを出し、指定のシートに貼る(連携できる環境なら自動で取り込む)
  2. 自動決まった時刻に Apps Script が動き、取引先×品目ごとに注文間隔の中央値とばらつきを計算する
  3. 自動前回注文日と間隔から次回見込み日と遅れ日数を出し、遅れがばらつきを超えた先だけを抜き出す
  4. 自動注文回数が少ない先、季節で波のある品目、切り替えの兆しのある先を、それぞれ別の扱いに振り分ける
  5. 自動抜き出した先の営業メモを Gemini API に渡し、事情の分類と根拠の文を返させる
  6. 自動事情に合わせて、連絡文の下書きを作らせる
  7. 自動結果を「フォロー候補」シートに書き出す
  8. 人担当者が候補の一覧を見て、連絡するか・どの手段で連絡するかを決め、下書きを直して送る
  9. 人連絡の結果を候補シートに記録する
各工程の詳しい説明を読む
  1. 月初に内勤営業が販売管理システムから直近1年の受注履歴をCSVで出し、スプレッドシートに貼る
  2. 取引先ごとに並べ替え、主な品目の前回注文日を目で追う
  3. 「いつもならもう注文が来ている」と感じた先に印を付ける
  4. 印を付けた先の営業メモを開き、最近の訪問や電話の記録を読む
  5. 連絡すべきと判断した先について、メールの文面を1通ずつ書くか、電話の要点をメモする
  6. 連絡の結果を営業メモに書き足す

(a)「いつもなら」の基準が人の記憶にある。 3番目の判断は担当者が取引先の癖を覚えているかどうかで決まり、担当替えのあとは、止まった注文に数か月気づかないことがあります。

(b)遅れの大きさを比べられない。 毎月注文する先の2週間の遅れと、隔月の先の2週間の遅れは重さが違いますが、目で追う一覧では同じに見えます。結局、注文額の大きい先から見ることになり、小口の先の離脱は拾えません。

(c)300社を毎月見る時間が無い。 締めや繁忙期が重なる月から順に省かれ、省いた月に限って、他社へ切り替えた先が出ます。

  1. 【人】 週に1回、販売管理システムから受注履歴のCSVを出し、指定のシートに貼る(連携できる環境なら自動で取り込む)
  2. 【自動】 決まった時刻に Apps Script が動き、取引先×品目ごとに注文間隔の中央値とばらつきを計算する
  3. 【自動】 前回注文日と間隔から次回見込み日と遅れ日数を出し、遅れがばらつきを超えた先だけを抜き出す
  4. 【自動】 注文回数が少ない先、季節で波のある品目、切り替えの兆しのある先を、それぞれ別の扱いに振り分ける
  5. 【自動】 抜き出した先の営業メモを Gemini API に渡し、事情の分類と根拠の文を返させる
  6. 【自動】 事情に合わせて、連絡文の下書きを作らせる
  7. 【自動】 結果を「フォロー候補」シートに書き出す
  8. 【人】 担当者が候補の一覧を見て、連絡するか・どの手段で連絡するかを決め、下書きを直して送る
  9. 【人】 連絡の結果を候補シートに記録する

3番目がこの設計の要です。 遅れているかどうかを計算の規則で決めているので、同じ履歴からはいつも同じ候補が出ます。 担当者が替わっても、候補の選び方は変わりません。

8番目で、人は送るかどうかを決めます。 下書きが出ても、取引先との関係を知っているのは担当者です。送信は人が行い、この構成からは自動で送りません。

02今回想定するシステム構成

構成図
販売管理システム
   │  受注履歴をCSVで出力(週1回)
   ▼
Googleスプレッドシート「受注履歴」シート
   ▼【トリガー】時間主導型トリガー(毎週月曜 7時台)
Google Apps Script
   ├── 取引先×品目ごとに注文間隔の中央値・ばらつきを計算
   ├── 次回見込み日・遅れ日数を計算し、許容幅を超えた先を抽出
   └── 回数不足/季節品目/切り替えの兆し を振り分け
   ▼
   │  UrlFetchApp で呼び出し(抽出した先の営業メモと計算結果)
Gemini API
   │  ① 営業メモから事情を分類(根拠の文つき)
   │  ② 事情に合わせた連絡文の下書き
   ▼  JSONで返す
Google Apps Script ── 値の検査(分類が決められた語か、日付が計算結果と同じか)
   ▼
「フォロー候補」シート
   ▼
【人が確認】連絡する先と手段を決め、下書きを直して Gmail で送る
役割想定する製品代替候補
実行環境Google Apps ScriptPython、Power Automate
生成AIGemini APIOpenAI API、Claude API

スプレッドシートとGmailは、新しく足すものではありません。 受注履歴の置き場、候補の一覧、連絡の記録はすべてスプレッドシートに置き、送信は担当者がふだんのGmailで行います。販売管理システムには書き込みません。

実行環境を Apps Script にしたのは、データがすでにスプレッドシートにあるからです。 計算も呼び出しも同じ場所で書け、別のサーバーを用意する必要がありません。時間主導型トリガーは、毎分、数時間ごと、毎日の指定時刻、毎週の指定曜日、毎月、特定の日時で動かせます。ただし時刻は少しずらされ、9時のトリガーなら9時から10時のあいだのどこかで動き、その時刻は日ごとに保たれるとされています。朝の始業前に一覧をそろえたいなら、1時間早めに設定します。

インストール型のトリガーは、作成した人のアカウントで動きます。 担当者の個人アカウントで作ると、その人が異動したときに止まります。部署で管理するアカウントで作ることを最初に決めます。トリガーが失敗したときは、Apps Script から通知のメールが届きます。

外部との通信は UrlFetchApp で行います。 HTTPとHTTPSで外部のホストと通信するための仕組みで、method、contentType、headers、payload を指定して呼びます。muteHttpExceptions を true にすると、失敗の応答でも例外で止まらず応答が返るので、応答コードを見て再試行するかを決められます。

制限は、1回の実行が6分までという点がいちばん効きます。 トリガーの合計実行時間は一般アカウントで1日90分、Google Workspace のアカウントで1日6時間、トリガーはスクリプトごと・ユーザーごとに20個まで、URL Fetch の呼び出しは一般アカウントで1日20,000回、Workspace で1日100,000回とされています。これらは予告なく変わりうるとも書かれています。300社の計算は数秒で終わりますが、Gemini API を1社ずつ呼ぶと6分に届くことがあるため、呼び出しは分けて行います(第7章)。

Gemini API は構造化出力を使います。 JSONスキーマを渡して、決めた形のJSONで返させる機能で、用途として「テキストをあらかじめ決めたカテゴリに分類する」「名前や日付などの情報を取り出す」が挙げられています。構文として正しいJSONは返るが、値はアプリケーション側で検査することとされています。

03どうやって実装するのか

Step1

処理の起点を決める

時間主導型トリガーで、毎週月曜の朝に動かします。 注文は日々来ますが、フォローの判断は週に1回まとめて行えば足ります。毎日動かすと、同じ先が連日候補に出て、担当者が一覧を見なくなります。

トリガーは2本に分けます。1本目が計算と抽出(月曜6時台)、2本目が Gemini API の呼び出し(月曜7時台、以降は未処理が残っていれば15分ごと)です。1回の実行は6分までなので、計算と呼び出しを1本にまとめると、候補の多い週に途中で止まります。2本目は候補シートの「未処理」の行だけを取り、処理した行に印を付けて、次の実行は続きから始めます。

受注履歴のCSVが今週分に貼り替わっていなければ、1本目は計算をせずに担当者へ知らせて終わります。古い履歴で計算すると、先週注文した先が「遅れ」として出ます。

Step2

入力データを集める

データ中身取得元
受注履歴受注日、取引先コード、品目コード、数量販売管理システムのCSV(直近2年分)
品目の区分品目コード、季節品目かどうか、フォローの対象外とする品目か自社で用意する品目の表
取引先の情報取引先コード、名称、担当者、フォローを止めている理由(休業・取引停止など)取引先の表
営業メモ取引先コード、日付、記録者、本文営業メモのシート(直近90日分だけ)
過去の連絡結果取引先コード、連絡日、結果フォロー候補シートの記録

計算の質を決めるのは受注履歴の粒度です。 1回の注文に複数の品目があるときは、品目ごとに1行になっている必要があります。受注番号の単位で1行のCSVしか出せない場合は、品目で行を分けるところから準備します。

営業メモを直近90日に絞るのは、古い事情で今の遅れを説明させないためです。 1年前の「担当者交代」を根拠に、今月の遅れを説明する下書きが出るのを防ぎます。

Step3

データの取得方法を決める

取るものどこからどう取るか
受注履歴「受注履歴」シート週1回CSVを貼る。販売管理システムがファイルを出力できるなら、指定フォルダのCSVを読み込む処理を足す
品目の区分・取引先の情報同じスプレッドシート内の表Apps Script で読む
営業メモ営業メモのシート抽出した先の取引先コードで絞って読む
事情の分類と下書きGemini APIUrlFetchApp で呼び出し、JSONで受け取る

販売管理システムからの取り込みは、最初は手作業で構いません。 週に1回CSVを貼る作業は数分です。自動化するのは、計算の結果が営業に使われると確かめてからです。

Gemini API の呼び出しは、UrlFetchApp.fetch に送信先、method: 'post'、contentType: 'application/json'、APIキーを入れたヘッダー、本文を渡します。APIキーはスクリプトの本文に書かず、スクリプトの設定側に置きます。

Step4

AIへ渡す前に整形する

ここがこの記事の中心です。計算はすべて Apps Script で行い、AIには渡しません。

記号意味計算のしかた
n注文回数取引先×品目ごとの、直近2年の注文の数
間隔注文と注文のあいだの日数受注日を古い順に並べ、隣どうしの差を取る
M間隔の中央値間隔を並べた真ん中の値
S間隔のばらつき各間隔と M の差の絶対値を並べた真ん中の値
W許容幅S × 2 と 7日 の大きいほう
補正前回の数量による調整前回数量を数量の中央値で割った値。0.5〜2.0の範囲に収める
E次回見込み日前回注文日 + M × 補正
L遅れ日数基準日 - E

抽出の条件は「L が W を超えている」ことです。 平均ではなく中央値を使うのは、1回だけの長い空白(年末年始の休業など)に引きずられないためです。ばらつきにも同じ理由で中央値からの差を使います。W の下限を7日にしているのは、毎回きっちり同じ間隔で注文する先で S が0になり、1日の遅れで候補に出てしまうのを防ぐためです。

数量の補正は、まとめ買いへの対策です。 前回いつもの2倍を買った先は、次の注文もいつもより遅くなるのが普通です。補正を掛けずに計算すると、まとめ買いをしてくれた上客ほど「遅れ」として出てきます。

振り分けは次の順で行います。

  1. フォロー停止中の取引先 … 取引先の表に停止理由がある先は、計算せずに除きます
  2. 注文回数が3回未満 … 間隔が1つしか取れず、ばらつきを出せません。候補にはせず、「履歴不足」として件数だけ数えます
  3. 季節品目 … 品目の表で季節品目とした品目は、M と W による判定を使いません。前年の同じ月の前後1か月に注文があり、今年の同じ期間に無いときだけ候補にします
  4. 切り替えの兆し … 直近3回の数量がいずれも数量の中央値の半分以下で、L が W を超えている先は、「減少」として別の区分にします
  5. 長期停止 … L が M の3倍を超えている先も、「長期停止」として別の区分にします
  6. 残りのうち L が W を超えた先 … 「遅れ」として候補にします

4番目と5番目を「遅れ」と分けるのは、声のかけ方が違うからです。 数か月注文が無い先や、少しずつ量を減らしている先に「そろそろ在庫はいかがですか」と送ると、事情を分かっていない会社だと受け取られます。この2つの区分は下書きを作らず、担当者の判断に回します。

1社で複数の品目が候補になったときは、取引先ごとに1行にまとめます。 同じ週に同じ先へ品目ごとの連絡が3通届くのを防ぎます。

中央値と判定の部分は、次のように書けます。

function median(values) {
  const a = values.slice().sort((p, q) => p - q);
  const mid = Math.floor(a.length / 2);
  return a.length % 2 ? a[mid] : (a[mid - 1] + a[mid]) / 2;
}

// dates: 同じ取引先・同じ品目の受注日(Date)を古い順に並べたもの
function judge(dates, baseDate, correctedIntervalDays) {
  if (dates.length < 3) return { status: 'insufficient_history' };
  const day = 86400000;
  const gaps = [];
  for (let i = 1; i < dates.length; i++) {
    gaps.push(Math.round((dates[i] - dates[i - 1]) / day));
  }
  const m = median(gaps);
  const s = median(gaps.map(g => Math.abs(g - m)));
  const w = Math.max(s + s, 7);
  // correctedIntervalDays は M に数量の補正を掛けた日数(別の関数で計算)
  const expected = new Date(dates[dates.length - 1].getTime());
  expected.setDate(expected.getDate() + Math.round(correctedIntervalDays));
  const lateDays = Math.round((baseDate - expected) / day);
  return { median_interval: m, spread: s, tolerance: w,
           expected_date: expected, late_days: lateDays,
           is_late: lateDays > w };
}
Step5

AIに処理させる

Gemini API に渡すのは、候補になった先の計算結果と、直近90日の営業メモだけです。 受注履歴そのものは渡しません。

させること中身
事情の分類営業メモから、遅れの理由になりうる事情を決めた語から選ぶ
根拠の抜き出し分類の根拠にしたメモの文を、そのまま写す
連絡文の下書き「遅れ」区分の先について、事情に合わせたメールの下書きを作る

事情の分類は、在庫過多(まとめ買いした、在庫が余っている)、担当者交代、他社検討(相見積もり、他社の名前が出ている)、休業・改装、需要減(店舗の閉鎖、生産の縮小)、不満あり(納期・品質の苦情)、記載なし の7つです。

させないこと理由
次回見込み日や遅れ日数の計算・修正計算の結果をそのまま使う。AIが日付を書き換えると、なぜ候補になったかを説明できない
連絡するかどうかの判断取引先との関係を知っているのは担当者
値引きや特別条件の提案価格は営業の権限で決める
メモに無い事情の推測「たぶん在庫がある」と書かせない。無ければ 記載なし
減少・長期停止 区分の下書き担当者が事情を確かめてから連絡する

他社検討 と 不満あり が出た先も、下書きは作りますが担当者に先に知らせます。 定型の文面で済ませてよい先ではありません。

Step6

指示内容を固定する

system_instruction に次を置きます。

あなたは業務用消耗品の商社で、既存取引先へのフォローを手伝う内勤営業です。
渡された「計算結果」と「営業メモ」だけを使ってください。

【してほしいこと】
1. 営業メモから、注文が遅れている理由になりうる事情を、次の7つから1つ選ぶ。
   在庫過多/担当者交代/他社検討/休業・改装/需要減/不満あり/記載なし
2. 選んだ根拠となるメモの文を、一字一句そのまま evidence に写す。
3. category が「遅れ」の先について、取引先の担当者あてのメール下書きを作る。

【厳守事項】
- 次回見込み日、遅れ日数、品目名は、計算結果の値をそのまま使う。
  書き換えたり、別の日付を計算したりしない。
- メモに書かれていない事情を推測しない。当てはまる記載が無ければ「記載なし」とし、
  evidence は空にする。
- 事情が2つ以上あるときは、日付の新しいメモのほうを選ぶ。
- 下書きでは、注文が遅れていることを責める書き方をしない。
  「前回のご注文から○週ほど経ちましたので、在庫のご状況を伺えればと思います」の調子にする。
- 値引き、特別価格、納期の約束を書かない。
- 他社の名前がメモにあっても、下書きには書かない。
- 在庫過多のときは、次の注文を促さず、状況の確認だけにとどめる。
- 担当者交代のときは、新しいご担当者へのあいさつを先に書く。
- category が「減少」または「長期停止」のときは、draft を空にする。
- 下書きは本文だけ。署名は付けない。300字以内。

本文には、取引先ごとに次を入れます。

【取引先】{customer_name}(担当:{contact_name})
【計算結果】category: {category} / 品目: {items} / 前回注文日: {last_date}
           次回見込み日: {expected_date} / 遅れ日数: {late_days}
【営業メモ(直近90日、新しい順)】{memos}

「計算結果の値をそのまま使う」を最初に書くのは、下書きの中で日付が変わるのを防ぐためです。 何も言わないと、メモの日付と見込み日を混ぜて「3週間ほど」を「1か月ほど」に言い換えることがあります。

「在庫過多のときは注文を促さない」を明記するのは、下書きの失敗がいちばん目立つ型だからです。 在庫を持ちすぎたと言った先に注文を勧めると、メモを読んでいないことが相手に伝わります。

Step7

出力形式を固定する

構造化出力で、次のスキーマを渡します。 送信先は https://generativelanguage.googleapis.com/v1beta/interactions、ヘッダーは x-goog-api-key、本文の response_format に mime_type: "application/json" とスキーマを入れます。

{
  "type": "object",
  "properties": {
    "customer_code": { "type": "string" },
    "reason": {
      "type": "string",
      "enum": ["在庫過多", "担当者交代", "他社検討", "休業・改装", "需要減", "不満あり", "記載なし"]
    },
    "evidence": { "type": "string" },
    "evidence_date": { "type": "string", "format": "date" },
    "expected_date": { "type": "string", "format": "date" },
    "late_days": { "type": "integer" },
    "draft": { "type": "string" },
    "notify_first": { "type": "boolean" }
  },
  "required": ["customer_code", "reason", "evidence", "expected_date", "late_days", "draft", "notify_first"]
}

JSONにする1つ目の理由は、reason を決めた語に固定できることです。 enum で7つに絞るので、「在庫がだぶついている」のような言い換えが入らず、事情ごとの件数を毎週数えられます。

2つ目は、戻ってきた値を検査できることです。 構文として正しいJSONが返っても値の正しさは保証されないので、Apps Script で次を確かめます。

検査合わないとき
expected_date と late_days が計算結果と同じか下書きを捨て、要確認 にする
evidence がメモの本文にそのまま含まれるかreason を 記載なし に戻し、要確認 にする
reason が 記載なし なのに evidence が入っていないかevidence を空にする
区分が 減少・長期停止 なのに draft が入っていないかdraft を空にする

2行目が効きます。 根拠の文がメモに無ければ、それはAIが作った事情です。文字列の一致で機械的に見分けられるので、人が読む前に落とせます。

Step8

システムへ連携する

つなぎ先方式内容
受注履歴シートApps Script で読む取引先×品目ごとの受注日と数量
品目・取引先の表Apps Script で読む季節品目、フォロー停止の理由
営業メモのシートApps Script で読む候補の先の直近90日分だけ
Gemini APIUrlFetchApp事情の分類と下書きをJSONで受け取る
フォロー候補シートApps Script で書く1社1行。区分、見込み日、遅れ日数、事情、根拠、下書き、担当者

フォロー候補シートは、担当者の列で絞って見られるようにします。 1行ごとに「連絡した/見送った/次回に回す」の選択欄と、結果を書く欄を置きます。

Gmail への送信は、この構成に入れません。 下書きを候補シートからコピーして、担当者がふだんのGmailから送ります。送信まで自動にすると、在庫過多の先に注文を促す1通が、止める人のいないまま出ていきます。

Step9

人が確認する

人が見るのは、候補シートに出た先だけです。 300社を毎月見る作業は、計算が肩代わりします。

  1. notify_first が付いた先を先に見る … 他社検討 と 不満あり。メールより電話か訪問がよいかを先に決めます
  2. 減少・長期停止 の先を見る … 下書きはありません。取引の状況を知っている担当者が、連絡するかを決めます
  3. 遅れ の先の下書きを直して送る … 事情と根拠の文を読み、下書きがそれに合っているかを確かめます
  4. 結果を記録する … 「在庫があった」「他社に替えていた」「注文をもらえた」を選択欄で残します

4番目を省かないでください。 「在庫があった」が多い先は、数量の補正が足りていないか、間隔の中央値が実態より短く出ています。記録が無いと、計算の規則を直す材料がありません。

Step10

例外に対処する

起きること対応
注文回数が3回未満候補にしない。「履歴不足」として件数だけ数え、月1回担当者に一覧を渡す
季節で波のある品目品目の表で季節品目にしたものは、前年同期との比較で判定する
他社へ切り替えた兆し(数量の減少、長期停止)下書きを作らず、担当者に回す
受注履歴が今週分に貼り替わっていない計算をせずに担当者へ知らせて終わる
取引先コードが営業メモと合わない事情は 記載なし として扱い、候補シートに「メモ未照合」と印を付ける
1回の実行が6分に近づく処理した行に印を付けて止め、次のトリガーで続きから
Gemini API が失敗の応答を返すmuteHttpExceptions で応答コードを見て、その行を未処理のまま残す。3回続けば担当者に知らせる
返ったJSONの値が検査に通らない下書きを捨て、要確認 として計算結果だけを候補シートに出す
長期休業・年末年始取引先の表の停止理由と、基準日から除く期間の表で除く

上の3行が、計算の規則だけでは決めきれない部分です。 どれも「遅れ」として一律に扱うと、連絡してはいけない先に定型の文面が届きます。区分を分け、人に回す先をはっきりさせておくことが、この構成の例外処理の中心です。

Step11

記録を残す

  • 実行日時と、使った受注履歴のCSVの出力日
  • 取引先×品目ごとの n、M、S、W、補正、E、L と、振り分けた区分
  • Gemini API に渡した本文と、返ったJSONの全文
  • 値の検査の結果(通った/要確認 にした理由)
  • 担当者の対応(連絡した/見送った/次回に回す)と、連絡の結果

2つ目を毎週残すのは、後から「なぜこの先が候補になったのか」を説明するためです。 候補から漏れた先で注文が止まったときも、その週の計算の値を見れば、W が広すぎたのか、履歴不足で外れたのかが分かります。

04実装レベルの3段階

最小構成:スプレッドシートの関数で間隔と遅れを計算し、営業メモを手で Gemini の画面に貼る / 遅れている先の抽出
半自動化:上記+Apps Script を時間主導型トリガーで動かし、Gemini API で事情の分類と下書きを候補シートに書き出す / 抽出、事情の読み取り、連絡文の下書き
本格構成:上記+販売管理システムから受注履歴を自動で取り込み、連絡の結果から許容幅を取引先ごとに調整する / 取り込みから候補の作成まで

本記事の想定は半自動化です。 CSVを週1回貼る数分の手作業は残りますが、1件6分の作業のうち、履歴を追う・遅れを判断する・メモを読む・文面を書くの大部分が置き換わります。 本格構成は、半自動化で2〜3か月の連絡結果がたまってから進めてください。 「在庫があった」の記録が無いうちに許容幅を自動で調整すると、何を根拠に広げたのか分からなくなります。販売管理システムの出力の仕組みも、会社ごとに違います。

05工数削減シミュレーション

前提値(モデル条件)
対象人数
3 名
月間件数
300 件
1件あたり現在時間
6 分
1件あたり導入後時間
1.5 分
現在  300件 × 6分 ÷ 60 = 30 時間/月
導入後 300件 × 1.5分 ÷ 60 = 7.5 時間/月
月間削減時間
22.5h
削減率
75%
年間削減時間
270h
年間金額換算(時間単価3,000円)
81万円
モデル条件による試算であり、実際の効果は業務内容・運用方法によって異なります。

自社条件で導入効果を整理したい方へ

このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。

AI活用について相談する

06向いている企業・向いていない企業

向いている
  1. 包装資材・清掃用品・事務用品・飲食店向け食材など、同じ取引先が同じ品目を周期的に注文してくる商社や小売の法人営業。受注履歴を販売管理システムからCSVで出せ、Googleスプレッドシートで扱える場合。取引先が数百社以上あり、営業が「そろそろ注文が来るはず」の先を記憶に頼って追っている場合。
向いていない
  1. 注文が案件ごとの一品物で、同じ品目の繰り返しがほとんど無い場合。取引先が数十社で、営業が全社の注文の波を把握できている場合。定期便・自動補充の契約で注文の時期がすでに決まっている場合。なお、取引を続けるか、値引きで引き留めるかといった判断は、この構成では代替できません。

07最小構成で試す方法

  1. 受注履歴から、過去1年に3回以上注文のある取引先を20社選ぶ(うち数社は、実際に注文が止まった先を入れる)
  2. スプレッドシートで取引先×品目ごとに受注日を並べ、隣どうしの差を関数で出す
  3. 間隔の中央値と、中央値との差の中央値を関数で出し、第7章の表のとおりに見込み日と遅れ日数を計算する
  4. 遅れが許容幅を超えた先について、営業メモを手元の Gemini の画面に貼り、「この営業メモから、注文が遅れている理由を7つの分類から選び、根拠の文をそのまま写してください。書かれていなければ記載なしとしてください」と指示する
  5. 候補になった先と、担当者の記憶で「気になっていた先」を突き合わせる

AIを使う前に、計算だけで候補が妥当かを確かめてください。 この構成の価値の大半は計算の側にあります。

出てきた内容判断
実際に止まった先が候補に出たApps Script で自動化に進む
まとめ買いの先ばかりが出た数量の補正を入れる。構成は有効
季節品目の先が毎回出る品目の表に季節品目の列を作るのが先

08実装時につまずきやすいポイント

問題対策
次回見込み日をAIに出させてしまう計算は Apps Script で行う。 AIには計算結果を渡すだけにする
まとめ買いした上客が「遅れ」に出る前回数量による補正を入れ、0.5〜2.0に収める
毎回きっちり注文する先が1日の遅れで出る許容幅に7日の下限を置く
年末年始の空白で中央値が伸びる平均でなく中央値を使い、除く期間の表を持つ
季節品目が毎年同じ時期に候補に出る品目の表で季節品目を分け、前年同期と比べる
受注番号単位のCSVで品目ごとに計算できない品目で行を分けて出力できるか、先に確かめる
実行が6分で途中で止まる計算と呼び出しのトリガーを分け、処理した行に印を付けて続きから
トリガーが担当者の異動で止まる作成者のアカウントで動く。 部署で管理するアカウントで作る
下書きの日付や期間がずれる計算結果と照合し、合わなければ下書きを捨てる
メモに無い事情が書かれる根拠の文がメモに含まれるかを文字列で照合する
在庫過多の先に注文を促す文面が出る指示で禁じ、事情ごとの書き方を決めておく
同じ先へ品目ごとに何通も届く取引先ごとに1行にまとめる

上の3行は、AIではなく計算の問題です。 候補の選び方が営業の感覚とずれると、下書きがよくても一覧が見られなくなります。最小構成で20社を試す段階で、ここを先に合わせてください。

09セキュリティ・AIガバナンス上の注意点

この構成で扱うデータ: 取引先の名称と担当者名、品目ごとの注文の時期と数量、そして営業メモに書かれた取引先の内部事情(担当者の異動、店舗の閉鎖、他社との比較)です。

  1. 外部へ渡すのは候補の先の直近90日のメモだけ … 受注履歴や取引先の一覧は Gemini API に渡しません。計算はスプレッドシートの中で終わらせます
  2. 営業メモの個人に関する記述に気をつける … 「担当の○○さんが体調を崩して」のような記述は、下書きの材料にしません。メモの書き方のルールを、あわせて営業部で決めてください
  3. 連絡するかどうかは人が決める … 送信は担当者が行います。他社検討や不満ありの先に定型の文面が届くと、取引そのものに響きます
  4. 価格の話を下書きに入れない … 値引きや特別条件は営業の権限です。AIが書いた条件が取引先に届くと、約束として受け取られます
  5. APIキーと実行アカウントを部署で管理する … キーはスクリプトの本文に書かず、トリガーは部署で管理するアカウントで作ります
  6. 利用する契約の条件を確かめる … 外部のAIへ取引先の情報を送るため、入力したデータの扱いが自社の取り決めに合う契約・設定かを、情報システム担当と確かめてから本番のデータを流します

誤りが起きた場合のリスクは、連絡すべき先を見落とすことと、連絡すべきでない先に定型の文面を送ることの2つです。 前者は許容幅と振り分けの規則で、後者は区分ごとの下書きの扱いと人の確認で防ぎます。

10まず何から始めるか

1週目:受注履歴の形を確かめる

販売管理システムから直近2年の受注履歴をCSVで出し、品目ごとに1行になっているか、取引先コードが営業メモと同じかを確かめます。あわせて、主な品目に季節品目の印を付けます。

2週目:20社で計算だけを試す

第8章の手順で20社の見込み日と遅れ日数を出し、担当者の記憶と突き合わせます。まとめ買いと季節品目で外れた先を数え、補正と振り分けの規則を決めます。

3週目:Apps Script で計算を自動にする

第7章の計算を Apps Script に移し、時間主導型トリガーで毎週の候補シートを出します。この時点ではAIを呼ばず、候補の一覧だけを1週間使ってもらいます。

4週目以降: Gemini API での事情の分類と下書きを足し、連絡の結果を記録します。「在庫があった」の件数を毎週見て、許容幅の規則を直していった時点で、この構成は運用に乗ります。


11関連ユースケース

12この仕組みを理解するための記事

13技術仕様の確認日・参考情報

技術仕様確認日:2026-09-28/最終更新:2026-09-28
確認した内容情報源確認日
時間主導型トリガーの間隔(毎分〜特定日時)、時刻が1時間の範囲でずらされ日ごとに保たれること、作成者のアカウントで動くこと、失敗時に通知メールが届くことGoogle for Developers: Installable Triggers2026-09-28
UrlFetchApp の fetch/fetchAll、method・contentType・headers・payload、muteHttpExceptions が true なら失敗時も応答を返すことGoogle for Developers: Class UrlFetchApp2026-09-28
1回の実行6分、トリガーの合計実行時間(一般90分/Workspace 6時間)、トリガー20個、URL Fetch 1日20,000回/100,000回、予告なく変わりうることGoogle for Developers: Quotas for Google Services2026-09-28
response_format に mime_type とスキーマを渡すこと、enum・required・format が使えること、分類と抽出が用途に挙がること、値はアプリ側で検査すべきことGoogle AI for Developers: Structured outputs2026-09-28
interactions の送信先、x-goog-api-key ヘッダー、system_instruction、generation_configGoogle AI for Developers: Text generation2026-09-28

実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。

自社の業務に使えるAI活用候補を整理します

このユースケース(UC-0263)についてのご相談はこちらから。

AI活用について相談する
目次