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 EngineでFAQ500件を扱うなら、検索索引とChat枠をどう分けるか

0
Posted at

Abstract FAQ retrieval and chat budget diagram

2026年9月28日時点の設計案。FAQを500件まで増やすとき、全件を毎回LLMへ渡す方式では、根拠の特定、更新、品質検証が難しくなる。先に検索対象を絞り、Chat APIには候補と質問だけを渡す構成を考える。

対象は問い合わせ回答の検索基盤を設計するエンジニアとテックリード。500件は設計上の想定件数であり、500件の索引構築、さくらのAI Engineへの送信、月間利用量の実測は行っていない。 以下のコードは小さな架空データでローカル確認した構成例である。

最初に決める境界は「無償のChat」と「保管を伴うRAG」

さくらのAI Engineの利用手順では、基盤モデル無償プランのチャット補完は月3,000リクエスト、ベクトル埋め込みは月10,000リクエストと案内されている。ただし、サービス基本情報は、無償プランでもRAGのドキュメント保管は課金対象と明記している。操作ガイドもドキュメントのベクトル化と保管に料金が発生すると説明する。「Chatが月3,000回まで無償」から「FAQ500件をアップロードしても無償」とは推論できない。

そこで、予算と実測がない段階ではFAQ索引をローカルに置き、API呼び出しをチャット補完に限定する設計を選ぶ。これはAPIのRAG機能を否定する判断ではない。検索品質、更新工数、データ配置、保管料金を測った後で比較し直せるよう、検索結果の入出力を分離しておく。

方式 利点 判断前に確認すること
毎回FAQ全件をプロンプトへ投入 試作が速い 入力長、根拠の追跡、更新時の再現性
AI Engineのドキュメント・RAG API 登録から検索・回答までAPIで扱える 保管・埋め込み料金、削除運用、検索品質
ローカル索引+Chat API FAQ保管を手元で管理し、候補だけ送れる 日本語検索の漏れ、索引の保守、送信データの審査

FAQ索引は何を検索し、何を残すか

FAQの正本には、少なくともfaq_id、質問、承認済み回答、根拠URLまたは文書ID、更新日時、管理者を持たせる。索引は正本から再生成できる派生物とする。古いFAQや承認状態が不明なFAQは、検索結果に出ても回答候補としては採用しない。

日本語の短い語句を含むFAQを探す試作には、SQLiteのFTS5 trigram tokenizerを選べる。3文字連続の部分文字列を索引化する方式なので、形態素解析を別途導入せずに候補を拾える。ただし2文字以下の検索語、言い換え、意味の近さはこの索引だけでは解決しない。ここをLLMの推測で埋めず、候補なし・曖昧として扱う。

import sqlite3

db = sqlite3.connect(":memory:")
db.execute("CREATE VIRTUAL TABLE faq USING fts5(id UNINDEXED, question, answer, tokenize='trigram')")
db.executemany(
    "INSERT INTO faq (id, question, answer) VALUES (?, ?, ?)",
    [
        ("F001", "契約変更の手続き", "管理画面から申請する"),
        ("F002", "請求書の発行", "履歴画面から取得する"),
    ],
)

# 例: 実運用では質問から安全に取り出した3文字以上の検索語を渡す。
term = "契約変更"
phrase = '"' + term.replace('"', '""') + '"'
rows = db.execute(
    "SELECT id, question, answer FROM faq WHERE faq MATCH ? ORDER BY rank LIMIT 3",
    (phrase,),
).fetchall()
assert rows[0][0] == "F001"

このコードは索引方式の最小例であり、FAQ500件の性能や自然文検索の精度を示すベンチマークではない。実運用では正本との同期、更新日時と根拠の結合、アクセス制御を追加する。日本語の表記揺れで候補が出ない場合に備え、別名辞書や検索方式の比較を評価データで判断する。

Chat枠は「使い切る」より、比較可能な検証に割り当てる

APIへ渡すのは質問と採用可能なFAQ候補のみとし、faq_idと根拠を出力に残す。候補がない、複数候補が矛盾する、更新期限を過ぎた場合は、回答を確定せず人間確認へ送る。モデルの自己申告する確信度だけで自動承認しない。

月間の残枠はアカウントのコントロールパネルで確認する。ここでは実残数を知らないため、呼び出し予算は次のように上限式で管理する。

評価用 = 評価質問数 × プロンプト候補数 × 再評価回数
必要枠 = 評価用 + 試験運用枠 + リトライ上限 + 予備枠
必要枠 <= 当月の実残枠

例えば50問を2案・3回で比較すれば評価用は300リクエスト。これは配分の計算例で、実際に300回呼び出した記録ではない。繰り返しが必要な評価セットを固定し、回答の文字面だけでなく、根拠の一致、誤った断定、回答保留、人間修正の理由を記録する。残枠の消費そのものを成果にしない。

本番前に止めるべき失敗

失敗 停止・確認条件 記録するもの
検索漏れ 正解FAQが上位候補にない 質問ID、期待FAQ ID、検索語、索引版
根拠のない回答 候補FAQにない事実を生成 質問ID、候補ID、判定理由。本文は必要最小限
古いFAQの採用 更新期限超過、根拠の失効 FAQ ID、更新日時、管理者
APIの429・一時障害 回数と待機時間を限定して再試行 HTTP状態、試行回数、最終状態
認証エラー・候補の矛盾 自動再試行や自動回答を停止 エラー種別、人間確認の結果

Inference API仕様には401、429、500、504などの応答が記載されている。無制限リトライは枠と処理時間を浪費するため、受付IDで再送を識別し、上限を超えたら人間確認に戻す。認証情報や問い合わせ本文を無制限にログへ残さず、評価用データは匿名化して保存する。

運用指標は、検索の正解FAQ上位到達率、根拠なし回答率、人間確認率、FAQ更新から索引反映までの時間、1件当たりAPI呼び出し回数とする。導入による確認時間短縮や費用対効果は、実測前に数値化しない。

次は公開可能な架空FAQで評価質問を用意し、検索漏れと回答保留を先に測る。必要性が確認できれば、ローカル索引とAI Engineのドキュメント・RAG APIを同じ評価セットで比較する。ここまで検証してからFAQ500件への拡張を判断する。

同様の仕組みの設計・構築・運用については相談可能。

この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表 / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。

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?