現代的なKBチャットボットのデフォルトアーキテクチャ
従来のKB検索はリンクを返し、ユーザーが読みます。RAGはそれを引用付きの一回の会話回答に変えます。うまく実装すれば、ユーザーは5つの文書を掘り下げる代わりに2秒で回答を得られます。失敗すれば、チャットボットは幻覚を起こし、CTOがプロジェクトを1年間禁止します。このページがその違いを説明します。
本番運用に必要な最小構成
- ベクトルストア: 既にPostgresがあるならpgvector、マネージドならPineconeまたはQdrant
- 埋め込み: text-embedding-3-largeをOpenAIに直接呼び出し — Kunavoは埋め込みを提供せず、どちらの場合も埋め込み呼び出しは生成呼び出しとは別のリクエストです
- 検索: ハイブリッド(ベクトル + BM25と逆順位融合)
- 生成: システムプロンプトでcache_controlを使用するClaude Sonnet 5
- UI: ストリーミング応答、引用表示、「わかりません」フォールバック
from openai import OpenAI
client = OpenAI(api_key="sk-kn-...", base_url="https://api.kunavo.com/v1")
def chat(question: str, history: list[dict]) -> dict:
chunks = hybrid_retrieve(question, k=5) # vector + BM25
context = "\n\n---\n\n".join(
f"[doc:{c['id']}] {c['text']}" for c in chunks
)
resp = client.chat.completions.create(
model="claude-sonnet-5",
messages=[
{"role": "system", "content": [{
"type": "text",
"text": (
"Answer only from Context. Cite [doc:N] for each claim. "
"If Context doesn't answer, say 'I don't have that.' "
"Be concise, no throat-clearing."
),
"cache_control": {"type": "ephemeral"},
}]},
*history,
{"role": "user", "content": f"# Context\n{context}\n\n# Q\n{question}"},
],
max_tokens=600,
)
answer = resp.choices[0].message.content
cited_ids = parse_citations(answer) # extract [doc:N] references
return {"answer": answer, "sources": [c for c in chunks if c["id"] in cited_ids]}本番規模でのコスト
- 初期インデックス作成: 500トークンの文書5,000件で約$0.25
- 1日1,000クエリ: キャッシュ使用時で月約$210
- 1日10,000クエリ: 月約$2,100
- Sonnetの代わりにHaiku 4.5を使用する場合: 約4倍安く、回答品質は約85%
アーキテクチャの詳細はRAG実装ガイドをご覧ください。言語別のチューニングに関する注意点は日本語RAG詳細解説とスペイン語RAGガイドにあります。
幻覚を実際に防ぐ3つのパターン
- すべての主張に引用を付ける: モデル出力内の
[doc:42]タグ。引用されたIDが検索結果セットにない場合は幻覚なので、ブロックしてログに記録する - システムプロンプトで明示的に拒否する: 「Contextに答えがない場合は、『わかりません』と言うこと。」これがないと、モデルは世界知識で補完します
- 出力上限を600トークンにする: 短い回答は通常、正確な回答です。余計な創作が入り込むのは、より長い出力です
第1週に提供するものと第4週に提供するもの
| 週 | マイルストーン |
|---|---|
| 1 | 文書100件、単一のチャンキング戦略、基本的なベクトル検索、10問の評価セット、recall@5約70% |
| 2 | 全文書コーパス、ハイブリッド検索、100問の評価セット、引用を強制、社内ベータ |
| 3 | 失敗した質問に基づいてチャンキングを調整し、社内ユーザーに提供、CSATを測定 |
| 4 | 監視 + コストダッシュボード、1日あたりの支出上限、パブリックベータまたは本番リリース |
/app/signupから開始
$10のチャージで、約10万文書の初期インデックス作成と1,500件のテストクエリをまかなえます。機能的なプロトタイプには十分以上で、残高は失効しません。その後、完全版RAGガイドで本番パターンを確認してください。
よくある質問
RAGチャットボットのクエリ1回あたりの費用はいくらですか?
Claude Sonnet 4.6でプロンプトキャッシュを有効にすると、クエリあたり約$0.007です。Claude Haiku 4.5では約$0.001で、コストは1/7ながら品質の約85%を得られます。
RAGチャットボットのハルシネーションを防ぐにはどうすればよいですか?
主に役立つ方法は3つあります。すべての主張に[doc:N]形式のIDを引用するようモデルに求める、システムプロンプトで明示的に回答を拒否するよう指示する、max_tokens=600で回答を制限することです。回答を表示する前に、引用されたすべてのIDが取得済みの集合に含まれているか確認してください。
RAGのインデックスでは、チャンクサイズをどの程度にすべきですか?
チャンクあたり1,000–1,500文字、オーバーラップ100–200文字にします。RecursiveCharacterTextSplitterで分割し、text-embedding-3-largeで埋め込みを生成してください。
RAGの検索にベクトル検索だけで十分ですか?
いいえ。ハイブリッド検索では、ベクトル類似度とBM25キーワード検索を組み合わせ、相互順位融合で結果を統合して上位5個のチャンクを取得します。