Ce que vous saurez faire
A la fin de ce tutoriel, vous saurez construire une application RAG (Retrieval Augmented Generation) avec LangChain Python et Claude (Anthropic). Vous indexerez les documents PDF de votre PME senegalaise (catalogues produits, fiches techniques, conditions generales de vente), puis vous interrogerez Claude qui repondra en s’appuyant sur ces documents. Resultat concret : un assistant interne qui repond aux commerciaux en moins de 3 secondes, base uniquement sur vos donnees verifiees, sans inventer de prix en FCFA. Coute estime : 15 000 FCFA par mois pour 1000 requetes.
Etape 1 : Preparer l’environnement Python
Sur votre poste Windows ou Ubuntu, installez Python 3.11 minimum. Creez un dossier projet et un environnement virtuel pour isoler les dependances :
mkdir rag-pme-dakar
cd rag-pme-dakar
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Linux/Mac
pip install --upgrade pip
Etape 2 : Installer LangChain et le SDK Anthropic
Installez les paquets necessaires. Nous prenons les versions stables compatibles entre elles :
pip install langchain==0.2.16
pip install langchain-anthropic==0.1.23
pip install langchain-community==0.2.16
pip install pypdf==4.3.1
pip install chromadb==0.5.5
pip install sentence-transformers==3.0.1
pip install python-dotenv==1.0.1
Etape 3 : Recuperer la cle API Anthropic
Allez sur console.anthropic.com, creez un compte, ajoutez 5 USD (environ 3000 FCFA) en credit via carte Visa internationale ou Wave en passant par Wise. Generez une cle API qui commence par sk-ant-. Creez un fichier .env a la racine du projet :
ANTHROPIC_API_KEY=sk-ant-api03-VOTRECLEICI
Ajoutez .env a votre .gitignore pour ne jamais publier la cle sur GitHub.
Etape 4 : Charger vos PDF metier
Placez vos documents (catalogue.pdf, cgv.pdf, tarifs.pdf) dans un dossier docs/. Le code suivant charge automatiquement tous les PDF :
from langchain_community.document_loaders import PyPDFDirectoryLoader
loader = PyPDFDirectoryLoader("./docs")
documents = loader.load()
print(f"Documents charges : {len(documents)} pages")
Pour 50 pages typiques d’une PME, le chargement prend moins de 5 secondes.
Etape 5 : Decouper en chunks intelligents
Claude ne peut pas digerer un PDF entier. Il faut decouper en morceaux de 800 caracteres avec 100 caracteres de chevauchement pour preserver le contexte :
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=800,
chunk_overlap=100,
separators=["\n\n", "\n", ". ", " "]
)
chunks = splitter.split_documents(documents)
print(f"Chunks crees : {len(chunks)}")
Etape 6 : Generer les embeddings localement
Pour eviter les frais OpenAI, on utilise un modele open-source qui tourne sur votre PC. Le modele paraphrase-multilingual-MiniLM gere bien le francais :
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
model_kwargs={"device": "cpu"}
)
Premier telechargement : 450 Mo, ensuite tout est en cache local.
Etape 7 : Stocker dans ChromaDB
ChromaDB est une base vectorielle gratuite qui s’execute en local. Aucun serveur a louer :
from langchain_community.vectorstores import Chroma
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db"
)
vectorstore.persist()
print("Index sauvegarde dans ./chroma_db")
Etape 8 : Configurer Claude comme moteur de reponse
On utilise Claude 3.5 Sonnet pour la qualite, ou Claude 3 Haiku pour reduire les couts (4x moins cher) :
from langchain_anthropic import ChatAnthropic
from dotenv import load_dotenv
load_dotenv()
llm = ChatAnthropic(
model="claude-3-5-sonnet-20241022",
temperature=0.2,
max_tokens=1024
)
Etape 9 : Construire la chaine RAG
On assemble retrieval + generation. Le retriever cherche les 4 chunks les plus pertinents :
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
template = """Tu es l'assistant interne d'une PME senegalaise.
Reponds UNIQUEMENT avec les informations du contexte ci-dessous.
Si l'information n'y est pas, reponds "Information non disponible".
Les prix sont toujours en FCFA.
Contexte :
{context}
Question : {question}
Reponse :"""
prompt = PromptTemplate(template=template, input_variables=["context", "question"])
qa = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
chain_type_kwargs={"prompt": prompt}
)
Etape 10 : Poser une premiere question
Testez avec une question reelle de vos commerciaux :
question = "Quel est le prix du modele Solaris 200W et la garantie ?"
reponse = qa.invoke({"query": question})
print(reponse["result"])
Reponse type : « Le modele Solaris 200W coute 145 000 FCFA TTC avec une garantie de 24 mois piece et main d’oeuvre. »
Etape 11 : Ajouter les sources citees
Pour la confiance, affichez le PDF source. Modifiez la chaine :
qa = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
chain_type_kwargs={"prompt": prompt},
return_source_documents=True
)
result = qa.invoke({"query": question})
for doc in result["source_documents"]:
print(f"Source : {doc.metadata['source']} page {doc.metadata['page']}")
Etape 12 : Mesurer le cout par requete
Claude facture en tokens. Une requete RAG typique = 1500 tokens d’entree + 200 tokens de sortie. Avec Claude 3.5 Sonnet : 0,005 USD soit environ 3 FCFA par question. Pour 1000 questions par mois : 3000 FCFA. Pour reduire encore, basculez sur claude-3-haiku-20240307 : 0,0008 USD par requete soit moins de 1 FCFA.
Etape 13 : Exposer en API web avec FastAPI
Pour que vos commerciaux interrogent depuis un navigateur :
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Question(BaseModel):
texte: str
@app.post("/ask")
def ask(q: Question):
reponse = qa.invoke({"query": q.texte})
return {"reponse": reponse["result"]}
# Lancer : uvicorn main:app --host 0.0.0.0 --port 8000
Etape 14 : Deployer chez un hebergeur africain
Hebergez l’application chez Orange Business Senegal (VPS 4 Go RAM a 25 000 FCFA par mois) ou sur un Raspberry Pi 5 dans vos locaux pour les donnees sensibles. Configurez un nom de domaine .sn via NIC Senegal (15 000 FCFA par an), activez HTTPS gratuit avec Let’s Encrypt via Certbot.
Erreurs
Erreur 1 : Cle API exposee sur GitHub. Anthropic la revoque automatiquement et vous facture les usages frauduleux. Solution : .gitignore stricte et secrets dans variables d’environnement systeme en production.
Erreur 2 : Chunks trop gros (3000 caracteres). Le retrieval devient flou et Claude noie sa reponse. Restez entre 500 et 1000.
Erreur 3 : Oublier le prompt strict. Sans la consigne « uniquement avec le contexte », Claude invente parfois des prix. Toujours ajouter la phrase « Si l’information n’y est pas, reponds Information non disponible ».
Erreur 4 : Indexer a chaque requete. Genere les embeddings une fois, persistez avec Chroma, rechargez avec Chroma(persist_directory=…).
Erreur 5 : Utiliser Claude pour les embeddings. C’est 50 fois plus cher. Utilisez sentence-transformers en local, gratuit.
Checklist
Avant mise en production, verifiez :
- Python 3.11+ installe et environnement virtuel actif
- Cle API Anthropic dans .env, jamais commitee
- Au moins 10 PDF metier dans /docs pour un index utile
- Chunks entre 500 et 1000 caracteres avec overlap de 100
- Modele d’embedding multilingue installe en local
- Base ChromaDB persistee sur disque
- Prompt template avec consigne anti-hallucination
- Test avec 20 questions reelles de vos commerciaux
- Sources citees affichees a chaque reponse
- Cout par requete mesure et budget mensuel valide
- API FastAPI exposee derriere HTTPS
- Sauvegardes hebdomadaires de chroma_db/ sur disque externe
- Logs des questions sauvegardes pour ameliorer l’index
- Procedure de re-indexation documentee pour mises a jour catalogue