L’architecture moderne par défaut d’un chatbot de base de connaissances
La recherche traditionnelle dans une base de connaissances renvoie des liens que l’utilisateur doit lire. Le RAG transforme cela en une réponse conversationnelle immédiate avec citations. Bien conçu, il fournit des réponses en 2 secondes au lieu de faire parcourir 5 documents. Mal conçu, le chatbot hallucine et votre CTO interdit le projet pendant un an. Cette page explique la différence.
La stack de production minimale viable
- Vector store : pgvector si vous utilisez déjà Postgres, Pinecone ou Qdrant pour une solution gérée
- Embeddings : text-embedding-3-large, appelé directement auprès d’OpenAI — Kunavo ne fournit pas d’embeddings, et l’appel d’embedding est de toute façon distinct de l’appel de génération
- Retrieval : hybride (vecteur + BM25 avec fusion des rangs réciproques)
- Génération : Claude Sonnet 5 avec cache_control sur le prompt système
- UI : réponses en streaming, rendu des citations, solution de repli « Je ne sais pas »
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]}Coût à l’échelle de la production
- Indexation initiale : environ $0.25 pour 5 000 documents de 500 tokens chacun
- 1 000 requêtes/jour : environ $210/mois avec mise en cache
- 10 000 requêtes/jour : environ $2 100/mois
- Avec Haiku 4.5 au lieu de Sonnet : environ 4 fois moins cher, environ 85 % de la qualité des réponses
La décomposition complète de l’architecture se trouve dans le guide d’implémentation du RAG. Les notes d’optimisation par langue sont dans le guide approfondi du RAG japonais et le guide du RAG espagnol.
Les trois pratiques qui empêchent réellement les hallucinations
- Citez chaque affirmation : utilisez les balises
[doc:42]dans la sortie du modèle. Si l’identifiant cité n’appartient pas à l’ensemble récupéré, le modèle a halluciné — bloquez et journalisez - Refus explicite dans le prompt système : « Si le contexte ne permet pas de répondre, dites “Je n’ai pas cette information.” » Sans cela, le modèle complète avec ses connaissances générales
- Limite de sortie de 600 tokens : les réponses courtes sont généralement les plus exactes. Les inventions supplémentaires apparaissent surtout dans les sorties plus longues
À livrer en semaine 1 contre semaine 4
| Semaine | Jalon |
|---|---|
| 1 | 100 documents, une stratégie de segmentation, recherche vectorielle de base, jeu d’évaluation de 10 questions, rappel@5 d’environ 70 % |
| 2 | Corpus complet, recherche hybride, jeu d’évaluation de 100 questions, citations obligatoires, bêta interne |
| 3 | Ajuster la segmentation selon les questions échouées, déployer auprès des utilisateurs internes, mesurer le CSAT |
| 4 | Suivi et tableau de bord des coûts, plafond quotidien des dépenses, bêta publique ou lancement en production |
Commencez à /app/signup
Une recharge de $10 couvre l’indexation initiale d’environ 100 000 documents et 1 500 requêtes de test — largement suffisant pour un prototype fonctionnel, et le solde n’expire jamais. Lisez ensuite le guide complet du RAG pour les pratiques de production.
FAQ
How much does one RAG chatbot query cost?
About $0.007 per query on Claude Sonnet 4.6 with prompt caching active, or about $0.001 on Claude Haiku 4.5 — which returns roughly 85% of the quality at one-seventh of the cost.
How do I stop a RAG chatbot from hallucinating?
Three patterns do most of the work: require the model to cite a [doc:N] id for every claim, put an explicit refusal instruction in the system prompt, and cap the answer with max_tokens=600. Then verify every cited id appears in the retrieved set before rendering the answer.
What chunk size should a RAG index use?
1,000–1,500 characters per chunk with 100–200 characters of overlap, split with RecursiveCharacterTextSplitter and embedded with text-embedding-3-large.
Is vector search alone enough for RAG retrieval?
No. Hybrid retrieval combines vector similarity with BM25 keyword search and merges the two with reciprocal rank fusion, taking the top 5 chunks.