Mistral Responses API : migrer votre agent en 30 min, sans état
Preview ouverte le 28 octobre : ce que change le format « items », et la boucle d'outils à recoder chez vous.
Oui, vous pouvez migrer un agent Mistral vers la nouvelle Responses API en une demi-heure, mais pas en changeant juste l'URL. Mistral a ouvert l'API en public preview le 28 octobre. Elle fonctionne avec tous les modèles de chat hébergés, Mistral Large 4 compris. Ce tuto s'adresse aux développeurs et responsables techniques de PME qui ont déjà un appel chat completions en production et veulent savoir ce qu'ils gagnent, ce qu'ils perdent.
Précision d'honnêteté : produit sorti il y a deux jours. Ce qui suit s'appuie sur la documentation officielle et les annonces, pas sur des mois de production. Les points non confirmés sont signalés.
Mistral Responses API : ce qui change face à chat completions
Avec chat completions, la réponse arrive dans un seul message, avec le texte et les appels d'outils mélangés dans le même objet. La Responses API découpe : le résultat est une liste d'items typés. La doc en liste trois pour la sortie : message de sortie (avec des blocs output_text), appel de fonction, et item de raisonnement.
Intérêt concret : votre code n'a plus à deviner si le modèle « réfléchit », « parle » ou « demande un outil ». Vous bouclez sur output et vous traitez chaque type. Pour un agent qui affiche une progression à l'utilisateur, c'est plus propre. Les trames de streaming suivent la même logique (response.output_text.delta pour les morceaux de texte).
Deux endpoints à retenir :
POST /v1/responses: crée la réponse.POST /v1/responses/input_tokens: estime les tokens d'une conversation, d'instructions et de définitions d'outils sans rien générer.
Si vous utilisez déjà le format Responses chez OpenAI, la forme vous sera familière. Nous avions décrit l'approche côté OpenAI dans notre test de l'Agents API d'OpenAI ; la différence majeure se trouve plus bas.
Premier appel à la Responses API Mistral : curl et Python
Deux champs sont obligatoires : model et input. L'entrée peut être une simple chaîne ou un tableau d'items (messages, appels de fonction, résultats de fonction, items de raisonnement). Le champ instructions remplace le message système : il est placé avant l'entrée.
curl https://api.mistral.ai/v1/responses \
-H "Authorization: Bearer $MISTRAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-large-4",
"instructions": "Tu réponds en français, en trois phrases max.",
"input": "Résume les risques d'un contrat de maintenance sans plafond de pénalités.",
"max_output_tokens": 1024
}'
Même appel en Python avec le SDK, selon les exemples de la doc :
resp = client.responses.create(
model="mistral-large-4",
input="Résume les risques d'un contrat de maintenance sans plafond.",
reasoning={"effort": "high"},
max_output_tokens=4096,
)
for item in resp.output:
if item.type == "message":
for part in item.content:
print(part.text)
Sortie structurée : le champ text accepte texte brut, mode JSON ou JSON Schema. Pour extraire des champs d'un email ou d'une facture, le JSON Schema évite le passage par un parseur maison. Un cas typique que nous avons déjà traité côté OpenAI dans notre tuto de routage de tickets.
Boucle d'outils : pourquoi l'API sans état change votre code
C'est le point qui piège. La doc impose des contraintes strictes sur plusieurs paramètres :
store: omis,falseounull.previous_response_id,conversation,prompt,moderation: omis ounull.background:false.truncation:"disabled".
Traduction : Mistral ne stocke rien. Si vous venez d'une API qui chaîne les tours avec un identifiant de réponse précédente, ce réflexe ne marche pas ici. Votre application garde l'historique et renvoie à chaque tour les items précédents dans input.
La boucle d'un agent avec un outil ressemble à ceci :
- Envoyer
input+ définitionstools. - Lire
output. Si un item est un appel de fonction, exécuter la fonction chez vous (Mistral n'exécute pas vos fonctions). - Ajouter à votre liste d'historique les items de sortie du modèle et un item « résultat de fonction » avec le même identifiant d'appel.
- Rappeler
/v1/responsesavec l'historique complet. Répéter jusqu'à ce qu'il n'y ait plus d'appel d'outil.
history = [{"role": "user", "content": question}]
while True:
resp = client.responses.create(
model="mistral-large-4", input=history, tools=TOOLS
)
history += resp.output
calls = [i for i in resp.output if i.type == "function_call"]
if not calls:
break
for c in calls:
history.append({
"type": "function_call_output",
"call_id": c.call_id,
"output": run_tool(c.name, c.arguments),
})
Deux détails de la doc à garder en tête : tool_choice accepte none, auto, required ou une fonction précise, et parallel_tool_calls existe, donc votre boucle doit gérer plusieurs appels dans le même tour. En revanche, max_tool_calls est accepté mais ignoré pour l'instant : mettez votre propre garde-fou (un compteur d'itérations) sinon une boucle folle brûle vos tokens.
Ce n'est pas un défaut en soi. Sans état côté serveur, rien de vos échanges n'est conservé chez l'éditeur, ce qui simplifie la réponse à une question RGPD. Le coût : vous renvoyez tout l'historique à chaque tour, donc la facture d'entrée grossit. Utilisez prompt_cache_key (acheminement du cache) et lisez notre tuto sur le appel d'outils programmatique pour réduire les tokens si vos agents enchaînent beaucoup d'appels.
Compter ses tokens avant l'appel : l'endpoint input_tokens
Autre nouveauté utile : POST /v1/responses/input_tokens renvoie une estimation d'entrée pour la conversation, les instructions et les définitions d'outils. Le SDK expose count_input_tokens en Python et countInputTokens en TypeScript.
Usage pratique pour une PME : placer un contrôle avant chaque tour d'agent. Si l'historique dépasse un seuil que vous fixez (disons 150 000 tokens), vous résumez les anciens tours avant d'envoyer. Comme truncation est forcé à disabled, le serveur ne coupera rien à votre place : c'est à vous de le faire, sinon l'appel échoue.
Le champ usage de la réponse détaille les tokens d'entrée, de sortie, mis en cache et de raisonnement. Loguez-les par appel. Pour voir où part l'argent d'un agent, un outil d'observabilité fait gagner du temps ; nous avons comparé six plateformes dans notre comparatif d'observabilité des agents.
Combien coûte Mistral Large 4 via la Responses API en France
Aucun supplément n'est mentionné pour la Responses API elle-même dans ce que nous avons pu consulter : la facturation suit le modèle. Pour Mistral Large 4, un récapitulatif du 30 octobre cite 0,70 $ le million de tokens d'entrée et 2,10 $ en sortie. Les notes de version de Mistral parlent par ailleurs d'une remise de 50 % pendant deux semaines au lancement, sans donner de grille complète. Vérifiez la grille officielle avant de chiffrer un budget : nous n'avons pas pu la croiser avec une seconde source.
Ordre de grandeur pour un agent qui renvoie 20 000 tokens d'historique et produit 1 000 tokens par tour : environ 0,016 $ le tour au tarif cité, soit à peu près 16 $ pour 1 000 tours. À ce prix, le surcoût de l'absence d'état reste modeste tant que l'historique est contrôlé. Il explose si vous laissez traîner 200 000 tokens à chaque appel.
Contexte modèle : Mistral Large 4 est un MoE de 1 000 milliards de paramètres dont 49 milliards actifs, avec 1 million de tokens de contexte. Les poids ont été publiés le 29 octobre sous une licence MIT modifiée (revente en Model-as-a-Service soumise à licence commerciale) selon le même récapitulatif, alors que la page du checkpoint principal affichait encore une date au 31 octobre. Notre analyse de la preview de Mistral Large 4 date d'il y a 22 jours : ce qui a bougé depuis, c'est l'accès aux poids et cette API.
Responses API Mistral ou chat completions : lequel garder ?
Gardez chat completions si votre agent est stable, sans outils complexes, et que rien ne vous manque. La preview n'offre aucune garantie de stabilité de contrat, et la doc liste plusieurs fonctions verrouillées.
Passez à la Responses API si :
- vous affichez le raisonnement ou la progression à l'utilisateur et voulez des items séparés ;
- vous voulez des sorties JSON Schema et un comptage de tokens avant l'appel ;
- vous préférez une API qui ne retient rien côté serveur.
Ne la choisissez pas si vous comptiez sur l'historique géré par le fournisseur, l'exécution en arrière-plan ou une troncature automatique : background et truncation sont verrouillés. Pour ce genre d'agent hébergé, l'offre d'OpenAI est d'une autre nature, et plus chère à cause du bac à sable.
Les trois pièges à anticiper avant de migrer
- Preview = contrat mouvant. Isolez les appels derrière une petite fonction maison. Si un champ change, vous corrigez un fichier.
- Raisonnement et plafond de sortie. Les tokens de raisonnement comptent dans
max_output_tokens. Testez avec 4 096 avant de descendre. - Boucle sans fin.
max_tool_callsest ignoré. Comptez les itérations vous-même et coupez à 8 ou 10.
Conseil de méthode : migrez d'abord un flux non critique (tri d'emails, résumé interne), comparez les sorties sur 50 cas réels, puis seulement basculez le reste.
Verdict
La Responses API de Mistral est une bonne base pour des agents propres, à condition d'accepter de tenir l'historique soi-même. Elle séduira les équipes qui veulent un fournisseur européen sans stockage côté serveur ; elle décevra celles qui attendent un agent hébergé clé en main. Notre conseil : un flux pilote cette semaine, la production quand la preview sera sortie de preview. Pour préparer l'étape suivante, relisez la doc officielle avant de coder, pas après.