0Pricing
AI Engineering Academy · Leçon

Générer des embeddings avec OpenAI

Utilisez les modèles text-embedding-3-small et text-embedding-3-large pour créer des embeddings de phrases, de paragraphes et de documents, puis comparez leurs compromis en matière de qualité et de coût.

Générer des embeddings avec OpenAI est une leçon AI Engineering Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Engineering Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Engineering Academy comprend 4 leçons au total.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

OpenAI Embedding Models Overview

OpenAI offers two production embedding models: text-embedding-3-small and text-embedding-3-large. The small model produces 1536-dimensional vectors and is 5x cheaper per token, while the large model produces 3072-dimensional vectors with higher accuracy on benchmarks. For most RAG applications, the small model is the right starting point.

Making Your First Embedding Call

The client.embeddings.create() method takes a model name and an input string or list. It returns a response object with a data list, where each item has an embedding attribute containing the vector as a Python list of floats.

Always store your API key in an environment variable — never hardcode it in source files.

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])

response = client.embeddings.create(
    model='text-embedding-3-small',
    input='What is retrieval-augmented generation?'
)

vector = response.data[0].embedding
print(f'Vector length: {len(vector)}')      # 1536
print(f'Type: {type(vector[0])}')           # float
print(f'Sample values: {vector[:3]}')       # [-0.02, 0.01, ...]

Embedding Batches Efficiently

Passing a list of strings to input embeds them all in one API round-trip. This is the recommended approach when indexing a document corpus. The response data list preserves the original order, making it easy to build a lookup dictionary.

Batches are limited to 2048 items per request and the total tokens across all inputs must stay within the model's token limit.

from openai import OpenAI

client = OpenAI()

documents = [
    'RAG stands for Retrieval-Augmented Generation.',
    'Embeddings convert text to numerical vectors.',
    'Pinecone is a managed vector database service.'
]

response = client.embeddings.create(
    model='text-embedding-3-small',
    input=documents
)

embeddings = [item.embedding for item in response.data]
print(f'Got {len(embeddings)} embeddings')
print(f'Each has {len(embeddings[0])} dimensions')

Reducing Embedding Dimensions

Both text-embedding-3 models support a dimensions parameter that truncates the output vector. For example, setting dimensions=256 returns a 256-element vector instead of 1536. Shorter vectors use less storage and compute, with a modest accuracy tradeoff.

This is useful when you want to experiment quickly or when storage cost matters more than peak retrieval quality.

from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
    model='text-embedding-3-small',
    input='Shorter vectors save storage and query time.',
    dimensions=256   # truncate from 1536 to 256
)

print(len(response.data[0].embedding))  # 256

Encoding Format: Base64 vs Float List

By default the API returns embeddings as a JSON array of floats (encoding_format='float'). You can request encoding_format='base64' to receive a compact base64-encoded binary blob, which transfers faster over the network for large batches.

When using base64, you need to decode it with NumPy: np.frombuffer(base64.b64decode(b64_str), dtype='float32').

import base64
import numpy as np
from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
    model='text-embedding-3-small',
    input='Base64 encoding transfers faster.',
    encoding_format='base64'
)

b64 = response.data[0].embedding
vector = np.frombuffer(base64.b64decode(b64), dtype='float32')
print(f'Decoded {len(vector)} floats')

Tracking Token Usage and Cost

Every embedding response includes a usage object with prompt_tokens. You pay per token: text-embedding-3-small costs $0.02 per million tokens and text-embedding-3-large costs $0.13 per million tokens (as of mid-2024).

Tracking usage lets you estimate how much it costs to index your entire corpus before you commit to a production run.

from openai import OpenAI

client = OpenAI()

texts = ['Document one content here.', 'Document two content here.']

response = client.embeddings.create(
    model='text-embedding-3-small',
    input=texts
)

tokens_used = response.usage.prompt_tokens
cost_usd = tokens_used * 0.00000002  # $0.02 per 1M tokens
print(f'Tokens: {tokens_used}, Cost: ${cost_usd:.6f}')

Comparing text-embedding-3-small vs large

The choice between small and large depends on your accuracy requirements and budget:

  • text-embedding-3-small: 1536D, faster, 5x cheaper, great for most RAG workloads
  • text-embedding-3-large: 3072D, higher MTEB benchmark scores, better for multilingual content and complex semantic tasks

A common pattern is to prototype and validate retrieval quality with the small model, then switch to large only if evaluation metrics fall below your target.

