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導入診断キューに変えるGoogleスプレッドシートとGAS実装

0
Posted at

この記事は、初回相談フォームの回答を、AI導入の優先度、注意点、人間確認の有無まで見える診断キューに変えるための実装メモです。

AI APIは呼びません。Googleフォームとスプレッドシート、Google Apps Scriptだけで、フォーム回答を「そのまま読むログ」から「次に確認するべき診断キュー」へ変換します。

作るもの

Googleフォームの回答シートから、次の2枚のシートを作ります。

  • consultation_responses: 初回相談フォーム回答
  • diagnosis_queue: AI導入診断キュー
  • diagnosis_rules: 判定ルール

完成形は、初回相談を受けたあとに、どの相談を先に見るか、どの情報はAIへ渡さないか、どの担当者が確認するかを小さく揃える台帳です。

Googleフォームとスプレッドシートで無料診断の受付ログを作る流れ

なぜ初回相談フォームを診断キューにするのか

AI導入相談の入口では、次のような回答が混ざります。

  • 問い合わせ対応を早くしたい
  • FAQを整えたい
  • 営業メモをCRMへ残したい
  • 予約や日程調整を自動化したい
  • 社内ナレッジを検索しやすくしたい
  • 個人情報や契約情報を含む可能性がある
  • そもそも何から始めるべきかわからない

フォーム回答をそのまま読むだけだと、担当者は毎回同じ判断をします。

  • これはどの業務領域か
  • AI化の前にフォームやFAQを直すべきか
  • 人間確認が必要な内容か
  • 個人情報や契約情報が混ざっていないか
  • 次に聞くべき質問は何か

診断キューを作る目的は、AIで自動回答することではありません。

初回相談を「読む」だけで終わらせず、導入順、確認者、注意点、次アクションへ分解することです。

consultation_responses シート

Googleフォームの回答シートは、例として次の列を想定します。

項目
A timestamp 2026/06/28 11:18
B response_id RES-20260628-001
C company_name 株式会社サンプル
D contact_email info@example.com
E business_area 問い合わせ対応
F current_tool Googleフォームとスプレッドシート
G monthly_volume 80
H pain_point 返信漏れとFAQ不足
I contains_sensitive いいえ
J desired_outcome まず問い合わせを整理したい
K free_text 料金や導入手順の質問が多い

ここで重要なのは、自由記述だけに頼らないことです。

月間件数、業務領域、現在の管理方法、センシティブ情報の有無を分けておくと、AI導入前の優先度を機械的に見やすくできます。

diagnosis_rules シート

判定ルールは、スプレッドシート上で編集できるようにします。

rule_key field match_type keyword score risk_flag next_action
inquiry_area business_area contains 問い合わせ 3 false FAQ候補と返信下書き条件を確認
high_volume monthly_volume gte 50 2 false 月間件数が多いため優先確認
sensitive contains_sensitive equals はい 0 true AI投入前に人間確認
contract_keyword free_text contains 契約 0 true 契約条件を含む可能性として確認
crm_tool current_tool contains CRM 1 false CRM項目とステータスを確認

ルールは複雑でなくて構いません。

最初はキーワード、数値しきい値、危険フラグだけで十分です。

diagnosis_queue シート

GASで生成する診断キューです。

項目
created_at 2026/06/28 11:20
diagnosis_id DIA-20260628-001
source_response_id RES-20260628-001
priority_score 5
workflow_area 問い合わせ対応
risk_level low
human_review_required false
suggested_first_step FAQ候補ログと問い合わせ分類を作る
reviewer operations_owner
status waiting_review
decision_note 月間件数が多く、問い合わせ対応が主課題

診断キューは、営業管理のためだけではなく、AI導入前の整理にも使います。

どの相談を先に見るかだけでなく、どこまでAIに任せてよいかを判断する入口になります。

GASコード

次のコードは、フォーム回答から診断キューを作る最小実装です。

const SHEETS = {
  responses: 'consultation_responses',
  rules: 'diagnosis_rules',
  queue: 'diagnosis_queue',
};

