Embeddings

Embeddings

Metni anlamsal arama, erişim (RAG), öneriler, kümeleme ve yinelenenleri ayıklama için vektörlere dönüştürün; OpenAI'nin text-embedding-3 modelleriyle, OpenAI fiyatının yarısına. Aynı model ID'leri, aynı istek ve yanıt, aynı vektörler: OpenAI için yazılmış kod, base URL ile anahtarı değiştirdiğinizde çalışır.

POST/v1/embeddings
ModelID1M giriş token'ı başınaOpenAI’nin fiyatıBoyutlar
Text Embedding 3 Smalltext-embedding-3-small$0.01$0.021,536 veya daha az
Text Embedding 3 Largetext-embedding-3-large$0.065$0.133,072 veya daha az

Yalnızca gönderdiğiniz metin için ödeme yaparsınız, vektörler ücretsizdir. Her iki model de giriş başına 8,192 token'a kadar okur. Başlamak için Text Embedding 3 Small birebir: ucuz, hızlı ve çoğu arama ile RAG işi için yeterince iyi. Text Embedding 3 Large ise daha büyük ve daha doğru model; erişim kalitesi depolama ve fiyattan daha önemli olduğunda tercih edin.

Hızlı başlangıç

import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
response = client.embeddings.create(
model="text-embedding-3-small",
input="The food was delicious and the waiter was friendly.",
)
vector = response.data[0].embedding # a list of 1,536 floats
print(len(vector), response.usage.prompt_tokens) # 1536 10

Herhangi bir OpenAI SDK'sı çalışır: https://api.zurelay.com/v1 adresini gösterin, Zurelay anahtarınızı kullanın ve SDK'nın embeddings metodunu çağırın. Yanıt, OpenAI'nin formatında gelir:

Yanıt (vektör kısaltılmış)
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [-0.0022748, -0.0093183, 0.0158532, ..., -0.0028842]
}
],
"model": "text-embedding-3-small",
"usage": { "prompt_tokens": 10, "total_tokens": 10 }
}

data, gönderdiğiniz sırayla her giriş için bir embedding içerir ve her biri kendi index değeriyle gelir. usage.prompt_tokens, isteğin faturalandırıldığı değerdir. Başlıklar da bunu söyler: x-zurelay-model modelin adını, x-zurelay-input-tokens token sayısını verir; x-request-id ise isteği istek günlüğünüzde bulmanızı sağlar.

Parametreler

modelstringzorunlu
text-embedding-3-small veya text-embedding-3-large.
inputstring veya arrayzorunlu
Neyi embed edebilirsiniz: bir string, en fazla 2,048 string'den oluşan bir dizi, token ID'lerinden oluşan bir dizi (OpenAI'nin cl100k_base tokenizer'ından gelen tam sayılar) veya en fazla 2,048 bu tür diziden oluşan bir dizi. Her giriş en fazla 8,192 token'dır ve hiçbiri boş string olamaz.
encoding_formatstring
float (varsayılan): her embedding bir sayı dizisidir. base64: her biri little-endian float32 sayılarından oluşan bir base64 dizesidir; daha küçüktür, indirmesi daha hızlıdır. Bkz. Base64.
dimensionsinteger
Vektörü kısaltın: text-embedding-3-small için 1 ile 1,536, text-embedding-3-large için 1 ile 3,072 arası. Tam uzunluk için boş bırakın. Bkz. Daha kısa vektörler.
userstring
İsteğe bağlı: OpenAI'nin API'sinde olduğu gibi, isteğin hangi son kullanıcı adına yapıldığını belirten bir ID. Kabul edilir, vektörlerde hiçbir şeyi değiştirmez.

Toplu istekler

Tek istekte çok sayıda metin gönderin: input en fazla 2,048 öğe alan bir dizi kabul eder ve yanıtlar aynı sırayla döner. Bin metin içeren tek bir istek, bin istekten çok daha hızlıdır ve maliyeti aynıdır: ödemeyi istek başına değil token başına yaparsınız. Her isteği toplamda 300,000 token'ın altında tutun.

