IA locale Débutant schedule 30 min

chat Premier chatbot Python en ligne de commande

Construire un chatbot conversationnel complet avec Python et Ollama : historique de conversation, boucle d'interaction, gestion des erreurs.

folder_open Préparer le projet 01

On crée un nouveau projet Python avec son venv. Si tu ne te souviens plus comment, relis le tuto sur les environnements virtuels.

terminalTerminal
mkdir chatbot-ollama
cd chatbot-ollama

# Créer et activer le venv
python -m venv venv                  # Windows
python3 -m venv venv                 # macOS / Linux

venv\Scripts\activate                # Windows
source venv/bin/activate             # macOS / Linux

# Installer la bibliothèque officielle Ollama pour Python
pip install ollama

La bibliothèque ollama est l'interface Python officielle pour parler à Ollama. Elle simplifie les appels API qu'on a vus dans le tuto précédent.

send Premier appel au modèle 02

Crée un fichier chatbot.py. On commence simple — un seul message, une seule réponse :

codechatbot.py — version 1
import ollama  # on importe la bibliothèque qu'on vient d'installer

# La fonction chat() prend un modèle et une liste de messages.
# Chaque message est un dictionnaire avec deux clés :
#   "role"    : "user" (l'utilisateur) ou "assistant" (le modèle)
#   "content" : le texte du message

reponse = ollama.chat(
    model="gemma4:e2b",
    messages=[
        {"role": "user", "content": "Bonjour ! Qui es-tu ?"}
    ]
)

# La réponse est un objet. Le texte généré est dans :
# reponse.message.content
print(reponse.message.content)
terminalTerminal
python chatbot.py

Le modèle répond. Mais là, c'est un programme qui envoie un message fixe et s'arrête. On veut une vraie conversation.

forum L'historique de conversation 03

Pour qu'un LLM se souvienne de ce qu'on a dit précédemment, il faut lui envoyer tout l'historique de la conversation à chaque requête. Les LLM n'ont pas de mémoire intrinsèque — ils ne voient que les messages qu'on leur passe.

Concrètement, on maintient une liste historique et on y ajoute chaque message (utilisateur et assistant) au fur et à mesure :

codechatbot.py — version 2 (avec historique)
import ollama

# L'historique démarre vide. On peut aussi y mettre un "system prompt"
# pour donner des instructions globales au modèle.
historique = [
    {
        "role": "system",
        "content": (
            "Tu es un assistant en français, sympathique et concis. "
            "Tu réponds toujours en français, même si on te parle dans une autre langue."
        )
    }
]

print("=== Chatbot Ollama (gemma4:e2b) ===")
print("Tape 'quitter' pour terminer.\n")

while True:  # une boucle infinie — on continue jusqu'à ce que l'utilisateur quitte
    
    # 1. Demander un message à l'utilisateur
    message_utilisateur = input("Toi : ").strip()
    
    # 2. Permettre de quitter proprement
    if message_utilisateur.lower() in ["quitter", "exit", "bye", "q"]:
        print("Au revoir !")
        break  # sort de la boucle while
    
    # 3. Ne rien faire si l'utilisateur n'a rien tapé
    if not message_utilisateur:
        continue  # passe à l'itération suivante de la boucle
    
    # 4. Ajouter le message de l'utilisateur à l'historique
    historique.append({
        "role": "user",
        "content": message_utilisateur
    })
    
    # 5. Envoyer TOUT l'historique au modèle
    reponse = ollama.chat(
        model="gemma4:e2b",
        messages=historique
    )
    
    # 6. Extraire le texte de la réponse
    texte_reponse = reponse.message.content
    
    # 7. Ajouter la réponse de l'assistant à l'historique
    historique.append({
        "role": "assistant",
        "content": texte_reponse
    })
    
    # 8. Afficher la réponse
    print(f"\nAssistant : {texte_reponse}\n")
info

Le while True: crée une boucle infinie — le programme continue indéfiniment jusqu'à ce qu'on rencontre un break. C'est le pattern classique pour une interface en ligne de commande interactive.

Lance le programme et teste une vraie conversation en plusieurs échanges. Remarque que le modèle se souvient de ce que tu as dit au début — c'est grâce à l'historique qu'on lui passe.

stream Afficher la réponse en temps réel (streaming) 04

Pour l'instant, le programme attend que le modèle ait tout généré avant d'afficher quoi que ce soit. C'est frustrant pour les longues réponses. On peut activer le streaming pour afficher le texte mot par mot, comme ChatGPT :

codechatbot.py — version finale avec streaming
import ollama
import sys  # pour flush le buffer d'affichage

historique = [
    {
        "role": "system",
        "content": (
            "Tu es un assistant en français, sympathique et concis. "
            "Tu réponds toujours en français."
        )
    }
]

print("=== Chatbot Ollama (gemma4:e2b) ===")
print("Tape 'quitter' pour terminer.\n")

while True:
    message_utilisateur = input("Toi : ").strip()

    if message_utilisateur.lower() in ["quitter", "exit", "bye", "q"]:
        print("Au revoir !")
        break

    if not message_utilisateur:
        continue

    historique.append({"role": "user", "content": message_utilisateur})

    print("Assistant : ", end="", flush=True)  # afficher sans saut de ligne

    texte_complet = ""  # on accumule le texte pour l'historique

    # stream=True active le streaming
    for chunk in ollama.chat(model="gemma4:e2b", messages=historique, stream=True):
        morceau = chunk.message.content
        print(morceau, end="", flush=True)  # afficher sans saut de ligne
        texte_complet += morceau           # accumuler

    print("\n")  # saut de ligne à la fin de la réponse

    historique.append({"role": "assistant", "content": texte_complet})
lightbulb

end="" dans print() empêche le saut de ligne automatique. flush=True force Python à afficher immédiatement sans attendre de remplir son buffer interne. Ces deux options ensemble permettent l'affichage progressif.

error_outline Gérer les erreurs proprement 05

Que se passe-t-il si Ollama n'est pas lancé, ou si le modèle n'existe pas ? Le programme plante avec une erreur cryptique. On peut gérer ça proprement avec try/except :

codeBloc try/except autour de l'appel Ollama
    # Remplace le bloc "for chunk in ollama.chat..." par ceci :
    try:
        print("Assistant : ", end="", flush=True)
        texte_complet = ""

        for chunk in ollama.chat(model="gemma4:e2b", messages=historique, stream=True):
            morceau = chunk.message.content
            print(morceau, end="", flush=True)
            texte_complet += morceau

        print("\n")
        historique.append({"role": "assistant", "content": texte_complet})

    except Exception as erreur:
        # Si quelque chose se passe mal, on affiche un message clair
        print(f"\n[Erreur] Impossible de contacter Ollama : {erreur}")
        print("Vérifie qu'Ollama est bien lancé sur ta machine.\n")
        # On retire le dernier message utilisateur de l'historique
        # car la réponse n'a pas été générée
        historique.pop()

Ton chatbot est maintenant robuste et agréable à utiliser. Dans le tuto suivant, on va plus loin : on crée un agent capable d'appeler de vraies fonctions Python pour récupérer des données réelles.