WordPressのAI FAQチャットボットは、公開済み記事だけを検索し、回答と同時に検証できる出典リンクを返す構成から始めます。ブラウザーからモデルAPIへ直接接続せず、サーバー側ゲートウェイで入力制限、検索、生成、出典、レート制限を扱います。答えがないときは推測せず、問い合わせ先へ戻します。
この記事は、公開判断に必要な構成、インターフェース契約、テスト、運用を決める導入設計です。コピーだけで動くWordPressプラグインやゲートウェイの完成実装は提供しません。記事収集・削除同期の実装はWordPressサイトをRAG化する方法へ分け、ここではFAQ画面から安全なフォールバックまでの責任分界を扱います。医療・法律・金銭判断、個別契約、アカウント操作など高リスク用途は、FAQボットだけで完結させないでください。
情報確認日:2026年8月17日(日本時間)
FAQボットは8段階で小さく公開する
公開までの順序
- 目的:減らしたい繰り返し質問と、答えない質問を決める
- 出典:公開済み正規記事だけを許可リストにする
- 同期:REST APIから必要フィールドを取得し、削除・非公開も反映する
- 検索:質問に近い公開チャンクを選び、アクセス境界を守る
- 生成:取得根拠だけで回答し、不明なら拒否する
- 表示:回答、出典、更新日、問い合わせ導線を安全に描画する
- ステージング:通常・答えなし・攻撃・障害ケースを評価する
- 運用:未回答、誤回答、更新遅延、停止・ロールバックを監視する
| 完成条件 | 非対象 |
|---|---|
| 公開記事の根拠と正規URLを回答ごとに示す | 非公開FAQ・顧客別回答 |
| 記事にない質問を「確認できない」と返す | あらゆる質問へ答える汎用チャット |
| 問い合わせ・人による確認へ一操作で移れる | 人のサポートを完全に廃止する |
| ウィジェットを即時停止して通常ページへ戻せる | モデルが常に正しいという保証 |
AI FAQチャットボットが向くサイトは?
- 同じ基本質問が繰り返され、回答が公開記事に明記されている
- 料金、仕様、手順、ポリシーの正本URLと更新担当者がある
- 出典リンクを開けば利用者が自分で確認できる
- 答えがない場合の問い合わせ先とレスポンス時間が決まっている
- 公開前・更新後にテストする担当者がいる
記事が古い、同じ質問に複数の矛盾した回答がある、問い合わせ先がない場合は、ボットより先に正本を整えます。AIは出典の不備を解消せず、見つけた不備を流暢に拡大する可能性があります。検索して根拠を渡す仕組みそのものが初めてなら、先にRAGとは何かで全体像を押さえておくと、この先の構成図が読みやすくなります。
AI FAQチャットボットが向かない質問は?
| 質問 | ボットの処理 | 次の窓口 |
|---|---|---|
| 注文・契約・アカウント | 個別データを聞かず案内を止める | 認証済みサポート |
| 医療・法律・金銭判断 | 一般情報の範囲を示し断定しない | 資格を持つ専門家 |
| 緊急・安全 | 通常FAQを続けず緊急案内へ | 地域の緊急窓口 |
| 公開記事に根拠なし | 推測せず「確認できない」 | 問い合わせページ |
| 記事同士が矛盾 | 新しいほうを勝手に選ばず停止 | コンテンツ担当者 |
全体構成はどうする?
公開WordPress記事
↓ REST API / scheduled sync
normalize → chunk → embedding → public-only index
↑
visitor → accessible widget → same-origin WordPress endpoint
↓
server-side FAQ gateway
validate / rate limit / retrieve
↓
local or approved model
↓
answer + sources + fallback + request ID
モデル提供元がローカルでもクラウドでも、ブラウザーへ機密情報を置きません。WordPress側の同一オリジンのエンドポイントはリクエストを受け、サーバー側で承認済みゲートウェイへ渡します。ゲートウェイだけがモデルの認証情報やローカル実行環境へ接続します。
避ける構成:テーマのJavaScriptへモデルAPIキーを埋め込む、ブラウザーから認証なしのOllama・LM Studioへ直接接続する、WordPressデータベースをLLMへ直接クエリさせる、LLM出力をinnerHTMLへそのまま入れる構成は採用しません。
出典ポリシーを最初に固定する
| 対象 | 採否 | 理由 |
|---|---|---|
| 公開済み投稿・ページ | 条件付きで採用 | 正規、担当者、更新日、公開範囲を確認 |
| 下書き・承認待ち・予約投稿 | 不採用 | 公開前の情報 |
| 非公開・パスワード protected | 不採用 | 公開FAQのアクセス境界外 |
| 仕様リビジョン・自動保存 | 不採用 | 正本ではない |
| コメント・フォーム・注文・ユーザーメタ情報 | 不採用 | 個人情報・信頼できないコンテンツを含み得る |
| 外部サイト | 原則不採用 | 更新・利用条件・提供状況を管理できない |
出典ポリシーはコードと運用文書の両方に置きます。「今は公開情報しかないから大丈夫」ではなく、将来追加される投稿タイプやプラグインデータが自動で混ざらない許可リストにします。
WordPress REST APIで何を取得する?
WordPressの公開投稿エンドポイントはGET /wp/v2/postsです。公開FAQに必要なフィールドだけを_fieldsで取得します。
curl -sS -D headers.txt \
"https://example.com/wp-json/wp/v2/posts?context=view&status=publish&per_page=100&page=1&orderby=modified&order=asc&_fields=id,link,slug,modified_gmt,title.rendered,content.rendered"
status=publishを明示し、認証が必要なcontext=editを使いません。ページも対象にする場合は、同じポリシーで/wp/v2/pagesを別に取得します。カスタム投稿タイプは、その種別がRESTへ公開され、出典ポリシーで承認された場合だけ追加します。
REST取得項目の契約表
| フィールド | 用途 | 保存・検証 |
|---|---|---|
id |
更新・削除の照合キー | 投稿タイプと組み合わせて一意化 |
link |
出典の正規候補 | 同一origin、HTTPS、200、正規を確認 |
slug |
運用時の識別 | リダイレクト・変更履歴を記録 |
modified_gmt |
再インデックスと更新表示 | timezoneをGMTへ統一 |
title.rendered |
検索・出典 title | HTML エンティティを安全にdecode |
content.rendered |
本文の正規化元 | ナビゲーション、script、フォームを除外 |
author、コメント、meta、media、プラグイン独自フィールドを「念のため」取得しません。WordPress公式資料も、_fieldsで必要なフィールドへ絞るとレスポンスと不要な処理を小さくできると説明しています。
100件を超える記事はどう同期する?
REST コレクションのper_pageは最大100です。レスポンスヘッダーのX-WP-TotalPagesを読み、1から最終ページまで取得します。
page=1を取得
↓ X-WP-TotalPagesを読む
page=2 ... last pageを取得
↓
全IDと保存中IDを照合
├─ new / modified → normalize・re-index
├─ unchanged → keep
└─ missing → index・cache・citation registryから削除
modified_afterによる差分取得だけでは、削除・非公開化された投稿がレスポンスに現れません。定期的な全IDの照合を行い、公開対象から消えたIDをインデックスと出典レジストリから削除します。詳細な収集・削除設計はWordPressサイトをRAG化する方法へ分けています。
本文をどう正規化する?
- WordPressが返した生成済みHTMLをDOMパーサーで読む
- script、style、フォーム、ボタン、ナビゲーション、広告、関連記事を除く
- 見出し、段落、一覧、表の意味を保ってテキスト化する
- HTML エンティティと空白を正規化する
- shortcodeの残骸、追跡 パラメーター、重複ブロックを除く
- 投稿ID、タイトル、URL、更新、セクション見出しをチャンクへ付ける
正規表現だけで複雑なHTMLを除去すると、表や見出しの関係を壊しやすくなります。実際のテーマ・プラグイン出力をテスト用データとして保存し、パーサーの回帰テストを作ります。
検索インデックスをpublic-onlyに保つ
FAQボット専用のインデックスを作り、社内資料、顧客データ、管理者向けmemoと共有しません。コレクション名が同じでメタデータ フィルターを忘れる事故を避けるため、機密区分が異なるデータは物理・論理的に分離します。
- インデックス作成時に
visibility=publicを固定する - 出典レジストリにWordPress 投稿タイプ・ID・ステータス・URLを持つ
- クエリ時にも公開 コレクションだけを指定する
- 削除後に検索hitと引用の両方から消えたことをテストする
回答プロンプトには何を要求する?
役割: このsiteの公開FAQ案内
根拠: supplied contextだけを使う
不明: 根拠が不足・矛盾する場合は「公開記事では確認できません」と答える
個別data: 注文番号、氏名、mail、健康・契約情報を求めない
出典: claimごとにsource IDを示す
action: tool、mail、database、WordPress更新を実行しない
着地: source linkまたは問い合わせ先を案内する
「必ず回答する」より「答えない条件」を具体化します。システムプロンプトだけをセキュリティ境界にせず、検索コレクション、出力スキーマ、ゲートウェイ検証、UI描画でも制限します。
返却JSONの契約を固定する
{
"answer": "公開記事では、返品申請は到着後7日以内と案内されています。",
"grounded": true,
"sources": [
{
"title": "返品・交換ポリシー",
"url": "https://example.com/returns/",
"modifiedAt": "2026-08-01T03:00:00Z"
}
],
"fallback": {
"required": false,
"label": "問い合わせる",
"url": "https://example.com/contact/"
},
"requestId": "faq_01J..."
}
記事に根拠がない場合はgrounded=false、sources=[]、fallback.required=trueにします。HTTP 200で返すアプリケーション上の「答えなし」と、ゲートウェイ障害の5xxを分けます。
出典URLをモデルに自由生成させない
モデルには出典IDを書かせ、ゲートウェイが検索結果のレジストリからtitle、正規URL、更新を引き直します。未知ID、同一origin外、非HTTPS、公開対象外のURLは捨てます。
出典UIの詳細、主張との対応、存在しないURLを防ぐ実装はRAGの引用・出典を正しく表示する方法で確認できます。
ブラウザーへAPIキーを置かない
公開ページのHTML・JavaScript・ソースマップ・ネットワークリクエストは利用者から見えます。モデルAPIキー、ローカル実行環境のトークン、ゲートウェイの管理認証情報を埋め込まないでください。
ブラウザーは同一オリジンのWordPressエンドポイントだけを呼びます。WordPressエンドポイントとゲートウェイ間はサーバー間通信を認証し、認証情報は環境変数やシークレット管理へ保存します。公開エンドポイント自体には、レート制限、本文サイズ、タイムアウト、不正利用の監視を適用します。
ウィジェットとエンドポイントのインターフェースをどう設計する?
テーマへ直書きせず、サイト固有のプラグインのshortcodeまたはブロックで、必要なページだけへ出します。次はUIとレスポンス契約を検討するための最小例です。
このコードだけでは動きません。/wp-json/site/v1/faqを登録し、入力検証、レート制限、認証済みゲートウェイ接続、レスポンススキーマ検証を行うサーバー側実装が別に必要です。エンドポイントを実装していないサイトへ貼ると404またはエラーになります。
<section class="faq-bot" aria-labelledby="faq-bot-title">
<h2 id="faq-bot-title">公開記事から質問する</h2>
<p>個人情報や注文番号は入力しないでください。回答はsourceで確認できます。</p>
<form id="faq-bot-form">
<label for="faq-question">質問</label>
<input id="faq-question" name="question" maxlength="500" required>
<button type="submit">質問する</button>
</form>
<div id="faq-answer" aria-live="polite"></div>
<ul id="faq-sources" aria-label="回答の参照元"></ul>
</section>
<script type="module">
const form = document.querySelector("#faq-bot-form");
const answer = document.querySelector("#faq-answer");
const sources = document.querySelector("#faq-sources");
form.addEventListener("submit", async (event) => {
event.preventDefault();
answer.textContent = "公開記事を確認しています…";
sources.replaceChildren();
const question = new FormData(form).get("question").toString().trim();
const response = await fetch("/wp-json/site/v1/faq", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ question })
});
if (!response.ok) {
answer.textContent = "現在回答できません。問い合わせページをご利用ください。";
return;
}
const data = await response.json();
answer.textContent = data.answer;
for (const source of data.sources ?? []) {
const url = new URL(source.url, location.origin);
if (url.origin !== location.origin || url.protocol !== "https:") continue;
const item = document.createElement("li");
const link = document.createElement("a");
link.href = url.href;
link.textContent = source.title;
item.append(link);
sources.append(item);
}
});
</script>
サンプルはインターフェースと安全な描画方法を示す設計例であり、動作検証済みウィジェットではありません。textContentとDOM APIを使い、モデルのHTMLを実行しない前提です。本番ではネットワーク エラー、タイムアウト、送信中の二重クリック、フォーカス移動、スクリーンリーダー、JavaScriptなしのフォールバック、プライバシーの注意書きも実装します。
WordPress RESTエンドポイントで何を検証する?
| 入力・処理 | ルール |
|---|---|
| Content-Type | application/jsonだけを受ける |
| question | string、1〜500文字、不正な UTF-8・対策文字を拒否 |
| 本文 | 小さな上限、未知フィールドを拒否 |
| レート | IPだけに依存せずセッション・ネットワーク・全体上限を組み合わせる |
| ゲートウェイ | 許可済みの固定URL、短いタイムアウト、retryなしまたは限定 |
| レスポンス | JSONスキーマ、回答長、出典件数、同一オリジンのURLを検証 |
| ログ | リクエストID、結果、遅延、出典IDを保存。本文は最小化 |
WordPress公式のセキュリティガイドは、入力を信頼せず検証・無害化し、出力時にコンテキストに合わせてエスケープするよう案内しています。LLM出力も外部APIやデータベースと同じ信頼できないデータです。
Prompt Injectionへどう備える?
公開記事や質問に「前の指示を無視して」と書かれても、ツール実行、機密情報取得、WordPress更新へ進めない構成にします。
- コメント、フォーム入力、外部ページをインデックスへ混ぜない
- 記事本文を指示ではなく引用データとして区切る
- モデル コンテキストへ機密情報・非公開データを入れない
- FAQボットにファイルシステム、メール、データベース 書き込み、MCP ツールを接続しない
- 出典IDとURLをアプリケーション側で検証する
- 攻撃文を含む記事テスト用データと質問を回帰テストへ入れる
OWASP 2025 LLM Top 10はPrompt Injection、Improper Output Handling、Excessive Agencyなどを挙げています。FAQという用途では、テキスト回答と公開された出典リンクだけに権限を絞ることが大きな対策です。
答えがないときの文面
推測しないフォールバック
公開記事では、この質問への回答を確認できませんでした。個人情報や注文番号はここへ入力せず、問い合わせページから担当者へご確認ください。
「分かりません」で行き止まりにせず、問い合わせURL、営業時間、通常のレスポンス目安を、公開中の正本から表示します。緊急時は通常問い合わせではなく、適切な緊急窓口へ分岐します。
ステージングでは何をテストする?
| ケース | 期待結果 |
|---|---|
| 単一記事で答えられる | 主張と出典が一致する |
| 複数記事が必要 | 条件を混同せず複数出典を示す |
| 言い換え・誤字 | 正しい記事を取得するか、無理ならフォールバック |
| 答えなし | 推測せず問い合わせへ |
| 矛盾する記事 | 片方を断定せずコンテンツ担当者へ |
| 削除・非公開記事 | 検索・出典候補に出ない |
| プロンプトインジェクション | 機密情報・ツール・未知URLを返さない |
| 500・タイムアウト | 通常ページと問い合わせ導線は使える |
| 長文・連打 | 上限とレート制限で安全に拒否 |
| キーボード・スクリーンリーダー | フォーム、ステータス、出典へ操作できる |
検索と回答を分けて測るデータセット設計はRAG評価のやり方を参照し、FAQ固有の問い合わせ分岐、プライバシー、アクセシビリティを追加します。
公開前チェックリスト
- 減らしたい質問と、ボットが答えない質問を定義した
- 出典は公開済み公開 投稿・ページの許可リストだけ
- 下書き、予約投稿、非公開、仕様リビジョン、コメント、フォーム、利用者 データを除外した
- REST取得フィールドをID、URL、更新日、title、本文へ絞った
- ページ分割と全IDの照合を実装した
- 削除・非公開化した記事がインデックスと引用から消える
- ブラウザーへモデル・ゲートウェイ 機密情報がない
- 公開エンドポイントに文字数、本文、レート、タイムアウト上限がある
- モデル出力をJSONスキーマでvalidateした
- 回答を
innerHTMLで直接描画していない - 出典URLをレジストリから解決し同一オリジン・HTTPSを確認した
- 答えなし・矛盾・高リスク質問で推測しない
- 問い合わせ、プライバシー、緊急窓口へのフォールバックがある
- 個人情報を入力しない注意がフォームの近くにある
- キーボード、フォーカス、aria-live、モバイル表示を確認した
- 障害時も記事閲覧と問い合わせを利用できる
- ステージングの通常・攻撃・削除・障害テストを通した
- ウィジェット・エンドポイント・同期を即時停止できる
- コンテンツ、システム、security、サポートの担当者がいる
公開後に何を測る?
| 指標 | 見る理由 | 誤解しないこと |
|---|---|---|
| 根拠あり回答率 | 出典付きで答えられた割合 | 高いほど正しいとは限らない |
| フォールバック率 | コンテンツ不足・対象範囲外を発見 | 無理に下げない |
| 出典クリック率 | 利用者が正本を確認したか | 低くても回答完結の場合がある |
| 問い合わせ移行 | 人が必要なケースを渡せたか | 問い合わせ0を目的にしない |
| 誤回答・訂正 | 重大な品質リスク | 平均満足度で相殺しない |
| p95 遅延・エラー | 利用可能性とコスト | 平均だけを見ない |
| 不正利用・レート拒否 | 攻撃・リソース枯渇 | IPだけで人を断定しない |
未加工の質問文を無期限に保存しません。個人情報が入力される前提で、本文を保存しない集計、短い保持、マスキング、アクセス制御を設計します。コンテンツ改善には、匿名化した話題・失敗理由・出典IDを使います。
記事更新をボット改善へつなげる
- フォールバックが多い質問を話題単位で集計する
- 本当にサイト 対象範囲内かコンテンツ担当者が判断する
- 必要なら既存記事の正本へ追記し、レビュー・公開する
- 同期後に新しい更新とチャンクが反映されたか確認する
- 元の失敗クエリと類似クエリを回帰テストへ追加する
ボット専用の非公開回答を増やすより、利用者も検索engineも確認できる公開記事を正本として改善します。個別回答が必要な質問は公開記事へ無理に一般化せず、サポートへ残します。
停止・ロールバック手順をどう作る?
- 機能フラグでウィジェットを非表示にし、記事と問い合わせは残す
- WordPressエンドポイントをメンテナンス用レスポンスへ切り替える
- 同期処理を止め、事故時の証拠を保全する
- モデル・インデックス・プロンプト・コードを直前の承認バージョンへ戻す
- 重大な誤回答出典と影響リクエストIDを特定する
- 必要な利用者・担当者へ通知し、修正後に全テストを再実行する
停止中に「AI FAQは使えません」とだけ表示せず、検索、主要FAQ、問い合わせページへの通常リンクを示します。
役割分担はどうする?
| 担当者 | 責任 |
|---|---|
| コンテンツ | 出典正本、更新、矛盾、公開範囲 |
| アプリケーション | REST同期、ゲートウェイ、スキーマ、ウィジェット、ロールバック |
| セキュリティ・プライバシー | 機密情報、レート、ログ、入力、障害対応、保持 |
| サポート | フォールバック、緊急分岐、レスポンス、コンテンツ不足 |
| 品質確認者 | データセット、出典一致、重大不適合、リリース判定 |
よくある質問
WordPressプラグインだけでAI FAQボットを作れますか?
製品によっては可能ですが、プラグインを入れるだけで出典ポリシー、誤回答、機密情報、レート制限、削除同期、問い合わせ、評価が自動的に完成するとは限りません。採用前に本文のチェックリストで実装範囲を確認してください。コードを書かずに試す選択肢はノーコードAIチャットボットの作り方に分けています。
WordPress REST APIを公開すると下書きも取得されますか?
未認証の投稿一覧は既定でpublishが対象です。FAQボットはcontext=viewとstatus=publishを明示し、必要フィールドだけを取得します。認証情報や編集用コンテキストを収集処理ジョブへ不用意に与えません。
FAQボットへ注文番号を入力してもらえますか?
この記事の公開記事限定ボットでは扱いません。注文・アカウント データは認証済みサポートへ分離し、公開フォームには個人情報を入力しない注意と安全な移動先を示します。
回答に出典があれば正しいですか?
出典URLが実在しても、主張を支持していない場合があります。出典IDをレジストリから解決し、主張との対応、更新日、矛盾、削除を評価します。
問い合わせ数が減れば成功ですか?
それだけでは判断できません。必要な問い合わせまで阻害していないか、誤回答・フォールバック・出典クリック・解決・利用者の負担を一緒に見ます。高リスク・個別ケースは人へ届くことが成功です。
FAQボットは出典付きで小さく公開する
WordPressのAI FAQチャットボットは、公開済み公開記事だけをREST APIから必要フィールドに絞って取得し、公開情報専用インデックスで検索し、回答と出典を返す設計から始めます。ブラウザーへ機密情報を置かず、サーバー側ゲートウェイで検証、レート制限、検索、スキーマを管理します。
記事にない質問、矛盾、個別データ、高リスク判断は推測せず、人の窓口へ戻します。削除・非公開の同期、出典の検証、アクセシビリティ、監視、停止・ロールバックまでを公開条件にすると、FAQボットは記事とサポートをつなぐ入口として安全に改善できます。