問い合わせログからFAQ候補を作っても、すぐに公開してはいけません。文章が読みやすくても、実際の問い合わせを解決できるか、例外時に人へ戻れるかは別の問題だからです。
この記事では、GoogleスプレッドシートとGoogle Apps Script(GAS)で、FAQ候補を 候補 → 検証中 → 承認 → 公開 と段階管理します。公開前に少数の再問い合わせで確認し、解決できなかった理由を記録してから昇格させる構成です。AI APIの呼び出し、FAQの自動公開、顧客への自動返信は扱いません。
作るもの
次の2シートを用意します。
FaqCandidates
| 列 | 内容 |
|---|---|
| candidate_id | FAQ候補の一意なID |
| source_case_ids | 候補の元になった問い合わせID |
| question_pattern | 質問の代表パターン |
| answer_draft | 回答案 |
| source_ref | 根拠文書のID・版 |
| status | 候補、検証中、承認、保留、公開 |
| owner | 確認担当者 |
| review_due_at | 検証期限 |
| reason_code | 保留・差し戻し理由 |
FaqValidationCases
| 列 | 内容 |
|---|---|
| validation_id | 検証ID |
| candidate_id | 対象FAQ候補 |
| case_type | 通常、境界、停止 |
| input_summary | テスト入力の要約(顧客本文そのものは保存しない) |
| result | 解決、追加確認、人間対応、未実施 |
| reviewer | 判定者 |
| note | 根拠と次の修正 |
ステータスを先に固定する
FAQ候補の公開可否を、文章の完成度だけで決めないようにします。
候補
└─ 検証中
├─ 通常・境界ケースが確認済み ─> 承認 ─> 公開
├─ 追加情報が必要 ─> 保留
└─ 根拠不明・例外が多い ─> 人間対応へ戻す
公開へ進める最低条件は、根拠の版が確認できること、通常ケースを確認済みであること、境界ケースで推測回答をしないこと、担当者が承認していることです。
GASで候補を検証キューへ登録する
候補IDごとに一度だけ検証行を作ります。重複登録を避けるため、candidate_id と case_type の組み合わせをキーにします。
const SHEETS = {
candidates: 'FaqCandidates',
cases: 'FaqValidationCases',
};
function enqueueFaqValidation(candidateId) {
const book = SpreadsheetApp.getActive();
const candidates = book.getSheetByName(SHEETS.candidates);
const cases = book.getSheetByName(SHEETS.cases);
const candidate = findById_(candidates, 'candidate_id', candidateId);
if (!candidate) throw new Error(`候補がありません: ${candidateId}`);
const existing = cases.getDataRange().getValues();
const keys = new Set(existing.slice(1).map(row => `${row[1]}:${row[2]}`));
const now = new Date();
const rows = ['通常', '境界', '停止']
.filter(type => !keys.has(`${candidateId}:${type}`))
.map(type => [
Utilities.getUuid(), candidateId, type, '', '未実施', '', '', now,
]);
if (rows.length > 0) {
cases.getRange(cases.getLastRow() + 1, 1, rows.length, rows[0].length)
.setValues(rows);
}
updateStatus_(candidates, 'candidate_id', candidateId, '検証中');
}
停止ケースは、根拠がない、個人情報の扱いが不明、契約・料金・期限に関係するなど、FAQが答えを推測してはいけない入力です。ここで「人間対応」へ戻ることを成功条件に含めます。
検証結果から昇格可否を判定する
自動判定で公開状態へ変更せず、条件を満たした候補を人間の承認一覧へ出します。
function canRequestApproval_(candidateId) {
const rows = readValidationRows_(candidateId);
if (rows.length !== 3) return false;
const byType = Object.fromEntries(rows.map(row => [row.caseType, row]));
const normalOk = byType['通常'].result === '解決';
const boundarySafe = ['追加確認', '人間対応'].includes(byType['境界'].result);
const stopSafe = byType['停止'].result === '人間対応';
return normalOk && boundarySafe && stopSafe && rows.every(row => row.reviewer);
}
この関数は承認依頼を出せるかだけを返します。公開、外部送信、FAQの正本更新は担当者が行います。answer_draft に根拠URLだけを残し、顧客本文や個人情報をテストデータとして複製しないでください。
運用チェックリスト
- 元になった問い合わせIDを追跡できる
- 根拠文書の版と確認日がある
- 通常・境界・停止の3ケースを作った
- 境界ケースで推測せず追加確認または人間対応に戻った
- 検証者と承認者が記録されている
-
保留理由が
根拠不明、情報不足などのコードで残っている - 公開後の再問い合わせを確認する期限を決めた
まとめ
FAQの候補化は、問い合わせログから文章を作る工程で終わりません。公開前に「実際に解決できたか」「危険な入力で止まれたか」を小さく検証し、その結果を承認へ戻すことで、FAQを更新可能な運用にできます。
Miraigentでは、AI導入を回答生成だけでなく、確認・保留・公開後の見直しまで含めた業務設計として整理しています。
