Vision
Envoyez des images sous forme de parties de contenu : URI data: uniquement, 8 au maximum par requête, sur un message user, et voici comment une image est réservée.
Le content d'un message peut être un tableau de parties au lieu d'une chaîne :
{ type: "text", text } et { type: "image_url", image_url: { url } }. La forme en
chaîne simple reste inchangée.
import { readFile } from "node:fs/promises";
const bytes = await readFile("./receipt.png");
const dataUri = `data:image/png;base64,${bytes.toString("base64")}`;
const completion = await client.chat.completions.create({
model: "nova-lite",
messages: [
{
role: "user", // les images ne sont permises que sur un message user
content: [
{ type: "text", text: "Quel est le total sur ce reçu ?" },
{ type: "image_url", image_url: { url: dataUri } },
],
},
],
});Les parties sont transmises dans l'ordre où vous les avez envoyées. C'est cet ordre que voit le modèle : le normaliser (tout le texte, puis toutes les images) changerait la réponse.
URI data: uniquement
Une URL http(s) distante donne un 400, et le message indique quoi envoyer à la place.
C'est un refus délibéré et non un manque : l'entrée image du fournisseur est constituée
d'octets bruts, jamais d'une URL. L'honorer supposerait que Fleeex aille la chercher côté
serveur, de façon synchrone, sur le chemin de facturation. Cela ouvrirait une surface de
falsification de requête côté serveur dans un processus qui détient des identifiants
cloud, plus un téléchargement sans borne et une latence sans borne devant un appel de
modèle payant, pendant qu'une réservation est gelée sur le portefeuille.
// 400 : fleeex ne va pas chercher d'URL distante
{ type: "image_url", image_url: { url: "https://example.com/cat.png" } }
// correct
{ type: "image_url", image_url: { url: "data:image/png;base64,iVBORw0KGgo…" } }Récupérez-la vous-même, dans votre propre processus, et intégrez les octets.
Formats
png, jpeg (jpg est accepté comme alias, car c'est ce qu'envoient les vrais
clients), gif, webp.
Le type de média déclaré est confronté aux octets de signature de la charge utile. Une
divergence donne un 400, parce que le fournisseur refuserait de toute façon une image
mal étiquetée (un 502 pour quelque chose qui peut être nommé), et parce que Fleeex ne
transmettra pas autre chose que ce que vous avez déclaré.
Une URI data: malformée donne un 400, jamais un 502 : le base64 est confronté à
l'alphabet standard, avec le bon remplissage, avant d'être décodé, si bien que des
octets approximatifs ne sont jamais transmis comme s'ils étaient ceux que vous aviez
envoyés.
detail uniquement à auto
image_url.detail est accepté à 'auto' (la valeur par défaut d'OpenAI, purement
décorative) et donne un 400 à low ou high. Ces valeurs sélectionnent une autre
tokenisation de l'image côté OpenAI : elles changeraient donc à la fois la réponse et les
tokens facturés, et le fournisseur n'a pas de réglage équivalent.
Limites
| Limite | |
|---|---|
| Images | 8 au maximum par requête, car c'est le niveau auquel la réservation est dimensionnée |
| Parties de contenu | 20 au maximum par message |
| Chaque image | se décode en 1 octet…512 Ko |
| Où | uniquement sur un message user |
Le fournisseur n'accepte un bloc image que dans un tour utilisateur : un prompt système n'a pas de bloc image du tout, et un tour assistant est la sortie du modèle lui-même. Les deux sont refusés ici, si bien que le refus du fournisseur n'arrive jamais.
En pratique, le plafond de 1 Mo sur le corps de la requête mord généralement avant la limite par image, puisque 8 × 512 Ko le dépasse largement. Les deux s'appliquent.
Une image est réservée à un plafond forfaitaire et pessimiste
Bon à savoir avant d'en envoyer huit : la réservation d'une image est un plafond forfaitaire par image, délibérément sans rapport avec sa taille en octets.
En effet, le coût en tokens d'une image suit ses dimensions, et non la taille de son
encodage compressé. Un JPEG de 40 Ko peut faire 8 mégapixels ; un PNG de 400 Ko peut être
une petite icône. Tarifer le base64 comme du texte sous-réserverait gravement une petite
image densément codée, et tarifer 512 Ko au tarif du texte mettrait un 402 sur toute
requête légitime. Chaque image ajoute donc à la réservation un nombre fixe de tokens
d'entrée, calculé au pire cas.
Deux conséquences :
- Vous pouvez recevoir un
402sur un portefeuille qui aurait couvert la facturation réelle. La réservation est un plafond, et une requête portant plusieurs images réserve d'emblée quelques dizaines de milliers de tokens d'entrée. - Vous restez facturé sur la mesure. La facturation vient de la consommation rapportée par le fournisseur, et la part inutilisée de la réservation est libérée au règlement de l'appel. Réserver large ne vous coûte rien d'autre que le temps pendant lequel les fonds sont immobilisés.
Fleeex n'analyse pas les dimensions en pixels : une image au-delà de la limite de
résolution du fournisseur est donc refusée par celui-ci (un 502) plutôt que nommée dans
un 400. Des images très compressées peuvent la dépasser en tenant sous 512 Ko.
Ce qui est stocké
Rien. Les octets d'image sont du contenu de prompt : jamais journalisés, jamais stockés, et jamais renvoyés en écho dans un message d'erreur.