Aller au contenu principal

L'API Embeddings : modèles et dimensions

Mis à jour le 29 juillet 2026

Objectifs

  • Maîtriser l’appel client.embeddings.create()
  • Comprendre les différences entre les modèles d’embedding
  • Utiliser la réduction de dimensions

L’appel de base

Toute l’API Embeddings d’OpenAI tient dans une seule méthode, client.embeddings.create(), à laquelle vous passez un texte et un nom de modèle :

from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
    input="Bonjour, comment allez-vous ?",
    model="text-embedding-3-large"
)

embedding = response.data[0].embedding
print(f"Type : {type(embedding)}")        # list
print(f"Longueur : {len(embedding)}")      # 3072
print(f"Extrait : {embedding[:3]}")        # [0.023, -0.041, 0.012]

L’objet retourné n’est pas le vecteur lui-même, mais une enveloppe qui en contient plusieurs, car l’API est conçue pour traiter des lots. Vous y trouverez data, une liste d’objets portant chacun le champ embedding (le vecteur) et index (sa position dans le batch envoyé) ; model, le modèle réellement utilisé ; et usage.prompt_tokens, le nombre de tokens facturés. Ce dernier champ mérite qu’on le journalise dès le premier jour : c’est la seule mesure fiable de ce que coûte votre indexation.

Les deux modèles disponibles

text-embedding-3-large est le modèle haute performance. Ses 3 072 dimensions capturent les nuances sémantiques les plus fines, ce qui le rend pertinent pour la recherche sur de grands corpus, pour les pipelines RAG exigeants et, plus généralement, pour les cas où la précision prime sur le coût. Si un utilisateur formule ses questions de façon détournée ou si vos documents traitent d’un domaine technique dense, la différence se voit dans le classement des résultats.

text-embedding-3-small est plus compact avec ses 1 536 dimensions, et il offre un rapport qualité/prix excellent. C’est le bon choix pour la classification de texte, les recommandations, le prototypage rapide et les applications à fort volume, où la question n’est pas de départager deux documents presque identiques mais de séparer des thèmes clairement distincts. Une boucle suffit à vérifier ce que chacun renvoie :

# Comparer les deux modèles
for model_name in ["text-embedding-3-small", "text-embedding-3-large"]:
    resp = client.embeddings.create(
        input="Intelligence artificielle",
        model=model_name
    )
    vec = resp.data[0].embedding
    print(f"{model_name}: {len(vec)} dimensions")

Embeddings par lots

Un corpus réel ne s’indexe pas texte par texte : chaque appel HTTP coûte un aller-retour réseau, et mille documents traités individuellement représentent mille latences accumulées. L’API accepte jusqu’à 2 048 textes en un seul appel, et le champ index vous permet de recoller chaque vecteur au bon document.

textes = [
    "L'apprentissage automatique progresse rapidement",
    "Le deep learning révolutionne la vision par ordinateur",
    "Les bases de données vectorielles stockent des embeddings",
    "Python est le langage préféré des data scientists"
]

response = client.embeddings.create(
    input=textes,
    model="text-embedding-3-large"
)

for item in response.data:
    print(f"Texte {item.index}: vecteur de {len(item.embedding)} dimensions")

print(f"Tokens consommés : {response.usage.prompt_tokens}")

En pratique, regroupez vos textes par lots de 100 à 2 048 selon votre volume : les petits lots facilitent la reprise après incident, les gros réduisent le nombre d’appels. Surveillez usage.prompt_tokens à chaque itération pour estimer les coûts au fil de l’eau plutôt que de les découvrir sur la facture, et prévoyez un retry exponentiel : un dépassement de rate limit est une erreur transitoire, pas une raison d’interrompre une indexation de trois heures.

Réduction de dimensions

Les modèles text-embedding-3-* acceptent un paramètre dimensions qui retourne des vecteurs plus courts que la taille native :

# Vecteur complet : 3072 dimensions
full = client.embeddings.create(
    input="Test de réduction",
    model="text-embedding-3-large"
)

# Vecteur réduit : 256 dimensions
reduced = client.embeddings.create(
    input="Test de réduction",
    model="text-embedding-3-large",
    dimensions=256
)

print(f"Complet : {len(full.data[0].embedding)} dim")    # 3072
print(f"Réduit : {len(reduced.data[0].embedding)} dim")  # 256

Le mécanisme est simple : la réduction tronque le vecteur puis le re-normalise, et comme les premières dimensions portent le plus d’information, la dégradation reste très progressive. Le tableau ci-dessous donne les repères habituels pour arbitrer entre qualité et stockage.

DimensionsQualité relativeStockageCas d’usage
3 072100 %~24 KoRecherche haute précision
1 536~98 %~12 KoBon compromis général
512~93 %~4 KoFort volume, coût réduit
256~88 %~2 KoPrototypage, classification simple

Retenez qu’un choix de dimension vous engage : tous les vecteurs d’un même index doivent avoir la même taille, et changer d’avis impose de tout recalculer.

Gestion des tokens

Les modèles d’embedding plafonnent à 8 191 tokens par texte, et l’API retourne une erreur au-delà. Mieux vaut donc mesurer avant d’envoyer, plutôt que de rattraper une exception au milieu d’un lot :

import tiktoken

encoder = tiktoken.get_encoding("cl100k_base")

texte = "Un texte potentiellement long..."
tokens = encoder.encode(texte)

if len(tokens) > 8191:
    # Tronquer
    texte_tronque = encoder.decode(tokens[:8191])
    print(f"Texte tronqué de {len(tokens)} à 8191 tokens")

La troncature est un filet de sécurité, pas une stratégie : un document long tronqué perd sa fin, et la fin contient souvent la réponse recherchée. Le vrai traitement des documents volumineux passe par le découpage, que nous verrons plus loin dans le cours.

Résumé

  • client.embeddings.create() accepte un texte ou une liste de textes
  • text-embedding-3-large (3 072 dim) pour la précision, text-embedding-3-small (1 536 dim) pour le coût
  • Le paramètre dimensions permet de réduire la taille des vecteurs
  • Les lots (batch) de textes sont plus efficaces que les appels individuels
  • Limite de 8 191 tokens par texte