Changer le thème

Intégration LangChain + Ollama : guide complet pour développer des applications LLM en local

Easton editorial illustration: MCP integration socket hub

Le mois dernier, j’ai jeté un œil à la facture OpenAI : 52,3 $. Honnêtement, j’ai un peu flanché — en tant que développeur solo qui bricole l’IA de temps en temps, comment ai-je pu dépenser autant ? Puis je me suis souvenu d’Ollama qui tourne en local : Llama 3.1 gratuit, prêt à l’emploi.

Mais il y a un hic : appeler directement l’API Ollama pour une application, c’est beaucoup de code. Format de requête, parsing de réponse, gestion d’erreurs… à chaque fois, c’est pénible. Là, LangChain entre en jeu — une couche d’abstraction prête à l’emploi pour Chat, RAG et Agent, avec bascule de modèle en une ligne.

Cet article fait partie de la série Guide pratique LLM local avec Ollama, sur l’intégration avec un framework. Nous partons du package langchain-ollama jusqu’aux trois scénarios Chat, RAG et Agent. Si vous avez lu les articles précédents (appels API, déploiement multi-modèles), celui-ci relie ces briques en un cadre de développement cohérent.

Premiers pas avec langchain-ollama

Je commence par un piège que j’ai pris. J’utilisais langchain_community.llms.Ollama : le code tournait, mais quelque chose clochait — la doc pointait toujours vers langchain-ollama. LangChain a extrait l’intégration Ollama dans un package dédié.

Pourquoi le package officiel ?

Meilleures annotations de types, autocomplétion IDE plus utile, rythme de maintenance aligné sur LangChain, et pas de risque de dépréciation comme pour les packages communautaires — j’en ai déjà souffert.

Installation en une commande :

pip install langchain-ollama

Trois classes principales, chacune pour un usage :

ClasseUsageScénario typique
ChatOllamaModèle de dialogueChat multi-tours, Q&R
OllamaLLMComplétion de texteGénération unique, continuation
OllamaEmbeddingsEmbeddings vectorielsRAG, recherche sémantique

En pratique, ChatOllama suffit pour environ 90 % des cas : dialogue multi-tours et streaming — l’affichage mot à mot améliore nettement l’expérience par rapport à une réponse d’un bloc.

Exemple minimal :

from langchain_ollama import ChatOllama

# Initialiser le modèle
llm = ChatOllama(
    model="llama3.1:8b",  # Nom du modèle, à télécharger via Ollama avant
    temperature=0.7       # Paramètre de randomisation, entre 0 et 1
)

# Envoyer un message
response = llm.invoke("Bonjour, présentez-vous brièvement")
print(response.content)

Avant d’exécuter, assurez-vous d’avoir fait ollama pull llama3.1:8b. Si Ollama n’est pas installé, reportez-vous au premier article de la série.

OllamaEmbeddings sert surtout à vectoriser du texte ; la section RAG l’utilisera en détail. Aperçu :

from langchain_ollama import OllamaEmbeddings

embeddings = OllamaEmbeddings(model="nomic-embed-text")

# Embedding d'un seul texte
vector = embeddings.embed_query("Ceci est un texte de test")
print(f"Dimension du vecteur : {len(vector)}")  # Souvent 768 ou plus

# Embedding par lot
vectors = embeddings.embed_documents([
    "Premier passage",
    "Deuxième passage"
])

nomic-embed-text est un modèle d’embedding courant pour la recherche sémantique. Dimensions élevées (souvent 768+), souvent meilleur qu’un modèle générique pour le retrieval.

Chat en pratique : dialogue multi-tours et streaming

Un seul appel API est simple ; un vrai chat est plus riche — l’utilisateur enchaîne les questions et le modèle doit garder le contexte. LangChain gère cela avec une liste de messages.

Dialogue multi-tours

Trois types de messages :

  • SystemMessage : rôle et comportement du modèle (ex. « vous êtes un assistant développeur »)
  • HumanMessage : entrée utilisateur
  • AIMessage : réponse du modèle

Exemple :

from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage

llm = ChatOllama(model="llama3.1:8b", temperature=0.7)

# Construire l'historique
messages = [
    SystemMessage(content="Vous êtes un assistant développeur qui explique les concepts techniques de façon claire et concise."),
    HumanMessage(content="Qu'est-ce qu'une API REST ?"),
    AIMessage(content="Une API REST est un style d'interface de service web qui utilise les méthodes HTTP (GET/POST/PUT/DELETE) pour manipuler des ressources. En bref : accéder aux données via des URL."),
    HumanMessage(content="En quoi GraphQL diffère-t-il de REST ?")
]

