Envoyer Plusieurs Images dans un Message
Analyser plusieurs images à la fois
L’API Vision de Mistral ne se limite pas à une seule image par message. Vous pouvez envoyer plusieurs images dans un même appel pour demander au modèle de les comparer, les synthétiser ou les analyser conjointement.
Cette capacité est essentielle pour des cas d’usage comme la comparaison avant/après, l’analyse de séries de documents, ou la vérification de conformité visuelle.
Structure d’un message multi-images
Le principe est simple : ajoutez plusieurs éléments image_url dans le tableau content :
message = {
"role": "user",
"content": [
{"type": "text", "text": "Comparez ces deux images et décrivez les différences."},
{"type": "image_url", "image_url": "https://exemple.com/image1.jpg"},
{"type": "image_url", "image_url": "https://exemple.com/image2.jpg"}
]
}
Vous pouvez mélanger des images par URL et en Base64 dans le même message.
Exemple : comparaison de deux images
from mistralai import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Vous êtes un expert en contrôle qualité. Comparez les images fournies avec précision."
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "Voici deux photos du même produit. La première est la référence, la seconde est l'échantillon reçu. Identifiez toutes les différences."
},
{"type": "image_url", "image_url": "https://exemple.com/reference.jpg"},
{"type": "image_url", "image_url": "https://exemple.com/echantillon.jpg"}
]
}
]
)
print(response.choices[0].message.content)
Intercaler texte et images
Vous pouvez également intercaler du texte entre les images pour fournir du contexte :
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Voici le plan architectural original :"},
{"type": "image_url", "image_url": "https://exemple.com/plan-original.png"},
{"type": "text", "text": "Et voici la photo du bâtiment construit :"},
{"type": "image_url", "image_url": "https://exemple.com/photo-batiment.jpg"},
{"type": "text", "text": "Le bâtiment est-il conforme au plan ? Listez les écarts."}
]
}
]
)
Ce format améliore la compréhension du modèle en associant chaque image à son contexte.
Traitement par lot avec Base64
Pour analyser un dossier d’images locales :
import base64
import os
from pathlib import Path
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def encoder_image(chemin):
with open(chemin, "rb") as f:
b64 = base64.standard_b64encode(f.read()).decode("utf-8")
ext = Path(chemin).suffix.lower()
mime = {"jpg": "jpeg", "jpeg": "jpeg", "png": "png", "webp": "webp"}.get(ext.lstrip("."), "jpeg")
return f"data:image/{mime};base64,{b64}"
# Charger toutes les images d'un dossier
dossier = Path("captures/")
images = sorted(dossier.glob("*.png"))
# Construire le contenu du message
content = [{"type": "text", "text": f"Analysez ces {len(images)} captures d'écran et résumez les éléments communs."}]
for img in images[:5]: # Limiter à 5 images max
content.append({"type": "image_url", "image_url": encoder_image(img)})
response = client.chat.complete(
model="mistral-small-latest",
messages=[{"role": "user", "content": content}]
)
print(response.choices[0].message.content)
Limites du multi-images
Quelques contraintes à garder en tête :
- Nombre d’images : il n’y a pas de limite stricte documentée, mais au-delà de 5-10 images, la qualité d’analyse peut diminuer et le coût en tokens augmente fortement
- Tokens cumulés : chaque image consomme 800-1500 tokens. Avec 5 images, le prompt peut atteindre 5 000-7 500 tokens rien qu’en images
- Fenêtre de contexte : le total (images + texte + réponse) ne doit pas dépasser la fenêtre de contexte du modèle
Estimation du coût multi-images
def estimer_cout_multi_images(nb_images, tokens_par_image=1000, tokens_texte=100, tokens_reponse=500):
"""Estime le nombre total de tokens pour un appel multi-images."""
total_input = (nb_images * tokens_par_image) + tokens_texte
total = total_input + tokens_reponse
print(f"Images : {nb_images} x {tokens_par_image} = {nb_images * tokens_par_image} tokens")
print(f"Texte prompt : {tokens_texte} tokens")
print(f"Réponse estimée : {tokens_reponse} tokens")
print(f"Total estimé : {total} tokens")
return total
estimer_cout_multi_images(3)
# Images : 3 x 1000 = 3000 tokens
# Texte prompt : 100 tokens
# Réponse estimée : 500 tokens
# Total estimé : 3600 tokens
Stratégie pour les grands volumes
Si vous devez analyser plus de 5 images, envisagez ces approches :
- Analyse séquentielle : traitez les images une par une, puis agrégez les résultats
- Groupement par lots : envoyez des groupes de 3-5 images par appel
- Pré-filtrage : utilisez un modèle léger (Small) pour filtrer, puis Large pour les cas importants
# Analyse séquentielle avec agrégation
resultats = []
for img_path in images:
response = client.chat.complete(
model="mistral-small-latest",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Décrivez brièvement le contenu de cette image."},
{"type": "image_url", "image_url": encoder_image(img_path)}
]
}]
)
resultats.append(response.choices[0].message.content)
# Synthèse finale (texte seul)
synthese = client.chat.complete(
model="mistral-small-latest",
messages=[{
"role": "user",
"content": f"Voici les descriptions de {len(resultats)} images :\n\n" +
"\n---\n".join(resultats) +
"\n\nFaites une synthèse globale."
}]
)
Points clés à retenir
- Vous pouvez envoyer plusieurs images dans un même message en ajoutant plusieurs éléments
image_url - Intercalez du texte entre les images pour fournir du contexte au modèle
- Chaque image ajoute 800-1500 tokens — estimez vos coûts avant l’appel
- Au-delà de 5 images, préférez une stratégie séquentielle ou par lots
- URL et Base64 peuvent être mélangés dans le même message