Aller au contenu principal

Conversations persistantes

Mis à jour le 28 juillet 2026

L’état qui persiste entre les échanges

L’un des avantages majeurs de l’API Agents par rapport à Chat Completions est la persistance des conversations. Vous n’avez plus à gérer manuellement l’historique des messages — Mistral le fait pour vous côté serveur. Concrètement, la liste de dictionnaires que vous accumuliez dans une variable, que vous tronquiez quand le contexte débordait et que vous reconstruisiez à chaque redémarrage de processus disparaît de votre code. Reste une seule chose à suivre : un identifiant. Et cet identifiant obéit à une règle qui piège tout le monde au premier projet.

Démarrer une conversation

La méthode conversations.start() crée une nouvelle conversation et envoie le premier message. L’exemple suivant crée au passage l’agent qui l’animera, puis lui confie un contexte de projet que vous allez pouvoir interroger sur plusieurs tours.

from mistralai import Mistral
import os

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Créer un agent
agent = client.beta.agents.create(
    model="mistral-medium-latest",
    name="Assistant Projet",
    description="Assistant de gestion de projet.",
    instructions="Vous aidez à organiser et suivre les projets. Soyez structuré."
)

# Démarrer la conversation
response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Je lance un nouveau projet de refonte de notre site web. Budget : 50K€, deadline : septembre 2026."
)

print(f"Conversation ID : {response.conversation_id}")

Le conversation_id retourné est votre clé pour continuer cette conversation plus tard. Rangez-le où votre application saura le retrouver : en session utilisateur, en base, dans le ticket de support auquel il se rattache.

Continuer une conversation

Pour ajouter un message à une conversation existante, fournissez le conversation_id à conversations.append(). Suivez le fil de l’exemple : la deuxième question ne redit rien du budget ni de l’échéance, et la troisième demande un planning sans rappeler qu’il s’agit d’une refonte web. L’agent dispose pourtant de tout ce contexte.

# Premier échange
response1 = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Je lance un projet de refonte web. Budget 50K€."
)

# Deuxième échange — l'agent se souvient du contexte
response2 = client.beta.conversations.append(
    conversation_id=response1.conversation_id,
    inputs="Quelles sont les étapes prioritaires ?"
)

# Troisième échange — toujours dans le même contexte
response3 = client.beta.conversations.append(
    conversation_id=response2.conversation_id,
    inputs="Rédige un planning pour les 3 premiers mois."
)

Regardez de près quel identifiant alimente chaque appel : response2 part de l’ID de response1, response3 de celui de response2. Ce n’est pas une coquette, c’est le mécanisme central de l’API.

Le mécanisme d’immutabilité

Chaque appel à conversations.append() retourne un nouveau conversation_id. L’ancien reste accessible en lecture, mais vous devez utiliser le dernier ID pour le prochain append.

# Chaque append retourne un nouvel ID
id_1 = response1.conversation_id  # "conv-aaa"
id_2 = response2.conversation_id  # "conv-bbb"
id_3 = response3.conversation_id  # "conv-ccc"

# Utilisez toujours le DERNIER id pour continuer
response4 = client.beta.conversations.append(
    conversation_id=id_3,  # Pas id_1 ou id_2
    inputs="Ajoute les jalons de validation client."
)

L’erreur classique consiste à enregistrer l’identifiant initial dans votre base de données au moment où l’utilisateur ouvre le fil, puis à le réutiliser tel quel à chaque message. Rien ne plante : l’API répond normalement, mais chaque question repart du contexte du premier échange, et votre agent semble atteint d’amnésie sans qu’aucune erreur ne vous alerte. Écrasez systématiquement l’identifiant stocké par celui que renvoie la réponse.

Lire l’historique d’une conversation

La lecture reste possible à tout moment, ce qui sert autant au débogage qu’à l’affichage d’un fil dans votre interface.

conversation = client.beta.conversations.retrieve(
    conversation_id=response.conversation_id
)

for entry in conversation.entries:
    print(f"[{entry.role}] {entry.type}: {entry.content[:100]}...")

Gérer le stockage

Par défaut, les conversations sont stockées dans le cloud Mistral. Le paramètre store=False supprime ce comportement pour les échanges que votre politique interne interdit de laisser sur un serveur tiers.

# Conversation éphémère — rien n'est sauvegardé
response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Données confidentielles à analyser...",
    store=False
)

Le prix à payer est cohérent avec l’objectif : la conversation n’est pas récupérable après la session et les données ne sont pas conservées sur les serveurs Mistral. Vous perdez donc la relecture d’historique décrite plus haut, et votre application devra assumer elle-même la trace des échanges si elle en a besoin. C’est un arbitrage à poser en amont, pas une case à cocher au dernier moment.

Pattern de conversation multi-tours

Le squelette ci-dessous applique tout ce qui précède dans une boucle interactive. Le point à retenir est la variable conversation_id, initialisée à None : elle décide de l’appel à effectuer — start() au premier tour, append() ensuite — et elle est réassignée après chaque réponse, conformément à la règle d’immutabilité.

from mistralai import Mistral
import os

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="Coach Technique",
    description="Coach pour les décisions techniques.",
    instructions="Vous êtes un coach technique senior. Posez des questions pour comprendre le contexte avant de conseiller."
)

# Boucle conversationnelle
conversation_id = None

while True:
    user_input = input("Vous : ")
    if user_input.lower() in ["quit", "exit"]:
        break

    if conversation_id is None:
        response = client.beta.conversations.start(
            agent_id=agent.id,
            inputs=user_input
        )
    else:
        response = client.beta.conversations.append(
            conversation_id=conversation_id,
            inputs=user_input
        )

    conversation_id = response.conversation_id

    for entry in response.outputs:
        if hasattr(entry, "content"):
            print(f"Agent : {entry.content}")

Adaptez-le à votre contexte en remplaçant input() par la source réelle de vos messages — requête HTTP, message de file d’attente, événement de webhook — et en persistant conversation_id là où votre application le retrouvera au tour suivant.

Points clés à retenir

  • conversations.start() crée une nouvelle conversation avec un premier message
  • conversations.append() ajoute un message à une conversation existante
  • Chaque append retourne un nouveau conversation_id — utilisez toujours le dernier
  • store=False désactive la persistance côté Mistral pour les données sensibles
  • L’agent conserve tout le contexte de la conversation sans que vous ayez à renvoyer l’historique