Şirket içi bilgi tabanını Claude ile aranabilir hâle getiren bir RAG sohbet botunun nasıl oluşturulacağını, 5.000 Japonca belge ölçeğinde uygulayan eksiksiz bir örnek sunuyoruz. Yaklaşık 30 satır kodun yanı sıra aylık işletim maliyeti tahminini de paylaşıyoruz.
Genel görünüm
- Belgeleri embedding vektörlerine dönüştürme (text-embedding-3-large)
- Kullanıcı sorusunu aynı modelle vektörleştirme ve en iyi 5 sonucu arama
- Alınan context'i Claude Sonnet 4.6'ya göndererek yanıt oluşturma
- Prompt caching ile yeniden çağırma maliyetini %90 azaltma
1) Belgeleri embedding'e dönüştürme (yalnızca bir kez)
# 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 belge × ortalama 500 token = 2,5 milyon token. Kunavo embedding sunmadığı için yalnızca bu aşama doğrudan OpenAI tarafından faturalandırılır—— birim fiyatı OpenAI'nin fiyatlandırma sayfasından kontrol edin. Burada sayı vermememizin nedeni, satmadığımız bir şeyin fiyatını yazarsak bu fiyat güncelliğini yitirdiğinde kimsenin bunu fark etmeyecek olmasıdır. Bu işlemi yalnızca bir kez çalıştırıp sonucu pgvector'a kaydedin.
2) Sorgu sırasında arama ve yanıt oluşturma
# 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.contentHer sorguda kullanılan token'lar: sorunun gömülmesi (~$0,000005) + Claude Sonnet 4.6 için yaklaşık 5K girdi token'ı (bağlam) × $1,20/1M = $0,006 + yaklaşık 500 çıktı token'ı × $6,00/1M = $0,003. Sorgu başına yaklaşık $0,009 (yaklaşık 1,4 yen).
3) Prompt caching ile daha da azaltma
Aynı sistem istemi her seferinde gönderildiğinden Anthropic prompt caching etkilidir:
# 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%Sistem istemi 3.000 token olarak sabit ve aynı kalıyorsa ikinci çağrıdan itibaren o bölümdeki girdi, ücretin %10'u üzerinden hesaplanır. Gerçek ölçümlerde sorgu başına maliyet yaklaşık $0,004 (yaklaşık 0,6 yen) seviyesine iner.
Aylık işletim maliyeti tahmini
| Kullanım miktarı | Maliyet | Not |
|---|---|---|
| İlk embedding | $0,25 | Tek seferlik |
| Günde 1.000 sorgu | Aylık yaklaşık $270 | caching yok |
| Günde 1.000 sorgu | Aylık yaklaşık $110 | caching var |
| Günde 10.000 sorgu | Aylık yaklaşık $1.100 | caching var, Slack botu ölçeği |
Japoncaya özgü dikkat noktaları
- Token tüketimi: Japonca, kodlama nedenleriyle (kanji ve kana) İngilizcenin 2-3 katı token tüketebilir. context'i 5K → 3K ile sınırlayın ve arama doğruluğuyla fark yaratın
- Embedding modeli: text-embedding-3-large çok dillidir ve Japonca doğruluğu yeterlidir. Kurum içi terimler fazlaysa ayrıca eş anlamlılar sözlüğü tutmanız önerilir
- Claude ve Gemini 2.5 Pro: Uzun özetleme ve alıntılarda daha titiz olan Claude'dur; arama kapsamı daha geniş olan Gemini 2.5 Pro'dur. Sonnet 4.6 ile başlayıp gerektiğinde Opus 4.7'ye yükseltmek standart yaklaşımdır
- Halüsinasyon önleme: “context'te yoksa 'bilgi yok' yanıtını ver” ifadesini sistem isteminde açıkça belirtin. Yine de sızıntı olursa max_tokens değerini azaltın ve kaynak belge kimliğini döndürmesini sağlayarak kaynak bağlantısını kullanıcı arayüzünde gösterin
Üretime alma kontrol listesi
- Embedding dizinini güncelleme akışı (cron ile günlük ve haftalık yeniden oluşturma)
- Hata durumunda geri dönüş (Claude → Gemini 2.5 Flash gibi iki aşamalı yapı)
- Hız sınırı ve maliyet üst sınırı (/app/keys bölümünde anahtar başına günlük $50 gibi limitler)
- Günlük maliyeti izlemek için günlükler ve izleme (usage panosu)
- Belirli ticari işlemler yasası (Japonya'daki müşteriler için) — /legal/tokutei-shoutorihiki
Başlamak için ücretsiz kaydolun. $10'dan başlayarak bakiye yükleyin ve kullandıkça ödeyin; ayrıntılar için /docs/quickstart veya /docs/caching sayfalarına bakın.