Prompts multimodaux avec images
Sur cette page
Claude lit les images : photos, captures d’écran, graphiques, pages scannées, diapositives. Cette leçon montre comment les joindre à un message, sous les trois formes que l’API accepte aujourd’hui, avec quelles limites, et comment rédiger un prompt visuel qui tient ses promesses : étiqueter les images, être précis, donner un exemple. Elle se termine par l’exercice du carnet, transcrire et résumer un article de recherche à partir de captures, et par le quiz du cours.
Le contenu en liste de blocs
Jusqu’ici, content était une chaîne. C’est un raccourci : {"role": "user", "content": "Raconte-moi une histoire"} équivaut à {"role": "user", "content": [{"type": "text", "text": "Raconte-moi une histoire"}]}. La forme en liste permet de mêler plusieurs blocs dans un même message, et c’est elle qu’exigent les images : un bloc image à côté d’un ou plusieurs blocs text.
messages = [{
"role": "user",
"content": [
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": base64_string}},
{"type": "text", "text": "Qu'aurait pu faire cette personne pour éviter cela ?"},
],
}]
Trois façons de fournir une image
Le carnet de 2024 précisait que la source devait être encodée en base64. L’API en accepte aujourd’hui trois :
base64: l’image encodée dans la requête, avec sonmedia_type;url: l’adresse d’une image publique, que l’API va chercher elle-même :{"type": "url", "url": image_url};file: l’identifiant d’un fichier déposé une fois par l’API Files et réutilisé ensuite :{"type": "file", "file_id": "…"}.
La dernière évite de renvoyer les mêmes octets à chaque tour d’une longue conversation. Sur Amazon Bedrock et sur Claude via Google Cloud géré par Google, seule la forme base64 est disponible.
Formats acceptés : JPEG, PNG, GIF et WebP (pour un GIF animé, seule la première image est lue). Limites sur l’API Claude au 5 novembre 2026 : 10 Mo par image en base64, 8 000 × 8 000 pixels au plus (plus strict au-delà de 20 images dans une requête), 600 images par requête (100 pour les modèles à fenêtre de 200 000 jetons), dans une requête de 128 Mo au maximum. Une image coûte des jetons selon sa taille, par carrés de 28 × 28 pixels ; au-delà d’une résolution maximale (2 576 pixels de grand côté depuis Claude 4.7), elle est réduite avant traitement, ce qui plafonne son coût.
Encoder une image locale
import base64
import mimetypes
def create_image_message(image_path):
"""Renvoie un bloc image prêt à placer dans `content`."""
with open(image_path, "rb") as image_file:
data = base64.b64encode(image_file.read()).decode("utf-8")
media_type, _ = mimetypes.guess_type(image_path) # image/png, image/jpeg…
return {"type": "image", "source": {"type": "base64", "media_type": media_type, "data": data}}
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[{"role": "user", "content": [
create_image_message("animal1.png"),
{"type": "text", "text": "Où pourrais-je observer cet animal dans le monde ?"},
]}],
)
print("".join(b.text for b in response.content if b.type == "text"))
Sans texte, Claude décrit l’image ; avec une question, il y répond. Pour une image en ligne, la forme url évite tout le code de téléchargement et d’encodage que le carnet écrivait avec httpx.
image_url = "…" # adresse publique d'une image JPEG, PNG, GIF ou WebP
{"type": "image", "source": {"type": "url", "url": image_url}}
Plusieurs images
On peut placer plusieurs blocs image dans un même message. Le carnet envoyait trois photos (un pygargue, un grizzli, un porc-épic) avec la question « quels sont ces animaux ? » : Claude 3.5 Sonnet les nommait tous, Claude 3 Haiku ne parlait que du porc-épic. Il suffisait d’étiqueter chaque image d’un bloc texte, « Image 1 : », « Image 2 : », pour que le petit modèle les traite toutes. Les modèles actuels gèrent bien mieux les images multiples, mais l’étiquette reste une bonne habitude : elle permet aussi de les désigner dans la question et dans la réponse. La documentation ajoute que Claude travaille mieux quand les images précèdent le texte qui les concerne.
content = [
{"type": "text", "text": "Image 1 :"}, create_image_message("animal1.png"),
{"type": "text", "text": "Image 2 :"}, create_image_message("animal2.png"),
{"type": "text", "text": "Image 3 :"}, create_image_message("animal3.png"),
{"type": "text", "text": "Quels sont ces animaux ?"},
]
Bien écrire un prompt visuel
Être précis. Sur une photo de groupe dont deux personnes sont coupées par le cadre, « combien de personnes ? » donnait 7 au lieu de 8. La version précise demandait de compter aussi les personnes partiellement visibles, même réduites à un bras, et d’examiner chaque zone de l’image. Le carnet ajoutait des balises <thinking> pour faire raisonner le modèle ; les modèles actuels réfléchissent d’eux-mêmes, et l’on garde surtout la précision de la consigne.
Donner un exemple. Pour décrire des diapositives en JSON (couleur de fond, titre, texte, description de l’illustration), le carnet montrait un échange complet : une diapositive et sa description attendue, puis la nouvelle diapositive. C’est la technique des exemples par l’historique de la leçon 2, appliquée aux images : un tour user avec l’image d’exemple, un tour assistant avec le JSON attendu, puis le tour user à traiter. Pour garantir un JSON valide, ajoutez les sorties structurées.
Connaître les limites. La documentation en liste plusieurs : Claude peut se tromper sur des images de mauvaise qualité, tournées ou très petites (moins de 200 pixels) ; ses dénombrements sont approximatifs, surtout pour beaucoup de petits objets, ce qui rejoint l’exemple de la photo de groupe ; il refuse de nommer les personnes d’après une image ; il ne sait pas dire si une image a été générée par une IA ; il n’est pas conçu pour interpréter des examens d’imagerie médicale complexes. Pour les usages à fort enjeu, une personne vérifie.
À vous de jouer
Transcrire et résumer un article. Le dossier du carnet contient cinq captures d’un article de recherche d’Anthropic sur le « many-shot jailbreaking ». Transcrivez chaque page par une requête séparée (une image, la consigne de transcrire fidèlement le texte), assemblez les cinq transcriptions, puis demandez un résumé non technique de l’ensemble. Le carnet conseille une requête par page plutôt que les cinq images d’un coup.
Voir une solution
pages = [f"research_paper/page{i}.png" for i in range(1, 6)]
def text_of(response):
return "".join(b.text for b in response.content if b.type == "text")
transcriptions = []
for page in pages:
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=8000,
messages=[{"role": "user", "content": [
create_image_message(page),
{"type": "text", "text": "Transcris fidèlement tout le texte de cette page, sans commentaire."},
]}],
)
transcriptions.append(text_of(response))
article = "\n\n".join(transcriptions)
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=8000,
messages=[{"role": "user",
"content": f"<article>{article}</article>\n\nRésume cet article de recherche pour un public non technique, en trois paragraphes."}],
)
print(text_of(response))
Sources officielles : 06_vision.ipynb (anthropics/courses, archivé) · Vision (documentation Claude : sources, formats, limites, coût, relue le 5 novembre 2026)
Points clés à retenir
- Une image se joint dans la forme en liste de
content, sous un blocimage, à côté de blocstext. - Trois sources :
base64,url(image publique) oufile(API Files) ; base64 seule sur Bedrock et Google Cloud géré par Google. - JPEG, PNG, GIF, WebP ; 10 Mo par image, 8 000 pixels de côté, jusqu’à 600 images par requête ; une image coûte des jetons selon sa taille.
- Étiqueter les images, les placer avant le texte, écrire une consigne précise, donner un exemple.
Quiz de fin de formation
1. Pourquoi ne faut-il plus lire `response.content[0].text` ?
Parce que content est une liste de blocs et que les modèles actuels réfléchissent avant de répondre : le premier bloc peut être un bloc thinking, sans attribut text. On parcourt les blocs et on garde ceux de type text.
2. Que se passe-t-il si `messages` se termine par un message `assistant` partiel ?
C’est le préremplissage : depuis Claude 4.6, la requête renvoie une erreur 400. Pour imposer un début ou un format, on le demande dans la consigne, ou on utilise les sorties structurées.
3. Quel modèle la documentation conseille-t-elle quand on ne sait pas lequel choisir, et comment décide-t-on ensuite ?
Claude Opus 5.5. On décide ensuite par une évaluation sur ses propres cas : descendre vers Sonnet ou Haiku, ou baisser l’effort, si la qualité tient ; monter vers Fable 5.1 si Opus 5.5 reste en deçà même aux efforts élevés.
4. Que devient `temperature` sur la version d'API 2026-10-21 ?
Une requête Messages qui contient temperature, top_p ou top_k renvoie une erreur 400, sur tous les modèles et même à la valeur par défaut. On les supprime ; la profondeur de réflexion se règle avec output_config.effort.
5. En streaming, quels deltas faut-il afficher pour montrer la réponse à l'utilisateur ?
Les seuls text_delta. Les thinking_delta, signature_delta et input_json_delta appartiennent à la réflexion et aux appels d’outils ; stream.text_stream fait ce tri pour vous.
6. Quelles sont les trois façons de fournir une image à l'API ?
Une source base64 dans la requête, une source url vers une image publique que l’API va chercher, ou une source file qui désigne un fichier déposé par l’API Files.
Bilan du cours
Un compte, une clé hors du code, un client ; une conversation en liste de messages, lue bloc par bloc ; un modèle choisi par l’évaluation plutôt que par réputation ; quelques paramètres qui tiennent la réponse, et l’effort qui règle la réflexion ; le streaming pour ne jamais faire attendre ; des images jointes comme des blocs. Ce sont les fondations de tout le reste. Pour continuer : Prompt Engineering interactif pour écrire de meilleurs prompts, L’utilisation d’outils (tool use) pour donner des capacités à Claude, Évaluation de prompts pour mesurer.
Crédits et licence — Adaptation française du cours « Anthropic API fundamentals » du dépôt anthropics/courses (Anthropic), archivé en lecture seule le 15 septembre 2026 et publié sous licence CC BY-NC 4.0 ; cette adaptation, qui le traduit, le remanie, met son code à jour pour les modèles de novembre 2026 et y intègre des repères du cours « Claude Platform 101 » de Claude Academy, est diffusée sous la même licence.