生成AIを業務へ導入するとき、「使えそうな業務」を探すだけでは判断が偏ります。入力の根拠が不明、人間確認の時間がない、失敗時の戻し先がない、といった状態で試行を始めると、自然な文章が返ってきても運用を続けられません。
この記事では、GoogleスプレッドシートとGoogle Apps Script(GAS)で、AI導入候補を PILOT(試行)、PREPARE(保留)、STOP(見送り)に分ける判断表を作ります。AI APIの呼び出し、顧客への自動送信、試行の自動承認は扱いません。GASは入力された確認結果を集計し、人間が次に見る候補を整理します。
作るもの
ADOPTION_SCOPE_GATE シートに、1行1業務で候補を登録します。次の5項目を0〜2点で記録し、危険フラグがあれば点数より先に STOP とします。
| 列 | 入力例 | 意味 |
|---|---|---|
scope_id |
SCOPE-001 |
候補を追跡するID |
work_name |
問い合わせ一次分類 | 対象を一つの工程に絞った名前 |
impact_scope |
2 |
影響範囲が限定されているか |
input_and_source |
2 |
入力項目と現行の正本があるか |
human_review |
1 |
確認者と確認時間が決まっているか |
recovery_path |
2 |
元の手順へ戻れるか |
decision_log |
1 |
判断理由と次回日を残せるか |
risk_flags |
none |
contract_or_money などの停止条件 |
route |
PREPARE |
GASが返す候補ルート |
owner |
業務管理者 | 台帳を更新する責任者 |
reviewer |
CS責任者 | 試行時に確認する人 |
next_review_at |
2026-09-16 |
次回の確認日 |
reason |
根拠の版が未確認 | その判定になった理由 |
判定ルールを先に固定する
点数の意味を決めずに集計を始めると、導入したい候補に都合よく点数を付けてしまいます。まず、次のルールをチームで共有します。
-
PILOT: 5項目をすべて測定でき、合計8点以上。少数件・人間確認付きで試行する -
PREPARE: 未入力がある、または合計8点未満。補う項目、担当者、期限を記録する -
STOP: 契約・料金・返金・苦情・重大な個人情報などの停止フラグがある、または復旧先・最終判断者が不明
PILOT は導入の成功や自動送信を意味しません。試行を始める前に、業務責任者が対象範囲、確認者、復旧方法を確認します。未確認の空欄を0点と断定せず、まず PREPARE に送ります。
スプレッドシートを準備する
空のスプレッドシートを作成し、Apps Scriptエディタに次のコードを貼り付けて setupAdoptionScopeGate を一度実行します。既存シートがある場合は、同名シートを作り直さずヘッダーの差分を確認してください。
const SHEET_NAME = 'ADOPTION_SCOPE_GATE';
const HEADERS = [
'scope_id',
'work_name',
'impact_scope',
'input_and_source',
'human_review',
'recovery_path',
'decision_log',
'risk_flags',
'route',
'owner',
'reviewer',
'next_review_at',
'reason',
'checked_at',
];
function setupAdoptionScopeGate() {
const book = SpreadsheetApp.getActiveSpreadsheet();
const sheet = book.getSheetByName(SHEET_NAME) || book.insertSheet(SHEET_NAME);
if (sheet.getLastRow() === 0) {
sheet.getRange(1, 1, 1, HEADERS.length).setValues([HEADERS]);
sheet.setFrozenRows(1);
}
}
入力例
まずは実際の顧客本文や個人情報を貼らず、業務の概要だけで3件入力します。
SCOPE-001 | 問い合わせ一次分類 | 2 | 2 | 2 | 2 | 1 | none
SCOPE-002 | 契約更新の返信案 | 0 | 2 | 2 | 2 | 2 | contract_or_money
SCOPE-003 | 社内FAQ候補の整理 | 2 | | 1 | 2 | 1 | none
SCOPE-002 は合計点に関係なく停止します。SCOPE-003 は input_and_source が未確認なので、都合よく0点として見送りにせず、保留理由と確認期限を登録します。
GASでルート候補を計算する
次の関数は、点数と停止フラグからルート候補を返します。配列やオブジェクトに未知の値が入った場合も、通常処理へ進めず PREPARE に戻します。
const CRITERIA = [
'impact_scope',
'input_and_source',
'human_review',
'recovery_path',
'decision_log',
];
const HARD_STOP_FLAGS = new Set([
'contract_or_money',
'high_impact_personal_data',
'complaint_or_incident',
'recovery_path_unknown',
'final_decider_unknown',
]);
function suggestRoute(record) {
const flags = String(record.risk_flags || '')
.split(',')
.map((flag) => flag.trim())
.filter(Boolean);
if (flags.some((flag) => HARD_STOP_FLAGS.has(flag))) {
return { route: 'STOP', reason: 'hard_stop_flag' };
}
const scores = CRITERIA.map((key) => record[key]);
const measured = scores.every((value) => {
const number = Number(value);
return Number.isInteger(number) && number >= 0 && number <= 2;
});
if (!measured) {
return { route: 'PREPARE', reason: 'unmeasured_criterion' };
}
const score = scores.reduce((sum, value) => sum + Number(value), 0);
if (score >= 8) {
return { route: 'PILOT', score };
}
return { route: 'PREPARE', score, reason: 'criteria_to_prepare' };
}
シートの行を更新する
続けて、ヘッダー名を読み取り、各行の route、reason、checked_at を更新します。入力データをAIへ送信したり、外部へ通知したりする処理は含めません。
function evaluateAdoptionScopeRows() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet || sheet.getLastRow() < 2) return;
const values = sheet.getDataRange().getValues();
const headers = values[0].map(String);
const index = Object.fromEntries(headers.map((name, i) => [name, i]));
const required = [...CRITERIA, 'risk_flags', 'route', 'reason', 'checked_at'];
required.forEach((name) => {
if (index[name] === undefined) throw new Error(`Missing column: ${name}`);
});
const now = new Date();
const output = values.slice(1).map((row) => {
if (row.every((value) => value === '')) return row;
const record = Object.fromEntries(
headers.map((name, i) => [name, row[i]]),
);
const result = suggestRoute(record);
row[index.route] = result.route;
row[index.reason] = result.reason || `score_${result.score}`;
row[index.checked_at] = now;
return row;
});
sheet.getRange(2, 1, output.length, headers.length).setValues(output);
}
トリガーを設定する場合も、まずは手動実行で結果を確認します。時間主導トリガーで勝手に試行を開始したり、PILOT の行を自動で公開状態へ変えたりする設定は作りません。
判定結果を人が確認する
GASの集計後は、route ごとに次の順番で確認します。
-
STOPを開き、AIへ渡さない理由と戻し先を記録する -
PREPAREの空欄を、正本・確認者・期限の順に補う -
PILOTは対象を一業務・少数件に限定する - 通常、境界、停止に近いケースを分けて記録する
- 確認時間、差し戻し、復旧の事実を次回レビューへ持ち込む
次の条件を満たしていても、別の業務へ自動的に範囲を広げません。
- 入力と参照先が現行である
- 人間の確認者と確認時間がある
- 失敗時に元の手順へ戻れる
- 判断理由、ルールの版、次回確認日が残る
運用チェックリスト
- 対象を一つの業務工程として書いた
- 顧客、契約、料金、返金、苦情、個人情報への影響を確認した
- AIへ渡してよい情報と渡さない情報を分けた
- 入力項目と現行の正本を特定した
- 最終確認者、不在時の戻し先、復旧方法を決めた
-
PILOT、PREPARE、STOPの意味を共有した - 判断理由、ルールの版、確認日時、次回確認日を残した
- 空欄を安全または危険と都合よく解釈していない
-
PILOTでも顧客への自動送信を許可していない
この構成で扱わないこと
この実装は、業務候補の確認漏れを見つけるための台帳です。AIの正確性、導入効果、法令への適合、情報漏えいがないことを保証するものではありません。
顧客本文、氏名、メールアドレス、認証情報、契約・決済情報は、候補表へ複製しません。高い影響を持つ判断、苦情、返金、採用可否などは、点数が高くてもAIの自動判断対象にせず、人間確認または対象外に戻します。
Miraigentでは、AIを入れる前に「試す条件」だけでなく「今回は見送る条件」と「見送った後に整える場所」を業務単位で確認します。最初の一歩は、直近の候補を3件だけ匿名化して台帳へ置き、点数を付けられない列を見つけることです。