Normalizing Embeddings for Dot Product Search

OpenAI returns L2-normalized embeddings, meaning each vector already has a magnitude of 1. This means you can use the dot product as a fast approximation of cosine similarity without an extra normalization step, which is important when searching millions of vectors where micro-optimizations add up.

import numpy as np
from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
    model='text-embedding-3-small',
    input='Are OpenAI embeddings normalized?'
)

vec = np.array(response.data[0].embedding)
magnitude = np.linalg.norm(vec)
print(f'Vector magnitude: {magnitude:.6f}')  # very close to 1.0

Handling Large Documents

The text-embedding-3-small model accepts up to 8191 tokens per input. If your document exceeds this limit, the API will return an error. The standard solution is to chunk the document first (typically 200-500 tokens per chunk) and embed each chunk separately.

This chunking is not just a technical requirement — it also produces better retrieval because embedding smaller focused pieces returns more precise results than embedding entire pages.

import tiktoken

enc = tiktoken.encoding_for_model('text-embedding-3-small')

def count_tokens(text):
    return len(enc.encode(text))

max_tokens = 8191
text = 'Very long document content...'  # pretend this is huge

if count_tokens(text) > max_tokens:
    print('Document too long — chunk before embedding')
else:
    print(f'Safe to embed: {count_tokens(text)} tokens')

Async Embedding for High Throughput

When indexing thousands of documents, use the async OpenAI client with asyncio.gather to send multiple embedding requests concurrently. This is much faster than sequential calls because the bottleneck is network latency, not CPU.

Always add rate limit handling with exponential backoff when running concurrent requests to avoid hitting the tokens-per-minute limit.

import asyncio
from openai import AsyncOpenAI

async def embed_batch(texts):
    client = AsyncOpenAI()
    response = await client.embeddings.create(
        model='text-embedding-3-small',
        input=texts
    )
    return [item.embedding for item in response.data]

async def main():
    batches = [['doc1', 'doc2'], ['doc3', 'doc4']]
    results = await asyncio.gather(*[embed_batch(b) for b in batches])
    all_embeddings = [emb for batch in results for emb in batch]
    print(f'Embedded {len(all_embeddings)} documents')

asyncio.run(main())

Caching Embeddings to Save Cost

Generating embeddings for the same text multiple times wastes money and time. Cache embeddings in a dictionary keyed by the text string (or a hash of it) and persist this cache to disk between sessions.

For production systems, store embeddings in a vector database that deduplicates by document ID. Only re-embed a document when its content actually changes, not on every indexing run.

import json, hashlib, os
from openai import OpenAI

CACHE_FILE = '/tmp/embedding_cache.json'
client = OpenAI()

try:
    cache = json.load(open(CACHE_FILE))
except FileNotFoundError:
    cache = {}

def get_embedding(text):
    key = hashlib.md5(text.encode()).hexdigest()
    if key not in cache:
        r = client.embeddings.create(model='text-embedding-3-small', input=text)
        cache[key] = r.data[0].embedding
        json.dump(cache, open(CACHE_FILE, 'w'))
    return cache[key]

vec = get_embedding('Caching saves API costs.')
print(f'Retrieved {len(vec)}-dim embedding')

Quick Check

Test your understanding of AI Engineering concepts from this lesson.

Lesson Recap

In this lesson you learned: text-embedding-3-small is the cost-effective choice for most RAG workloads, batch embedding multiple texts in one API call is more efficient than sequential calls, and the dimensions parameter can reduce vector size to trade accuracy for storage savings. Next up we build a semantic search system using these embeddings and NumPy.

Questions Fréquemment Posées

La leçon « Générer des embeddings avec OpenAI » est-elle gratuite ?

Oui — le texte complet de « Générer des embeddings avec OpenAI » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Engineering Academy, passe à CoddyKit PRO. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Générer des embeddings avec OpenAI » ?

Utilisez les modèles text-embedding-3-small et text-embedding-3-large pour créer des embeddings de phrases, de paragraphes et de documents, puis comparez leurs compromis en matière de qualité et de c… Tu pratiques AI Engineering Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Engineering Academy ?

Aucune expérience préalable n'est requise. AI Engineering Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Générer des embeddings avec OpenAI » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Engineering Academy ?

Oui. Chaque leçon AI Engineering Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Que sont les embeddings vectoriels ?
  2. Générer des embeddings avec OpenAI
  3. Recherche sémantique avec NumPy
  4. Regrouper et visualiser des embeddings
← Retour à AI Engineering Academy