Gerando embeddings com a OpenAI
Use os modelos text-embedding-3-small e text-embedding-3-large para gerar embeddings de frases, parágrafos e documentos e compare suas compensações entre qualidade e custo.
Gerando embeddings com a OpenAI é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.
Visão geral dos modelos de embedding da OpenAI
A OpenAI oferece dois modelos de embedding para produção: text-embedding-3-small e text-embedding-3-large. O modelo pequeno produz vetores com 1536 dimensões e custa 5 vezes menos por token, enquanto o modelo grande produz vetores com 3072 dimensões e apresenta maior precisão em avaliações de referência. Para a maioria das aplicações RAG, o modelo pequeno é o ponto de partida ideal.
Fazendo sua primeira chamada de embedding
O método client.embeddings.create() recebe um nome de model e uma string ou lista em input. Ele retorna um objeto de resposta com uma lista data, na qual cada item tem um atributo embedding contendo o vetor como uma lista Python de números de ponto flutuante.
Armazene sempre sua chave de API em uma variável de ambiente — nunca a codifique diretamente nos arquivos de código-fonte.
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, ...]Processando lotes de embeddings com eficiência
Passar uma lista de strings para input gera todos os embeddings em uma única viagem de ida e volta à API. Essa é a abordagem recomendada ao indexar um corpus de documentos. A lista data da resposta preserva a ordem original, facilitando a criação de um dicionário de consulta.
Os lotes são limitados a 2048 itens por solicitação, e o total de tokens entre todas as entradas deve permanecer dentro do limite de tokens do modelo.
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')Reduzindo as dimensões dos embeddings
Os dois modelos text-embedding-3 aceitam um parâmetro dimensions que trunca o vetor de saída. Por exemplo, definir dimensions=256 retorna um vetor com 256 elementos em vez de 1536. Vetores mais curtos usam menos armazenamento e capacidade de processamento, com uma pequena redução de precisão.
Isso é útil quando você deseja experimentar rapidamente ou quando o custo de armazenamento é mais importante do que a qualidade máxima da recuperação.
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)) # 256Formato de codificação: Base64 versus lista de números de ponto flutuante
Por padrão, a API retorna embeddings como uma matriz JSON de números de ponto flutuante (encoding_format='float'). Você pode solicitar encoding_format='base64' para receber um bloco binário compacto codificado em base64, que é transferido mais rapidamente pela rede em lotes grandes.
Ao usar base64, você precisa decodificá-lo com 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')Acompanhando o uso de tokens e os custos
Cada resposta de embedding inclui um objeto usage com prompt_tokens. Você paga por token: text-embedding-3-small custa US$ 0,02 por milhão de tokens, e text-embedding-3-large custa US$ 0,13 por milhão de tokens (em meados de 2024).
Acompanhar o uso permite estimar quanto custará indexar todo o seu corpus antes de iniciar uma execução em produção.
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}')Comparando text-embedding-3-small e text-embedding-3-large
A escolha entre os modelos pequeno e grande depende dos seus requisitos de precisão e do seu orçamento:
- text-embedding-3-small: 1536D, mais rápido, 5 vezes mais barato, excelente para a maioria das cargas de trabalho RAG
- text-embedding-3-large: 3072D, pontuações mais altas no benchmark MTEB, melhor para conteúdo multilíngue e tarefas semânticas complexas
Um padrão comum é criar um protótipo e validar a qualidade da recuperação com o modelo pequeno, mudando para o grande apenas se as métricas de avaliação ficarem abaixo da sua meta.
Normalizando embeddings para pesquisa por produto escalar
A OpenAI retorna embeddings normalizados por L2, o que significa que cada vetor já tem magnitude 1. Isso permite usar o produto escalar como uma aproximação rápida da similaridade de cosseno, sem uma etapa adicional de normalização — algo importante ao pesquisar milhões de vetores, quando pequenas otimizações fazem diferença.
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.0Lidando com documentos grandes
O modelo text-embedding-3-small aceita até 8191 tokens por entrada. Se o seu documento exceder esse limite, a API retornará um erro. A solução padrão é dividir primeiro o documento em partes (normalmente de 200 a 500 tokens por parte) e gerar uma incorporação para cada parte separadamente.
Essa divisão não é apenas uma exigência técnica — ela também produz uma recuperação melhor, porque gerar incorporações de trechos menores e mais focados retorna resultados mais precisos do que gerar uma incorporação da página inteira.
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')Incorporações assíncronas para alto rendimento
Ao indexar milhares de documentos, use o cliente assíncrono da OpenAI com asyncio.gather para enviar várias solicitações de incorporação simultaneamente. Isso é muito mais rápido do que fazer chamadas sequenciais, porque o gargalo é a latência da rede, não a CPU.
Ao executar solicitações simultâneas, sempre inclua um tratamento do limite de solicitações com espera progressiva exponencial para evitar atingir o limite de tokens por minuto.
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())Armazenando incorporações em cache para reduzir custos
Gerar incorporações para o mesmo texto várias vezes desperdiça dinheiro e tempo. Armazene as incorporações em cache em um dicionário indexado pela cadeia de texto (ou por um hash dela) e mantenha esse cache no disco entre as sessões.
Em sistemas de produção, armazene as incorporações em um banco de dados vetorial que elimine duplicatas usando o ID do documento. Gere novamente a incorporação de um documento somente quando o conteúdo realmente mudar, não a cada execução da indexação.
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')Verificação rápida
Teste sua compreensão dos conceitos de Engenharia de IA desta lição.
Recapitulação da lição
Nesta lição, você aprendeu que: text-embedding-3-small é a opção econômica para a maioria das cargas de trabalho de RAG, gerar incorporações de vários textos em uma única chamada à API é mais eficiente do que fazer chamadas sequenciais e o parâmetro dimensions pode reduzir o tamanho do vetor, trocando precisão por economia de armazenamento. A seguir, construiremos um sistema de busca semântica usando essas incorporações e NumPy.
Aprenda Python com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 30
- Aulas
- 120
Perguntas Frequentes
A aula “Gerando embeddings com a OpenAI” é grátis?
Sim — o texto completo de “Gerando embeddings com a OpenAI” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.
O que vou aprender em “Gerando embeddings com a OpenAI”?
Use os modelos text-embedding-3-small e text-embedding-3-large para gerar embeddings de frases, parágrafos e documentos e compare suas compensações entre qualidade e custo. Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Engineering Academy?
Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Gerando embeddings com a OpenAI”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Engineering Academy?
Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que são embeddings vetoriais?
- Gerando embeddings com a OpenAI
- Busca semântica com NumPy
- Agrupando e visualizando embeddings