AIエージェントや問い合わせ自動化を始める前に、業務フローを一度図にするだけでは足りません。通常ケースしか書かれていないフローは、例外が来た時に「どこで止めるか」「誰へ戻すか」を決められないからです。
この記事では、GoogleスプレッドシートとGoogle Apps Script(GAS)で、実データを扱わずに業務フローのサンプルケース台帳を作ります。通常・境界・停止の期待結果を固定し、AIを接続する前に人間確認の位置を検証できるようにします。
作るもの
WORKFLOW_CASES と CASE_RUNS の2シートを用意し、次を実装します。
- 業務の入口、AIに任せる処理、人間確認、戻し先をケース定義にする
- 通常・境界・停止の期待判定を固定する
- 実行結果を期待結果と比較し、差分だけをレビュー対象にする
- 実際の顧客本文ではなく、架空のケースまたは参照IDだけで検証する
この台帳はAIの正しさを証明するものではありません。AIの出力を自動承認したり、停止ケースを通常処理へ進めたりする処理は作りません。
シートの列
WORKFLOW_CASES
case_id,workflow,case_type,input_summary,required_fields,
ai_allowed,expected_route,expected_reviewer,return_to,active
例:
| case_id | case_type | 条件 | ai_allowed | expected_route |
|---|---|---|---|---|
| WF-001 | normal | 必須項目がそろい、参照FAQがある | true | draft |
| WF-002 | boundary | 利用環境が未記入で補足が必要 | false | clarify |
| WF-003 | stop | 契約・返金・苦情を含む | false | manual |
input_summary には顧客本文や氏名を書かず、架空の短い説明か社内で管理する参照IDだけを置きます。expected_route は自由記述にせず、draft、clarify、manual、reject のように固定します。
CASE_RUNS
run_id,case_id,run_at,actual_route,actual_reviewer,
review_status,diff_reason,next_action
ケース定義と実行結果を分けることで、期待結果を書き換えて実績に合わせる事故を防げます。
GASで判定する
まず、判定に使う値をコード側で固定します。
const CASE_SHEET = 'WORKFLOW_CASES';
const RUN_SHEET = 'CASE_RUNS';
const CASE_TYPES = ['normal', 'boundary', 'stop'];
const ROUTES = ['draft', 'clarify', 'manual', 'reject'];
function assertOneOf_(value, values, label) {
if (!values.includes(value)) {
throw new Error(`${label} must be one of: ${values.join(', ')}`);
}
}
function makeCaseIndex_(rows) {
const index = new Map();
rows.slice(1).forEach((row, offset) => {
const [caseId, workflow, caseType, inputSummary, requiredFields,
aiAllowed, expectedRoute, reviewer, returnTo, active] = row;
if (!caseId || String(active).toLowerCase() !== 'true') return;
assertOneOf_(caseType, CASE_TYPES, `case_type at row ${offset + 2}`);
assertOneOf_(expectedRoute, ROUTES, `expected_route at row ${offset + 2}`);
if (!inputSummary || !returnTo) {
throw new Error(`case ${caseId} needs input_summary and return_to`);
}
index.set(caseId, { caseId, workflow, caseType, aiAllowed,
expectedRoute, reviewer, returnTo });
});
return index;
}
function validateRun_(run, caseIndex) {
const spec = caseIndex.get(run.caseId);
if (!spec) throw new Error(`unknown or inactive case: ${run.caseId}`);
assertOneOf_(run.actualRoute, ROUTES, 'actual_route');
const sameRoute = run.actualRoute === spec.expectedRoute;
const stopWasBypassed = spec.caseType === 'stop' && run.actualRoute === 'draft';
return {
result: sameRoute && !stopWasBypassed ? 'match' : 'review',
diffReason: sameRoute ? '' : `${spec.expectedRoute} expected, ${run.actualRoute} actual`
};
}
function reviewLatestRuns() {
const book = SpreadsheetApp.getActive();
const caseRows = book.getSheetByName(CASE_SHEET).getDataRange().getValues();
const runSheet = book.getSheetByName(RUN_SHEET);
const caseIndex = makeCaseIndex_(caseRows);
const values = runSheet.getDataRange().getValues();
const header = values[0];
const col = Object.fromEntries(header.map((name, i) => [name, i]));
values.slice(1).forEach((row, offset) => {
if (!row[col.run_id] || row[col.review_status]) return;
const result = validateRun_({
caseId: row[col.case_id],
actualRoute: row[col.actual_route]
}, caseIndex);
runSheet.getRange(offset + 2, col.review_status + 1).setValue(result.result);
runSheet.getRange(offset + 2, col.diff_reason + 1).setValue(result.diffReason);
if (result.result === 'review') {
runSheet.getRange(offset + 2, col.next_action + 1)
.setValue('人間確認: 期待ルートと実績を照合');
}
});
}
この関数は差分の発見までです。review を approved へ変更する処理は、担当者が根拠と戻し先を確認した後に行います。
ケースを増やす順番
最初から大量の実例を登録すると、個人情報や契約情報が混ざります。次の順で架空ケースを増やします。
- 必須項目がそろった通常ケースを2件作る
- 必須項目不足、参照元不一致、担当者不在を境界ケースにする
- 契約、返金、苦情、個人情報、権限不明を停止ケースにする
- 各ケースの
return_toに、フォーム補足、担当者、責任者などの戻し先を書く - AIを接続する前に、期待ルートと人間確認者をレビューする
公開前・運用前チェックリスト
- ケースに顧客本文、氏名、連絡先、契約番号、認証情報がない
- 通常・境界・停止が最低1件ずつある
-
停止ケースの
expected_routeがmanualになっている - 実績と期待結果を別シートへ保存している
- 差分が出た時の確認者と戻し先がある
- AIの自動承認、自動送信、自動更新をこのGASに実装していない
- ケース追加やルール変更の理由を別の判断ログに残す
まとめ
AI導入前の業務フローは、きれいな一本道よりも、迷った時に戻れるケース台帳として作る方が運用に向いています。GASで自動化する範囲は期待結果との差分抽出までに絞り、ケースの妥当性、停止条件、次の担当者は人間が確認します。
Miraigentでは、AI導入の相談でも「何を任せるか」だけでなく、境界ケースと停止後の戻し先を確認しています。まずは直近の業務を、架空の通常・境界・停止ケース3件へ書き換えるところから始めてください。
