0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

問い合わせ対応をAI化する前に決めるエスカレーション条件

0
Posted at

問い合わせの一次分類や返信案作成をAIに任せる時、先に決めるべきなのはプロンプトではありません。AIの出力を誰が確認し、どの条件で担当者・責任者へ戻すかです。

本稿では、Googleフォームとスプレッドシートに問い合わせを集め、GASで「通常」「確認」「停止」を振り分ける最小構成を実装します。AI呼び出しは任意の後段に置き、顧客への自動送信は行いません。

この記事で作るもの

  • 問い合わせを1行1件で記録するシート
  • 影響度・情報不足・契約/返金などの条件から確認先を決めるGAS
  • AIの返信案を作る前に、人へ戻す判断ログ
  • 担当者不在時にも一人で決めないための停止条件

判断の出力はあくまで候補です。顧客への送信、返金、契約変更、個人情報を含む処理は人が確定します。

判定ルールを先に固定する

入力された文章をそのままAIへ渡して判定させるのではなく、受付時点で業務上の条件を記録します。

項目 該当時の扱い
影響度 通常 / 重要 / 重大 重要以上は確認
情報不足 あり / なし ありは追加質問へ戻す
契約・料金 あり / なし ありは責任者確認
個人情報 あり / なし 伏せ字確認。自動送信しない
苦情・事故 あり / なし 即時停止して担当者へ戻す
回答根拠 FAQの項目ID 空欄なら確認

「AIが自信ありと返した」はエスカレーション条件を解除する根拠にしません。業務条件と根拠の有無をルールにします。

シートの最小構成

INQUIRIES シートに次の列を作ります。

case_id,received_at,category,impact,missing_info,contract_flag,
personal_info_flag,complaint_flag,faq_id,reviewer,status,reason,next_action

impactnormalimportantcritical の3値に限定します。自由記述だけにすると、担当者ごとに基準がずれます。

GASで確認先を決める

次の関数はAIを呼び出しません。受付後に必ず実行し、AIへ渡す前の業務ゲートにします。

const STATUS = Object.freeze({
  DRAFT: 'DRAFT',
  HUMAN_REVIEW: 'HUMAN_REVIEW',
  STOPPED: 'STOPPED',
  READY_FOR_DRAFT: 'READY_FOR_DRAFT',
});

function classifyInquiry(row) {
  const reasons = [];

  if (row.complaint_flag === true || row.impact === 'critical') {
    reasons.push('苦情または重大影響');
    return { status: STATUS.STOPPED, reviewer: '責任者', reasons };
  }
  if (row.contract_flag === true) reasons.push('契約・料金の確認が必要');
  if (row.personal_info_flag === true) reasons.push('個人情報の扱いを確認');
  if (row.missing_info === true) reasons.push('追加情報が必要');
  if (!row.faq_id) reasons.push('回答根拠が未登録');
  if (row.impact === 'important') reasons.push('重要影響');

  if (reasons.length > 0) {
    return { status: STATUS.HUMAN_REVIEW, reviewer: '担当者', reasons };
  }
  return { status: STATUS.READY_FOR_DRAFT, reviewer: '担当者', reasons: [] };
}

実際のシート値は文字列になるため、チェックボックス列を読む場合は次のように正規化します。

function toBoolean(value) {
  return value === true || value === 'TRUE' || value === 'true';
}

function classifySheetRow(values, columns) {
  const row = {
    impact: values[columns.impact],
    missing_info: toBoolean(values[columns.missing_info]),
    contract_flag: toBoolean(values[columns.contract_flag]),
    personal_info_flag: toBoolean(values[columns.personal_info_flag]),
    complaint_flag: toBoolean(values[columns.complaint_flag]),
    faq_id: values[columns.faq_id],
  };
  return classifyInquiry(row);
}

トリガー処理では「送信」まで進めない

フォーム送信トリガーは、分類と記録だけを行います。返信案の作成を追加する場合も、READY_FOR_DRAFT の行だけを対象にし、送信処理とは別のメニューに分けます。

function onFormSubmit(event) {
  const sheet = event.range.getSheet();
  const values = sheet.getRange(event.range.getRow(), 1, 1, sheet.getLastColumn())
    .getValues()[0];
  const columns = getColumnIndexMap(sheet);
  const result = classifySheetRow(values, columns);

  writeDecision(sheet, event.range.getRow(), result);
  // ここでは外部API呼び出し、顧客送信、契約変更を行わない。
}

例外時に戻れる判断ログを残す

最低限、次の値を同じ行か別の DECISION_LOG シートへ保存します。

case_id: INQ-20260912-001
status: HUMAN_REVIEW
reason:
  - 回答根拠が未登録
reviewer: 担当者
next_action: FAQ候補を確認してから返信案を作る
decided_at: 2026-09-12T10:15:00+09:00

reason を「AIが不安定だった」の一言で終わらせず、FAQ、フォーム項目、CRM、承認ルールのどこを直すかまで記録します。判断ログは監視のためだけでなく、次の担当者が同じ迷いを繰り返さないための改善入口です。

本番前チェックリスト

  • 重大影響・苦情・契約/料金を停止条件にした
  • 個人情報をAIへ送る前の伏せ方を決めた
  • FAQの項目IDなど回答根拠を記録できる
  • 担当者不在時の代理確認者と、代理で決めない条件がある
  • READY_FOR_DRAFT と顧客送信の処理を分離した
  • 例外・復旧・最終判断をログへ残せる
  • テストデータに実顧客情報を使っていない

まとめ

問い合わせ対応のAI化は、回答を速くする処理から始めると、確認責任が曖昧になりやすいです。先に「どこまで進めるか」「どこで止めるか」「誰へ戻すか」を固定し、GASはその境界を機械的に記録する役割に絞ります。

Miraigentでは、AI導入前に対象業務・人間確認・例外・判断ログ・改善先を一緒に棚卸ししています。導入可否を決める前に、まず直近の問い合わせ1件をこの表へ当てはめてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?