Aller au contenu principal

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 :

  1. Analyse séquentielle : traitez les images une par une, puis agrégez les résultats
  2. Groupement par lots : envoyez des groupes de 3-5 images par appel
  3. 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