# Le modèle s'appuie sur tout l'historique
response = llm.invoke(messages)
print(response.content)

Ici, le modèle voit la réponse précédente et comprend que l’utilisateur compare GraphQL et REST. Sans le AIMessage, il risquerait de tout réexpliquer depuis le début.

Streaming : une réponse qui « vit »

Le streaming évite l’écran vide : le texte apparaît progressivement, comme une frappe. Très utile pour les longues réponses.

from langchain_ollama import ChatOllama

llm = ChatOllama(model="llama3.1:8b")

# Sortie en streaming
print("Réponse du modèle : ", end="", flush=True)
for chunk in llm.stream("Écrivez un tri rapide en Python et expliquez le principe"):
    print(chunk.content, end="", flush=True)
print()  # Retour à la ligne final

stream() renvoie un itérateur ; chaque chunk contient un fragment. flush=True affiche immédiatement sans buffer.

En test, le streaming paraît plus réactif qu’une réponse monolithique — surtout au-delà de 100 caractères. L’utilisateur a l’impression que le système « réfléchit », pas qu’il est bloqué.

RAG en pratique : retrieval sur une base locale

Le RAG (Retrieval-Augmented Generation) est l’un des usages LLM les plus utiles aujourd’hui : on récupère d’abord des passages pertinents dans une bibliothèque de documents, puis le modèle répond à partir de ce contexte. Il peut ainsi « savoir » ce qui n’était pas dans ses données d’entraînement.

Décomposition du flux RAG

Cinq étapes :

  1. Charger les documents — PDF, TXT, Markdown, etc.
  2. Découper le texte — fragments plus petits pour le retrieval
  3. Générer les vecteurs — embeddings numériques
  4. Stocker l’index — base vectorielle (ici ChromaDB)
  5. Retrieval et génération — à la question, récupérer puis répondre

Code complet testé :

from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_chroma import Chroma
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# === 1. Charger les documents ===
loader = TextLoader("./my_document.txt")  # Remplacez par votre chemin
docs = loader.load()

# === 2. Découper le texte ===
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200
)
splits = text_splitter.split_documents(docs)

# === 3 & 4. Embeddings et stockage ===
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

# === 5. Retriever ===
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# === 6. Chaîne RAG ===
template = """Répondez à la question à partir du contexte ci-dessous. Si le contexte ne contient pas l'information, indiquez clairement « aucune information pertinente dans le document ».

Contexte :
{context}

Question : {question}
"""
prompt = ChatPromptTemplate.from_template(template)

llm = ChatOllama(model="llama3.1:8b")

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# === 7. Requête ===
response = rag_chain.invoke("Quel est le contenu principal du document ?")
print(response)

Le cœur est rag_chain : syntaxe LCEL (LangChain Expression Language) qui enchaîne retriever, prompt, modèle et parseur.

Réglages utiles :

chunk_size : environ 800 pour de la doc technique dense ; 1000-1500 pour du contenu plus narratif.

k : en général 3 à 5 fragments ; trop élevé dilue la pertinence, trop bas peut omettre l’essentiel.

persist_directory est indispensable : sans persistance, chaque redémarrage reconstruit l’index — long et coûteux. Après l’avoir ajouté, le chargement prend quelques secondes.

Agent en pratique : appels d’outils via JSON

La différence majeure avec un simple chat : l’agent peut appeler des outils externes.

Exemple : « Quel temps fait-il à Pékin aujourd’hui ? » Un modèle conversationnel peut inventer ; un agent interroge d’abord une API météo, puis répond.

Limites des outils avec Ollama

À dire clairement : le support des outils chez Ollama n’est pas au niveau d’OpenAI. Les modèles OpenAI gèrent le function calling nativement ; Llama 3.1 et consorts sont encore en retard sur ce point.

La solution côté LangChain : un JSON Agent — le modèle produit du JSON structuré, le framework décide quel outil appeler. En test, c’est utilisable, moins fluide qu’OpenAI, mais suffisant pour des tâches simples.

Exemple d’outils personnalisés

from langchain_ollama import ChatOllama
from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """Obtenir la météo pour une ville donnée"""
    weather_data = {
        "Pékin": "Ensoleillé, 25°C, bonne qualité de l'air",
        "Shanghai": "Nuageux, 22°C, risque de pluie fine",
        "Shenzhen": "Chaud, 30°C, UV élevés"
    }
    return weather_data.get(city, f"Aucune donnée météo pour {city}")