# pip install tiktoken
import tiktoken
# The tokenizer text-embedding-3 counts with, to keep each request under the limits
enc = tiktoken.get_encoding("cl100k_base")
def batches(texts, max_inputs=2048, max_tokens=300_000):
batch, tokens = [], 0
for text in texts:
count = len(enc.encode(text))
if batch and (len(batch) == max_inputs or tokens + count > max_tokens):
yield batch
batch, tokens = [], 0
batch.append(text)
tokens += count
if batch:
yield batch
vectors = []
for batch in batches(texts):
response = client.embeddings.create(model="text-embedding-3-small", input=batch)
vectors += [item.embedding for item in response.data] # in the order sent

8,192 token'dan uzun belgeleri embed etmeden önce parçalara ayırın. Arama ve RAG için birkaç yüz token'lık, bir iki paragraflık parçalar genellikle belgenin tamamından daha iyi eşleşmeler bulur.

dimensions ile daha kısa vektörler

text-embedding-3 modelleri, kısaltılmış bir vektörün yine de çalışacağı şekilde eğitilmiştir: dimensions isteyin, tam vektörün ilk kısmını uzunluğu 1'e yeniden normalize edilmiş olarak alırsınız. Daha kısa vektörler daha az depolama ve bellek kaplar, daha hızlı aranır; karşılığında doğruluk biraz düşer. Text Embedding 3 Large, 1.024 boyutta tam 3.072 boyutunun üçte biri kadar yer kaplar.

response = client.embeddings.create(
model="text-embedding-3-large",
input="The food was delicious and the waiter was friendly.",
dimensions=1024,
)
print(len(response.data[0].embedding)) # 1024
Karşılaştırdığınız her şey için tek bir model ve tek bir boyut kullanın: farklı uzunluktaki vektörler karşılaştırılamaz ve birçok vektör veritabanı indeksi oluştururken uzunluğu sabitler. Daha kısa vektörlerin fiyatı aynıdır: ücret giriş token'ı başınadır.

Base64

"encoding_format": "base64" ile her embedding, JSON dizisi yerine little-endian float32 sayılarından oluşan bir base64 dizesi olarak döner: daha küçük, indirmesi ve ayrıştırması daha hızlı. encoding_format değerini boş bıraktığınızda OpenAI'nin Python SDK'sı base64'ü kendisi ister ve sizin için çözer, yani iki durumda da düz float'lar alırsınız. Base64'ü kendiniz isterseniz dizeyi alırsınız; şöyle çözün:

import base64
import numpy as np
response = client.embeddings.create(
model="text-embedding-3-small",
input=["First text", "Second text"],
encoding_format="base64",
)
# Each embedding is a base64 string of little-endian float32 numbers
vectors = [np.frombuffer(base64.b64decode(item.embedding), dtype="<f4") for item in response.data]

Belgelerinizi bir kez embed edip vektörleri saklayın. Aramak için sorguyu aynı modelle embed edin ve belgeleri ona olan kosinüs benzerliğine göre sıralayın: 1'e ne kadar yakınsa anlamca o kadar yakındır, ortak tek kelime olmasa bile. text-embedding-3 vektörlerinin uzunluğu 1'dir, bu yüzden nokta çarpımı aynı sıralamayı verir.

# pip install openai numpy
import os
import numpy as np
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
MODEL = "text-embedding-3-small"
docs = [
"To change your password, open Settings, choose Security and click Change password.",
"Invoices are emailed on the first day of each month and can be downloaded under Billing.",
"Invite teammates from the Team page; each person signs in with their own email.",
"API keys can be limited to a monthly budget, a rate limit and a list of models.",
]
def embed(texts):
response = client.embeddings.create(model=MODEL, input=texts)
return np.array([item.embedding for item in response.data])
doc_vectors = embed(docs) # embed once, and store the vectors beside the text
def search(query, k=2):
query_vector = embed([query])[0]
# The vectors have length 1, so the dot product is the cosine similarity
scores = doc_vectors @ query_vector
best = np.argsort(-scores)[:k]
return [(docs[i], float(scores[i])) for i in best]
for text, score in search("How can I change my password?"):
print(f"{score:.3f} {text}") # the password article comes first

Birkaç bin belgeden fazlası için vektörleri bir vektör veritabanında ya da vektör indeksinde (pgvector, Qdrant, Pinecone, Weaviate, Chroma ve benzerleri) tutun ve sıralamayı ona bırakın.

Getirme (RAG)

Getirme destekli üretim, bir soruyu kendi belgelerinizden yanıtlar: soruya en yakın pasajları arar, sonra bunları soruyla birlikte bir sohbet modeline verir. İkisi de aynı Zurelay anahtarıyla yapılır.

# After the search example above: retrieve, then answer from what was found
question = "How do I stop a key from spending too much?"
notes = "\n".join(text for text, _ in search(question))
answer = client.chat.completions.create(
model="gpt-6-luna",
messages=[
{
"role": "system",
"content": "Answer from these notes only. If they don't say, say so.\n\n" + notes,
},
{"role": "user", "content": question},
],
)
print(answer.choices[0].message.content)

LangChain, LlamaIndex ve AI SDK

OpenAI embeddings sınıfı bulunan framework'ler Zurelay'in base URL'si ve anahtarıyla çalışır; model ID'leri OpenAI'nin ID'leri olarak kalır.

LangChain

# pip install langchain-openai
import os
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(
model="text-embedding-3-small",
base_url="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
query_vector = embeddings.embed_query("How can I change my password?")
doc_vectors = embeddings.embed_documents(["First document", "Second document"])

LangChain'in Python OpenAIEmbeddings sınıfı metinleri varsayılan olarak kendisi tokenize eder ve token ID'lerini gönderir. Zurelay token dizilerini kabul eder, yani varsayılan ayarlar olduğu gibi çalışır.

LlamaIndex

# pip install llama-index-embeddings-openai
import os
from llama_index.core import Settings
from llama_index.embeddings.openai import OpenAIEmbedding
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small",
api_base="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
vector = Settings.embed_model.get_text_embedding("How can I change my password?")

Settings.embed_model ayarlandığında oluşturduğunuz her indeks ve retriever Zurelay üzerinden embed eder. Sohbet modeli için LlamaIndex rehberine bakın.

Vercel AI SDK

// npm install ai @ai-sdk/openai
import { createOpenAI } from "@ai-sdk/openai";
import { cosineSimilarity, embed, embedMany } from "ai";
const zurelay = createOpenAI({
baseURL: "https://api.zurelay.com/v1",
apiKey: process.env.ZURELAY_API_KEY,
});
const model = zurelay.embedding("text-embedding-3-small");
const { embeddings } = await embedMany({ model, values: ["First document", "Second document"] });
const { embedding } = await embed({ model, value: "How can I change my password?" });
console.log(cosineSimilarity(embedding, embeddings[0]));

Uygulamalar ve vektör depoları

OpenAI'nin embeddings'ini ayarlanabilir bir base URL ile çağıran uygulamalar da aynı şekilde çalışır: base URL'yi https://api.zurelay.com/v1 yapın, Zurelay anahtarınızı ve yukarıdaki model ID'lerinden birini kullanın. Buna Open WebUI'nin belgeler için OpenAI embedding motoru, LibreChat'in RAG API'si, n8n'in Embeddings OpenAI düğümü ve Dify'ın OpenAI uyumlu model sağlayıcısı dahildir.

OpenAI ile aynı vektörler

text-embedding-3-small ve text-embedding-3-large adreslerine giden istekler OpenAI'nin kendi modellerinde çalışır. Her rotayı OpenAI'nin API'siyle karşılaştırdık: aynı metin ve model için vektörler OpenAI'ninkilerle eşleşiyor, kosinüs benzerliği 0.9999 ya da daha yüksek. Yani OpenAI'nin API'siyle oluşturduğunuz bir indeks, sorgularınızı Zurelay üzerinden embed ettiğinizde çalışmaya devam eder; Zurelay üzerinden oluşturduğunuz bir indeks de OpenAI'ninkiyle çalışır. İkisi arasında geçiş için yeniden embed etmek gerekmez.

Model değiştirmek, yeniden embed etmek demektir

Farklı modellerden gelen vektörler karşılaştırılamaz

text-embedding-3-small vektörü, text-embedding-3-large vektörünün ya da başka herhangi bir modelden gelen bir vektörün yanında hiçbir şey ifade etmez: her model metni kendi uzayına yerleştirir. Bu yüzden modeli değiştirmek için depoladığınız her şeyi yeni modelle yeniden embed edin ve bundan sonra o modelle sorgulayın.

Aynı nedenle bir embeddings isteğini her zaman adını verdiğiniz model yanıtlar. Akıllı yönlendirme ayarlarınız ne olursa olsun isteği asla başka bir modele devretmez: model çalışmıyorsa, indeksinizle eşleşmeyen vektörler yerine yeniden denemeniz için 503 model_unavailable alırsınız.

Sınırlar

  • İstek başına en fazla 2,048 giriş.
  • Her girişte en fazla 8,192 token, isteğin tamamında 300,000 token.
  • Boş dize olmaz.
  • dimensions 1 ile modelin tam uzunluğu arasında: text-embedding-3-small için 1,536, text-embedding-3-large için 3,072.
  • Bir sınırı aşan istek, o sınırı belirten bir 400 ile reddedilir ve hiçbir maliyeti olmaz.
  • Belirli modellerle sınırlı bir anahtarın listesinde embedding modelinin de bulunması gerekir. Bkz. Anahtar sınırları ve kuralları.

Embedding'ler için ödeme

Embeddings yalnızca giriş tokenları üzerinden faturalandırılır, OpenAI'nin saydığı gibi sayılır ve vektörler ücretsizdir. Text Embedding 3 Small, 1M token başına $0.01 ve Text Embedding 3 Large $0.065 tutarındadır — OpenAI'nin yarı fiyatına. Her biri 100 token olan bir milyon metin, yani 100M token, Text Embedding 3 Small ile $1.00 ve Text Embedding 3 Large ile $6.50 tutarında embed edilir; OpenAI'de ise $2.00 ve $13.00.

İstek başına minimum yok: 10 tokenlık bir istek 10 token olarak faturalandırılır. Daha kısa dimensions ve base64 aynı ücrete tabidir. Her yanıtın usage ve x-zurelay-input-tokens başlığı neyin faturalandırıldığını söyler, her istek istek günlüğünüzde yer alır ve başarısız istekler için ücret alınmaz.

Hatalar

Hatalar OpenAI'nin biçiminde gelir, bu yüzden OpenAI SDK'ları onları OpenAI'de olduğu gibi fırlatır.

DurumKodNe zaman
400invalid_requestBir alan eksik ya da hatalı: boş bir string, 2,048 taneden fazla input, tam sayı olmayan bir dimensions ya da float veya base64 dışında bir encoding_format. Mesaj hangisi olduğunu söyler.
400invalid_valuedimensions, modelin tam uzunluğundan büyük.
400context_length_exceededBir input 8,192 tokenı ya da istek 300,000 değerini aşıyor. Metni bölün veya aynı anda daha az input gönderin.
503model_unavailableModel kısa süreliğine kullanılamıyor. retry-after başlığındaki saniye kadar bekleyip yeniden deneyin.

Anahtarlar, kredi, bütçeler ve hız sınırları diğer tüm uç noktalarla aynı hataları verir: bkz. Hatalar. OpenAI'ın SDK'ları, yeniden denemeye değer olanları otomatik olarak tekrar dener.

Önce deneyin

Paneldeki Deneme alanı bölümünde bir embedding modeli seçin, birkaç metin yazıp embed edin: her vektörü, faturalandırılan token'ları ve her çiftin kosinüs benzerliğini görürsünüz. Kodu al düğmesi aynı isteği Python, Node.js veya cURL için yazar.

Sorunuz mu var, yoksa bir şey mi eksik? Destek ekibimize sorun, genellikle bir dakika içinde e-postayla yanıtlayalım.