RAG avec Ollama : LLM Local, Données Privées, Zéro API Externe
RAG (Retrieval-Augmented Generation) est la technique qui permet à un LLM de répondre à partir de vos propres documents. Mais la plupart des tutoriels envoient tout vers OpenAI ou Anthropic. Voici comment faire la même chose entièrement en local avec Ollama.
Pourquoi Local ?
Trois raisons pratiques :
- RGPD : les données sensibles ne quittent jamais votre infrastructure
- Coût : zéro API, zéro facture par token
- Offline : fonctionne sans connexion internet
La contrepartie : il faut une machine suffisamment puissante (8 Go VRAM minimum pour des modèles 7B).
Stack
Ollama → serveur LLM local (Llama 3.1, Mistral, Phi-3...)
nomic-embed → modèle d'embedding local (via Ollama)
ChromaDB → vector store en mémoire ou persistant
Python → tout colle ensemble
Pipeline en 4 étapes
1. Installer Ollama et les modèles
# Installer Ollama (Linux/Mac)
curl -fsSL https://ollama.com/install.sh | sh
# Télécharger le LLM et le modèle d'embedding
ollama pull llama3.1:8b
ollama pull nomic-embed-text
2. Indexer les documents
import chromadb
import ollama
def embed(text: str) -> list[float]:
resp = ollama.embeddings(model="nomic-embed-text", prompt=text)
return resp["embedding"]
client = chromadb.Client()
collection = client.create_collection("docs")
documents = [
{"id": "doc1", "text": "La politique RGPD de l'entreprise est..."},
{"id": "doc2", "text": "Les données clients sont stockées dans..."},
]
for doc in documents:
collection.add(
ids=[doc["id"]],
embeddings=[embed(doc["text"])],
documents=[doc["text"]],
)
3. Retrieval — trouver les passages pertinents
def retrieve(query: str, n: int = 3) -> list[str]:
results = collection.query(
query_embeddings=[embed(query)],
n_results=n,
)
return results["documents"][0]
4. Génération avec contexte
def rag(question: str) -> str:
passages = retrieve(question)
context = "\n\n".join(passages)
response = ollama.chat(
model="llama3.1:8b",
messages=[{
"role": "user",
"content": f"""Réponds à la question en te basant UNIQUEMENT sur le contexte fourni.
Si la réponse n'est pas dans le contexte, dis-le clairement.
Contexte :
{context}
Question : {question}"""
}]
)
return response["message"]["content"]
Ce qui change par rapport au RAG cloud
Embedding local vs cloud : nomic-embed-text est nettement moins précis que text-embedding-3-large d’OpenAI sur des corpus complexes. Sur des documents métier en français, la différence est réelle — testez toujours sur vos données avant de choisir.
Latence : sur un Macbook M2 ou une machine Linux avec GPU mid-range, comptez 2–5 secondes pour une réponse 7B. Acceptable pour des outils internes, pas pour du temps réel.
ChromaDB en prod : pour la production, utilisez le mode persistant ou remplacez par pgvector (PostgreSQL) — plus robuste pour les volumes importants.
# ChromaDB persistant
client = chromadb.PersistentClient(path="/data/chroma")
Cas d’usage idéaux
- Base de connaissances RH interne (contrats, politiques)
- Support client sur documentation propriétaire
- Assistant sur données médicales ou juridiques
- Tout contexte où les données ne peuvent pas quitter le réseau interne
Stéphanie Caumont
Product Owner IA · En savoir plus