@tool
def calculate(expression: str) -> str:
    """Effectuer un calcul mathématique"""
    try:
        result = eval(expression)  # Attention : en production, préférez une implémentation plus sûre
        return f"Résultat : {result}"
    except:
        return "Erreur de calcul, vérifiez l'expression"

@tool
def search_local_docs(query: str) -> str:
    """Rechercher dans la bibliothèque locale"""
    return f"Résultats pour « {query} » : 3 enregistrements trouvés"

Le décorateur @tool transforme une fonction en outil LangChain ; la docstring devient la description pour le modèle.

Création du JSON Agent :

from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOllama(model="llama3.1:8b")
tools = [get_weather, calculate, search_local_docs]

prompt = ChatPromptTemplate.from_messages([
    ("system", "Vous êtes un assistant utile qui peut utiliser des outils pour accomplir des tâches."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

response = agent_executor.invoke({
    "input": "Quel temps fait-il à Pékin aujourd'hui, puis calculez 23 + 45"
})

print(response["output"])

verbose=True affiche le raisonnement de l’agent, utile au débogage.

Retour d’expérience :

70-80 %
Taux de succès JSON Agent
Tâches simples en général OK ; tâches complexes parfois en échec
Source: Données de test de l’auteur

Sur plusieurs tâches, le taux tourne autour de 70-80 %. Météo, calculs : en général correct ; combinaisons d’outils : parfois mauvais format de paramètres ou mauvais choix d’outil — limite courante des agents LLM locaux, loin de la stabilité OpenAI.

Si vos exigences Agent sont élevées :

  1. Modèle plus capable (Qwen 2.5, DeepSeek, etc.)
  2. Simplifier le flux et réduire le nombre d’outils
  3. Ou OpenAI natif : plus cher, mais bien plus stable

OpenAI vs Ollama : bascule en une ligne

Question fréquente : peut-on utiliser OpenAI et Ollama avec le même code LangChain ? Oui, et c’est très simple.

Méthode 1 : changer l’import

Code OpenAI :

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4", temperature=0.7)
response = llm.invoke("Expliquez l'informatique quantique")

Pour Ollama, une ligne d’import :

from langchain_ollama import ChatOllama

llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
response = llm.invoke("Expliquez l'informatique quantique")

Templates, Chain, parseurs : inchangés. L’abstraction LangChain rend la bascule quasi transparente pour la logique métier.

Méthode 2 : API compatible OpenAI

Ollama expose aussi un endpoint compatible OpenAI — sans changer d’import :

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="llama3.1:8b",
    base_url="http://localhost:11434/v1",
    api_key="ollama"
)

response = llm.invoke("Expliquez l'informatique quantique")

Utile si le projet est déjà structuré autour de ChatOpenAI et que vous voulez tester un modèle local sans refactoriser.

Synthèse comparative

CritèreOpenAI (GPT-4)Ollama (Llama 3.1)
Coût~0,03 $ / 1K tokens en entréeGratuit (coût électricité GPU local)
ConfidentialitéDonnées dans le cloud ; vigilance conformitéTraitement local, données qui ne sortent pas
OutilsFunction calling natif, stableJSON Agent, ~70-80 % de succès
LatenceRapide (cloud optimisé, 1-3 s au premier token)Dépend du GPU local (3-10 s variable)
CapacitéGPT-4 parmi les plus fortsLlama 3.1 8B solide, en dessous de GPT-4

Recommandations :

  • Apprentissage, prototype : Ollama, économique et flexible
  • Production, fort trafic : OpenAI, stabilité et débit
  • Données sensibles : Ollama, tout reste local
  • Agents complexes : OpenAI, outils plus fiables

L’idéal : les deux — Ollama en dev, OpenAI en prod ; la bascule ne coûte qu’une ligne.

Synthèse

Vous avez maintenant une carte complète de l’intégration LangChain + Ollama.

Package langchain-ollama et les trois classes ChatOllama, OllamaLLM, OllamaEmbeddings ; puis Chat (streaming), RAG (documents locaux en Q&R), Agent (JSON Agent comme compromis actuel) ; enfin les stratégies de bascule OpenAI/Ollama — une ligne suffit, des dizaines de dollars par mois à zéro en local.

Quand choisir Ollama ?

Quand vous voulez économiser, protéger la confidentialité ou apprendre le développement LLM sans craindre la facture.

Quand rester sur OpenAI ?

Agents complexes, production à fort trafic, exigences strictes de latence et de stabilité. Le local ne remplace pas encore l’expérience cloud optimisée.

Si vous n’avez pas encore testé, commencez par Chat — le plus simple, l’effet le plus immédiat. Puis RAG pour connecter vos documents et voir le modèle « lire » votre matériel. Les agents peuvent attendre : plus de réglages et de pièges.

La série continue : déploiement multi-modèles, optimisation des performances, mise en production. Suivez la suite si cela vous intéresse.

Questions en commentaires ou sur GitHub. Les exemples ont été exécutés ; en cas d’erreur, vérifiez surtout que le modèle est téléchargé et les dépendances installées, puis lisez le message d’erreur.

Développement avec LangChain + Ollama

De l'installation à Chat, RAG et Agent : maîtrisez le développement d'applications LLM locales en un seul parcours

⏱️ Estimated time: 60 min

  1. 1

    Step 1: Installer le package langchain-ollama

    Exécutez la commande d'installation :

    ```bash
    pip install langchain-ollama
    ```

    Assurez-vous qu'Ollama est installé et qu'un modèle est téléchargé (par ex. `ollama pull llama3.1:8b`).
  2. 2

    Step 2: Créer une application Chat

    Initialisez ChatOllama et envoyez un message :

    ```python
    from langchain_ollama import ChatOllama

    llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
    response = llm.invoke("Bonjour")
    print(response.content)
    ```

    Prise en charge du dialogue multi-tours et du streaming.
  3. 3

    Step 3: Construire une base de connaissances RAG

    Cinq étapes :

    • Charger les documents (TextLoader / PyPDFLoader)
    • Découper le texte (RecursiveCharacterTextSplitter)
    • Générer les vecteurs (OllamaEmbeddings)
    • Stocker l'index (ChromaDB)
    • Retrieval et génération (RAG Chain)

    Paramètres clés : chunk_size=1000, k=4, persist_directory obligatoire.
  4. 4

    Step 4: Implémenter un Agent avec appels d'outils

    Définissez des fonctions outil et créez un JSON Agent :

    ```python
    @tool
    def get_weather(city: str) -> str:
    """Obtenir les informations météo"""
    ...

    agent = create_tool_calling_agent(llm, tools, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tools)
    ```

    Taux de succès d'environ 70-80 % ; pour les tâches complexes, privilégiez OpenAI.
  5. 5

    Step 5: Basculer entre OpenAI et Ollama

    Méthode 1 : changer l'import

    ```python
    from langchain_ollama import ChatOllama # Ollama
    from langchain_openai import ChatOpenAI # OpenAI
    ```

    Méthode 2 : API compatible OpenAI (sans changer l'import)

    ```python
    llm = ChatOpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama"
    )
    ```

FAQ

Quelle différence entre langchain-ollama et langchain_community.llms.Ollama ?
langchain-ollama est un package officiel indépendant, avec de meilleures annotations de types et un rythme de maintenance aligné sur la version principale. langchain_community.llms.Ollama est un package communautaire susceptible d'être déprécié. Nous recommandons le package officiel langchain-ollama.
Faut-il utiliser ChatOllama ou OllamaLLM ?
Dans environ 90 % des cas, ChatOllama suffit. Il prend en charge le dialogue multi-tours, le streaming et l'historique des messages. OllamaLLM convient à la génération de texte en une seule passe ou à la continuation de texte.
Comment régler chunk_size et k dans un système RAG ?
chunk_size : 800 pour la documentation technique, 1000-1500 pour du contenu plus narratif. k (nombre de fragments récupérés) : en général 3 à 5 ; trop élevé dilue la pertinence, trop bas peut omettre des informations clés. Définissez toujours persist_directory pour persister la base vectorielle.
Pourquoi les appels d'outils Ollama sont-ils moins stables qu'avec OpenAI ?
Les modèles Ollama (y compris Llama 3.1) n'ont pas de function calling natif ; il faut un JSON Agent pour produire du JSON structuré, avec un taux de succès d'environ 70-80 %. OpenAI est plus stable pour les agents complexes.
Comment basculer entre OpenAI et Ollama ?
Méthode 1 : changer l'import (ChatOpenAI vers ChatOllama). Méthode 2 : API compatible OpenAI en modifiant seulement base_url et api_key. Le reste du code (templates de prompt, Chain, parsing de sortie) reste inchangé.
Ollama convient-il à la production ?
Cela dépend du contexte. Apprentissage personnel, prototypage, données sensibles : Ollama convient. Production à fort trafic, agents complexes, exigences de latence élevées : préférez OpenAI. Idéalement : Ollama en développement pour réduire les coûts, OpenAI en production pour la stabilité.

10 min de lecture · Publié le: 7 avr. 2026 · Mis à jour le: 27 juil. 2026

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog