Generera embeddings med OpenAI
Använd modellerna text-embedding-3-small och text-embedding-3-large för att skapa embeddings av meningar, stycken och dokument och jämför avvägningarna mellan kvalitet och kostnad.
Generera embeddings med OpenAI är en gratis lektion i AI Engineering Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för AI Engineering Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI Engineering Academy innehåller totalt 4 lektioner.
Översikt över OpenAI:s inbäddningsmodeller
OpenAI erbjuder två inbäddningsmodeller för produktion: text-embedding-3-small och text-embedding-3-large. Den mindre modellen producerar vektorer med 1536 dimensioner och kostar fem gånger mindre per token, medan den större modellen producerar vektorer med 3072 dimensioner och har högre träffsäkerhet i benchmarktester. För de flesta RAG-tillämpningar är den mindre modellen en bra utgångspunkt.
Gör ert första inbäddningsanrop
Metoden client.embeddings.create() tar emot ett model-namn och en input-sträng eller lista. Den returnerar ett svarsobjekt med en lista i data, där varje objekt har attributet embedding som innehåller vektorn som en Python-lista med flyttal.
Lagra alltid API-nyckeln i en miljövariabel — hårdkoda den aldrig i källfiler.
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, ...]Bädda in batcher effektivt
Om ni skickar en lista med strängar till input bäddas alla in under en enda API-omgång. Detta är den rekommenderade metoden när ni indexerar en dokumentkorpus. Svarslistan data bevarar den ursprungliga ordningen, vilket gör det enkelt att skapa en uppslagsordbok.
Batcher är begränsade till 2048 objekt per begäran och det totala antalet token i alla indata måste ligga inom modellens tokenbegränsning.
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')Minska inbäddningarnas dimensioner
Båda modellerna i text-embedding-3-serien stöder parametern dimensions, som kapar den utgående vektorn. Om ni till exempel anger dimensions=256 returneras en vektor med 256 element i stället för 1536. Kortare vektorer kräver mindre lagring och beräkningskapacitet, med en måttlig kompromiss i träffsäkerhet.
Detta är användbart när ni vill experimentera snabbt eller när lagringskostnaden är viktigare än högsta möjliga kvalitet vid hämtning.
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)) # 256Kodningsformat: Base64 jämfört med flyttalslista
Som standard returnerar API:t inbäddningar som en JSON-array med flyttal (encoding_format='float'). Ni kan begära encoding_format='base64' för att få ett kompakt base64-kodat binärt block, som överförs snabbare över nätverket för stora batcher.
När ni använder base64 måste ni avkoda det med 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')Spåra tokenanvändning och kostnad
Varje inbäddningssvar innehåller ett usage-objekt med prompt_tokens. Ni betalar per token: text-embedding-3-small kostar 0,02 USD per miljon token och text-embedding-3-large kostar 0,13 USD per miljon token (i mitten av 2024).
Genom att spåra användningen kan ni uppskatta kostnaden för att indexera hela korpusen innan ni startar en produktionskörning.
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}')Jämför text-embedding-3-small och large
Valet mellan small och large beror på era krav på träffsäkerhet och er budget:
- text-embedding-3-small: 1536D, snabbare, fem gånger billigare, utmärkt för de flesta RAG-arbetsbelastningar
- text-embedding-3-large: 3072D, högre poäng i MTEB-benchmarken, bättre för flerspråkigt innehåll och komplexa semantiska uppgifter
Ett vanligt tillvägagångssätt är att prototypa och validera kvaliteten på hämtningen med small-modellen och sedan byta till large endast om utvärderingsmåtten ligger under ert mål.
Normalisera inbäddningar för sökning med skalärprodukt
OpenAI returnerar L2-normaliserade inbäddningar, vilket innebär att varje vektor redan har längden 1. Därför kan ni använda skalärprodukten som en snabb approximation av cosinuslikheten utan ett extra normaliseringssteg. Det är viktigt vid sökning bland miljontals vektorer, där små optimeringar tillsammans gör stor skillnad.
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.0Hantera stora dokument
Modellen text-embedding-3-small tar emot upp till 8191 tokens per indata. Om dokumentet överskrider denna gräns returnerar API:et ett fel. Standardlösningen är att först dela upp dokumentet i delar, vanligtvis 200–500 tokens per del, och skapa en embedding för varje del separat.
Denna uppdelning är inte bara ett tekniskt krav – den ger också bättre sökresultat, eftersom embeddings för mindre, fokuserade delar ger mer precisa resultat än embeddings för hela sidor.
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')Asynkron embedding för hög genomströmning
När Ni indexerar tusentals dokument bör Ni använda den asynkrona OpenAI-klienten tillsammans med asyncio.gather för att skicka flera embeddingförfrågningar samtidigt. Detta går mycket snabbare än sekventiella anrop, eftersom flaskhalsen är nätverkslatens och inte CPU:n.
Lägg alltid till hantering av hastighetsbegränsningar med exponentiell backoff när Ni kör samtidiga förfrågningar, så att Ni undviker att nå gränsen för antal tokens per minut.
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())Cacha embeddings för att sänka kostnaderna
Att generera embeddings för samma text flera gånger slösar både pengar och tid. Cacha embeddings i en dictionary med textsträngen, eller en hash av den, som nyckel och spara cachen på disk mellan sessionerna.
I produktionssystem bör Ni lagra embeddings i en vektordatabas som eliminerar dubbletter baserat på dokument-ID. Skapa endast en ny embedding för ett dokument när innehållet faktiskt har ändrats, inte vid varje indexeringskörning.
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')Snabbtest
Testa Era kunskaper om AI Engineering-begrepp från den här lektionen.
Sammanfattning av lektionen
I den här lektionen har Ni lärt Er att text-embedding-3-small är det kostnadseffektiva valet för de flesta RAG-arbetsbelastningar, att batch-embedding av flera texter i ett API-anrop är effektivare än sekventiella anrop och att parametern dimensions kan minska vektorstorleken för att byta viss träffsäkerhet mot minskad lagringsåtgång. Nästa steg är att bygga ett semantiskt söksystem med dessa embeddings och NumPy.
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Generera embeddings med OpenAI” gratis?
Ja – hela texten till ”Generera embeddings med OpenAI” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i AI Engineering Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i AI Engineering Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Generera embeddings med OpenAI”?
Använd modellerna text-embedding-3-small och text-embedding-3-large för att skapa embeddings av meningar, stycken och dokument och jämför avvägningarna mellan kvalitet och kostnad. Ni övar på AI Engineering Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI Engineering Academy?
Du behöver inga förkunskaper. Utbildningen i AI Engineering Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Generera embeddings med OpenAI”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI Engineering Academy-lektionen?
Ja. Varje AI Engineering Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Vad är vector embeddings?
- Generera embeddings med OpenAI
- Semantisk sökning med NumPy
- Klustring och visualisering av embeddings