function buildDiagnosisQueue() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const responseSheet = ss.getSheetByName(SHEETS.responses);
  const rulesSheet = ss.getSheetByName(SHEETS.rules);
  const queueSheet = getOrCreateSheet_(ss, SHEETS.queue);

  const responses = readObjects_(responseSheet);
  const rules = readObjects_(rulesSheet);
  const existingIds = getExistingSourceIds_(queueSheet);
  const now = new Date();
  const output = [];

  responses.forEach((response) => {
    if (!response.response_id || existingIds.has(String(response.response_id))) {
      return;
    }

    const diagnosis = evaluateResponse_(response, rules, now);
    output.push(toQueueRow_(diagnosis));
  });

  if (queueSheet.getLastRow() === 0) {
    queueSheet.appendRow([
      'created_at',
      'diagnosis_id',
      'source_response_id',
      'priority_score',
      'workflow_area',
      'risk_level',
      'human_review_required',
      'suggested_first_step',
      'reviewer',
      'status',
      'decision_note',
    ]);
  }

  if (output.length > 0) {
    queueSheet
      .getRange(queueSheet.getLastRow() + 1, 1, output.length, output[0].length)
      .setValues(output);
  }
}

function evaluateResponse_(response, rules, now) {
  const matchedRules = rules.filter((rule) => matchesRule_(response, rule));
  const score = matchedRules.reduce((sum, rule) => sum + Number(rule.score || 0), 0);
  const hasRisk = matchedRules.some((rule) => String(rule.risk_flag).toLowerCase() === 'true');
  const workflowArea = response.business_area || '未分類';

  return {
    createdAt: now,
    diagnosisId: buildDiagnosisId_(now, response.response_id),
    sourceResponseId: response.response_id,
    priorityScore: score,
    workflowArea,
    riskLevel: hasRisk ? 'needs_review' : score >= 4 ? 'medium' : 'low',
    humanReviewRequired: hasRisk,
    suggestedFirstStep: buildFirstStep_(response, matchedRules, hasRisk),
    reviewer: hasRisk ? 'operations_owner' : 'cs_owner',
    status: 'waiting_review',
    decisionNote: matchedRules.map((rule) => rule.next_action).filter(Boolean).join(' / '),
  };
}

function matchesRule_(response, rule) {
  const field = String(rule.field || '');
  const value = response[field];
  const keyword = String(rule.keyword || '');
  const matchType = String(rule.match_type || 'contains');

  if (matchType === 'contains') {
    return String(value || '').includes(keyword);
  }

  if (matchType === 'equals') {
    return String(value || '') === keyword;
  }

  if (matchType === 'gte') {
    return Number(value || 0) >= Number(keyword || 0);
  }

  return false;
}

function buildFirstStep_(response, matchedRules, hasRisk) {
  if (hasRisk) {
    return 'AI投入前にセンシティブ情報と人間確認条件を確認する';
  }

  const area = String(response.business_area || '');

  if (area.includes('問い合わせ')) {
    return '問い合わせ分類、FAQ候補、人間確認ルールを作る';
  }

  if (area.includes('営業') || area.includes('CRM')) {
    return 'CRM項目、ステータス、送信抑止リストを確認する';
  }

  if (matchedRules.length === 0) {
    return '業務領域と導入目的を追加ヒアリングする';
  }

  return '業務棚卸しと自動化しない範囲を確認する';
}

function toQueueRow_(diagnosis) {
  return [
    diagnosis.createdAt,
    diagnosis.diagnosisId,
    diagnosis.sourceResponseId,
    diagnosis.priorityScore,
    diagnosis.workflowArea,
    diagnosis.riskLevel,
    diagnosis.humanReviewRequired,
    diagnosis.suggestedFirstStep,
    diagnosis.reviewer,
    diagnosis.status,
    diagnosis.decisionNote,
  ];
}

function readObjects_(sheet) {
  const values = sheet.getDataRange().getValues();
  const headers = values.shift().map((header) => String(header).trim());
  return values
    .filter((row) => row.some((cell) => cell !== ''))
    .map((row) => Object.fromEntries(headers.map((key, index) => [key, row[index]])));
}

function getExistingSourceIds_(sheet) {
  if (sheet.getLastRow() < 2) return new Set();
  const values = sheet.getRange(2, 3, sheet.getLastRow() - 1, 1).getValues();
  return new Set(values.map((row) => String(row[0])));
}

function buildDiagnosisId_(date, responseId) {
  const ymd = Utilities.formatDate(date, 'Asia/Tokyo', 'yyyyMMdd');
  const suffix = String(responseId).replace(/[^0-9A-Za-z]/g, '').slice(-6);
  return `DIA-${ymd}-${suffix}`;
}

function getOrCreateSheet_(ss, name) {
  return ss.getSheetByName(name) || ss.insertSheet(name);
}

サンプルルール

diagnosis_rules は、最初は次のような内容で始められます。

rule_key,field,match_type,keyword,score,risk_flag,next_action
inquiry_area,business_area,contains,問い合わせ,3,false,FAQ候補と返信下書き条件を確認
high_volume,monthly_volume,gte,50,2,false,月間件数が多いため優先確認
sensitive,contains_sensitive,equals,はい,0,true,AI投入前に人間確認
contract_keyword,free_text,contains,契約,0,true,契約条件を含む可能性として確認
crm_tool,current_tool,contains,CRM,1,false,CRM項目とステータスを確認

診断キューで見るべき項目

診断キューができたら、次の順に見ます。

観点 見ること
human_review_required AIへ渡す前に人間確認が必要か
priority_score 先に対応すべき相談か
workflow_area 問い合わせ、CRM、FAQ、営業などの領域
suggested_first_step どの台帳やルールから作るか
decision_note なぜその判断になったか

スコアは厳密な評価ではありません。

担当者が最初に見る順番と、確認漏れを減らすための並び替えに使います。

AIへ送らない情報を先に分ける

初回相談フォームは、個人情報や契約情報が混ざりやすい入口です。

診断キューをAI下書きや要約に使う場合でも、次の情報は本文投入の前に分けます。

  • 氏名、メールアドレス、電話番号
  • 契約番号、請求、返金、解約に関する具体情報
  • 顧客固有の内部事情
  • 法務、医療、税務など専門判断に近い相談
  • 秘密情報、APIキー、パスワード、認証情報

今回のGASは、外部API送信をしません。

AI連携を後から足す場合も、診断キューの human_review_requiredrisk_level を見て、安全側に倒す設計にします。

運用チェックリスト

公開や社外送信の前に、次を確認します。

  • フォーム回答に response_id がある
  • 連絡先項目と相談本文が分かれている
  • センシティブ情報の有無を選択式で聞いている
  • 診断ルールを人間が編集できる場所に置いている
  • 未分類の相談を自動処理へ流していない
  • 診断キューに確認担当と次アクションが残っている
  • AIへ送らない情報を先に分けている

ここでは自動化しないこと

この記事の実装では、次のことはしません。

  • AI APIへフォーム本文を送る
  • 顧客へ自動返信する
  • 契約、返金、法務、医療、税務に関する判断を自動化する
  • 個人情報を含む自由記述をそのまま外部サービスへ送る
  • スコアだけで受注確度や売上を断定する

初回相談フォームの目的は、AIで即時回答することではありません。

AI導入前に、どの業務から整えるべきか、どこで人間が確認すべきかを見える状態にすることです。

まとめ

初回相談フォームは、受け付けるだけでなく、AI導入診断キューへ変換できます。

  • フォーム回答に業務領域、件数、注意情報を分けて持たせる
  • diagnosis_rules でスコアとリスクを判定する
  • diagnosis_queue に優先度、確認担当、次アクションを残す
  • センシティブ情報や契約系の相談はAI投入前に止める
  • AI導入は、ツール選定より先に入口の整理から始める

Miraigentでは、問い合わせフォーム、FAQ、CRM、人間確認ルールをまとめて見直し、AI導入前の無料診断として整理しています。


Miraigentの公開リソース

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?