以 Claude 建立可搜尋內部知識庫的 RAG 聊天機器人完整實作範例,規模約 5,000 份日文文件。公開內容包含約 30 行程式碼,以及每月營運成本估算。
整體概觀
- 將文件轉換為嵌入向量(text-embedding-3-large)
- 使用相同模型將使用者問題轉換為向量,搜尋排名前 5 的結果
- 將取得的 context 傳給 Claude Sonnet 4.6 以產生回答
- 透過 Prompt caching 將重複呼叫成本降低 90%
1) 嵌入文件(只需一次)
# 1) 5,000 件の社内文書を埋め込みベクトル化
from openai import OpenAI
# 埋め込みは Kunavo では提供していません(/v1/embeddings は実装済みの
# ワイヤフォーマットですが、有効なモデルがないため呼ぶと失敗します)。
# 埋め込みは OpenAI に直接、生成は Kunavo に — クライアントは 2 つ持ちます。
embedder = OpenAI(api_key="sk-...") # OpenAI 本家
kunavo = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
documents = load_documents() # [{id, text, metadata}, ...]
# バッチ 100 件ずつで埋め込みを呼ぶ
batches = [documents[i:i+100] for i in range(0, len(documents), 100)]
all_vectors = []
for batch in batches:
resp = embedder.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 個 token 計算,共 250 萬個 token。由於 Kunavo 不提供嵌入服務,只有此步驟會直接向 OpenAI 計費——單價請在 OpenAI 定價頁面確認。這裡不寫數字,是因為替自己不販售的產品撰寫價格,即使過時也沒有人會注意。此處理只執行一次,並將結果儲存在 pgvector 中。
2) 查詢時的搜尋與回答生成
# 2) ユーザー質問 → 関連文書を検索 → Claude に投げて回答
def answer(question: str) -> str:
# 質問を埋め込み化
q_embed = embedder.embeddings.create( # 埋め込みは OpenAI 直
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 = kunavo.chat.completions.create( # 生成は Kunavo
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每次查詢使用的 token:問題嵌入(約 $0.000005)+ Claude Sonnet 4.6 的輸入約 5K token(context)× $1.20/1M = $0.006 + 輸出約 500 token × $6.00/1M = $0.003。每次查詢約 $0.009(約 1.4 日圓)。
3) 透過 Prompt caching 進一步降低成本
由於每次都會傳送相同的系統提示,因此 Anthropic prompt caching 會發揮作用:
# 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 個 token 且內容相同,從第二次起,該部分的輸入會按 10% 的價格計算。實測每次查詢可降至 約 $0.004(約 0.6 日圓)。
每月營運成本估算
| 用量 | 成本 | 備註 |
|---|---|---|
| 初始嵌入 | $0.25 | 一次性 |
| 每日 1,000 次查詢 | 約 $270/月 | 無 caching |
| 每日 1,000 次查詢 | 約 $110/月 | 有 caching |
| 每日 10,000 次查詢 | 約 $1,100/月 | 有 caching,Slack 機器人規模 |
日文特有的注意事項
- Token 消耗:日文有時會消耗英語 2–3 倍的 token(原因在於漢字與假名的編碼方式)。將 context 從 5K 縮減至 3K,以搜尋精準度取勝
- 嵌入模型:text-embedding-3-large 支援多語言,日文精準度也足夠。若內部術語很多,建議另外維護同義詞字典
- Claude 與 Gemini 2.5 Pro:Claude 更嚴謹於長文摘要與引用,Gemini 2.5 Pro 的搜尋範圍更廣。先從 Sonnet 4.6 開始,必要時升級至 Opus 4.7,是標準做法
- 防止幻覺:在系統提示中明確指示「若 context 中沒有,請回答『沒有相關資訊』」。若仍有遺漏,請縮小 max_tokens,並要求回傳來源文件 ID,再於 UI 中顯示來源連結
上線檢查清單
- 嵌入索引更新流程(透過 cron 每日、每週重建)
- 失敗時的備援方案(Claude → Gemini 2.5 Flash 等兩階段配置)
- 速率限制與成本上限(在 /app/keys 中為每個金鑰設定每日 $50 等上限)
- 日誌與監控(透過 usage 儀表板追蹤每日成本)
- 特定商取引法(適用於日本客戶)— /legal/tokutei-shoutorihiki
開始使用請先免費註冊。從 $10 起儲值,採隨用隨付方式開始使用;詳細資訊請參閱 /docs/quickstart 或 /docs/caching。