Back to blog
実装ガイド·May 25, 2026·8 min read

日本語 RAG チャットボットを Claude で構築 — 5,000 文書のナレッジベースを 30 行で

社内ドキュメント 5,000 件を Claude Sonnet 4.6 で検索可能にする RAG 完全実装。埋め込みコスト $0.25、1 クエリ約 0.9 円(prompt caching 適用後)。日本語特有のトークン消費・ハルシネーション対策・本番投入チェックリスト含む。

社内ナレッジベースを Claude で検索可能にする RAG チャットボットの作り方を、 日本語ドキュメント 5,000 件規模で実装する完全例。コード約 30 行 + 月額運用コスト の見積もりまで含めて公開します。

全体像

  1. ドキュメントを埋め込みベクトル化(text-embedding-3-large)
  2. ユーザー質問を同じモデルでベクトル化、上位 5 件を検索
  3. 取得した context を Claude Sonnet 4.6 に投げて回答生成
  4. Prompt caching で再呼び出しコスト 90% 削減

1) ドキュメントを埋め込む(一回だけ)

embed.py
# 1) 5,000 件の社内文書を埋め込みベクトル化
from openai import OpenAI

client = OpenAI(
    api_key="sk-kunavo-...",
    base_url="https://api.kunavo.com/v1",
)

documents = load_documents()  # [{id, text, metadata}, ...]

# バッチ 100 件ずつで Gemini text-embedding を呼ぶ
batches = [documents[i:i+100] for i in range(0, len(documents), 100)]
all_vectors = []
for batch in batches:
    resp = client.embeddings.create(
        model="text-embedding-3-large",
        input=[d["text"] for d in batch],
    )
    all_vectors.extend(resp.data)

# Postgres + pgvector に保存(または Pinecone, Qdrant など)
save_to_vector_db(documents, all_vectors)

5,000 件 × 平均 500 トークンとして 250 万トークン。text-embedding-3-large は Kunavo で約 $0.10/1M tokenなので 5,000 件全部で約 $0.25。 この処理は一度だけ走らせて結果を pgvector に保存しておきます。

2) クエリ時の検索と回答生成

query.py
# 2) ユーザー質問 → 関連文書を検索 → Claude に投げて回答
def answer(question: str) -> str:
    # 質問を埋め込み化
    q_embed = client.embeddings.create(
        model="text-embedding-3-large",
        input=[question],
    ).data[0].embedding

    # 上位 5 件を検索
    relevant = vector_search(q_embed, top_k=5)

    # Claude に context + question を渡す
    context = "\n\n---\n\n".join(d["text"] for d in relevant)
    resp = client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[
            {
                "role": "system",
                "content": (
                    "あなたは社内ナレッジ ベースをもとに正確に答えるアシスタントです。"
                    "提供された context にない情報については「情報がありません」と答えてください。"
                ),
            },
            {"role": "user", "content": f"# Context\n{context}\n\n# 質問\n{question}"},
        ],
        max_tokens=800,
    )
    return resp.choices[0].message.content

各クエリで使うトークン:質問の埋め込み (~$0.000005) + Claude Sonnet 4.6 の input 約 5K トークン (context) × $2.10/1M = $0.0105 + output 約 500 トークン × $10.50/1M = $0.005。1 クエリあたり 約 $0.016(約 2.4 円)

3) Prompt caching でさらに削減

同じシステムプロンプトを毎回送るので Anthropic prompt caching が効きます:

cache.py
# 3) Cache_control で再呼び出しコストを 90% 削減
# 同じ context(社内ドキュメント)を何度も使うので、Anthropic prompt caching が効く

resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {
            "role": "system",
            "content": [{
                "type": "text",
                "text": SYSTEM_PROMPT_AND_GUIDELINES,  # 安定したシステムプロンプト
                "cache_control": {"type": "ephemeral"},
            }],
        },
        {"role": "user", "content": f"# Context\n{context}\n\n# 質問\n{question}"},
    ],
)
# 2回目以降の同じシステムプロンプトはキャッシュヒット → 入力料金の 10%

システムプロンプトが 3,000 トークン安定して同じなら、2回目以降は その部分の input が 10% の料金で計算されます。 実測で 1 クエリあたり 約 $0.006(約 0.9 円) まで下がります。

月間運用コストの見積もり

使用量コスト備考
初期埋め込み$0.25一回限り
1,000 クエリ/日約 $180/月caching なし
1,000 クエリ/日約 $54/月caching あり
10,000 クエリ/日約 $540/月caching あり、Slack ボット規模

日本語ならではの注意点

  • トークン消費:日本語は英語の 2-3 倍のトークンを消費する ことがあります(漢字や仮名のエンコーディング上の理由)。 context を 5K → 3K に絞り、検索精度で勝負しましょう
  • 埋め込みモデル:text-embedding-3-large は多言語対応で 日本語精度も十分。社内用語が多い場合は同義語辞書を別途持つことを推奨
  • Claude vs Gemini 3 Pro:長文要約・引用に厳密なのは Claude、 検索の幅が広いのは Gemini 3 Pro。Sonnet 4.6 から始めて、必要に応じて Opus 4.7 にエスカレートするのが定石
  • ハルシネーション対策:「context にない場合は『情報がない』と 答える」をシステムプロンプトで明示。それでも漏れる場合は max_tokens を絞り、 引用元の文書 ID を返させて UI で出典リンクを表示

本番投入のチェックリスト

  • 埋め込みインデックスの更新フロー(cron で日次・週次再構築)
  • 失敗時のフォールバック(Claude → Gemini 3 Flash など 2 段構え)
  • レート制限とコスト上限(/app/keys でキー毎に日次 $50 などキャップ)
  • ログとモニタリング(usage ダッシュボードで日次コスト追跡)
  • 特定商取引法(日本のお客様向け) — /legal/tokutei-shoutorihiki

始めるには 無料登録で $2 のクレジットを受け取り、 詳細は /docs/quickstart /docs/caching を参照してください。