एम्बेडिंग्स

एम्बेडिंग्स

टेक्स्ट को वेक्टर में बदलें — सेमांटिक सर्च, रिट्रीवल (RAG), सुझाव, क्लस्टरिंग और डुप्लीकेट हटाने के लिए। OpenAI के text-embedding-3 मॉडल, OpenAI की कीमत से आधी कीमत पर। वही मॉडल ID, वही रिक्वेस्ट और रिस्पॉन्स, वही वेक्टर: OpenAI के लिए लिखा कोड बेस URL और की बदलते ही चल पड़ता है।

POST/v1/embeddings
मॉडलIDप्रति 1M इनपुट टोकनOpenAI की कीमतडाइमेंशन
Text Embedding 3 Smalltext-embedding-3-small$0.01$0.021,536, या उससे कम
Text Embedding 3 Largetext-embedding-3-large$0.065$0.133,072, या उससे कम

आप जो टेक्स्ट भेजते हैं उसका भुगतान करते हैं, वेक्टर मुफ़्त हैं। दोनों मॉडल प्रति इनपुट 8,192 टोकन तक पढ़ते हैं। शुरुआत के लिए Text Embedding 3 Small सही है: सस्ता, तेज़, और ज़्यादातर सर्च और RAG के लिए अच्छा। Text Embedding 3 Large बड़ा और ज़्यादा सटीक मॉडल है — जब रिट्रीवल की क्वालिटी स्टोरेज और कीमत से ज़्यादा मायने रखे।

झटपट शुरुआत

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

कोई भी OpenAI SDK चलेगा: उसे https://api.zurelay.com/v1 पर सेट करें, अपनी Zurelay की डालें और उसका embeddings मेथड कॉल करें। जवाब बिल्कुल OpenAI वाला मिलता है:

रिस्पॉन्स (वेक्टर छोटा किया गया)
{
"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 में हर इनपुट के लिए एक एम्बेडिंग होता है, उसी क्रम में जिसमें आपने भेजा, और हर एक के साथ उसका index। usage.prompt_tokens वही है जिस पर रिक्वेस्ट का बिल बना। हेडर भी यही बताते हैं: x-zurelay-model मॉडल का नाम देता है और x-zurelay-input-tokens टोकन का, और x-request-id आपके रिक्वेस्ट लॉग में वह रिक्वेस्ट ढूंढ देता है।

पैरामीटर

modelstringज़रूरी
text-embedding-3-small या text-embedding-3-large।
inputstring या arrayज़रूरी
क्या एम्बेड करें: एक स्ट्रिंग, 2,048 स्ट्रिंग तक की ऐरे, टोकन ID की ऐरे (OpenAI के cl100k_base टोकनाइज़र से पूर्णांक), या ऐसी 2,048 ऐरे तक की ऐरे। हर इनपुट ज़्यादा से ज़्यादा 8,192 टोकन का हो, और कोई भी खाली स्ट्रिंग न हो।
encoding_formatstring
float (डिफ़ॉल्ट): हर एम्बेडिंग संख्याओं का एक ऐरे होती है। base64: हर एक little-endian float32 संख्याओं की base64 स्ट्रिंग होती है — छोटी, और डाउनलोड करने में तेज़। देखें Base64।
dimensionsinteger
वेक्टर छोटा करें: text-embedding-3-small पर 1 से 1,536, text-embedding-3-large पर 1 से 3,072। पूरी लंबाई के लिए इसे छोड़ दें। देखें छोटे वेक्टर।
userstring
वैकल्पिक: उस अंतिम उपयोगकर्ता की ID जिसके लिए अनुरोध है, जैसे OpenAI के API में। स्वीकार किया जाता है, और वेक्टर पर कोई असर नहीं पड़ता।

बैचिंग

एक ही अनुरोध में कई टेक्स्ट भेजें: input अधिकतम 2,048 का ऐरे लेता है, और नतीजे उसी क्रम में लौटते हैं। हज़ार टेक्स्ट वाला एक अनुरोध हज़ार अनुरोधों से कहीं तेज़ है, और खर्च भी उतना ही: आप प्रति टोकन चुकाते हैं, प्रति अनुरोध नहीं। हर अनुरोध कुल मिलाकर 300,000 टोकन से कम रखें।

# 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 टोकन से लंबे दस्तावेज़ों को एम्बेड करने से पहले टुकड़ों में बाँटें। सर्च और RAG के लिए, कुछ सौ टोकन के टुकड़े — एक-दो पैराग्राफ़ — पूरे दस्तावेज़ों से आमतौर पर बेहतर मैच ढूँढते हैं।

dimensions के साथ छोटे वेक्टर

text-embedding-3 मॉडल ऐसे प्रशिक्षित हैं कि छोटा किया गया वेक्टर भी काम करता है: dimensions माँगें और आपको पूरे वेक्टर का पहला हिस्सा मिलता है, जो लंबाई 1 पर फिर से नॉर्मलाइज़ किया गया है। छोटे वेक्टर कम स्टोरेज और मेमोरी लेते हैं और तेज़ी से सर्च होते हैं, थोड़ी कम सटीकता के साथ। Text Embedding 3 Large, 1,024 dimensions पर अपने पूरे 3,072 की एक-तिहाई जगह लेता है।

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
जो भी आप तुलना करते हैं, उसके लिए एक ही मॉडल और एक ही साइज़ इस्तेमाल करें: अलग-अलग लंबाई के वेक्टर की तुलना नहीं हो सकती, और कई वेक्टर डेटाबेस इंडेक्स बनाते समय लंबाई तय कर देते हैं। छोटे वेक्टर का खर्च भी उतना ही: कीमत प्रति इनपुट टोकन है।

Base64

"encoding_format": "base64" के साथ हर एम्बेडिंग JSON ऐरे की जगह little-endian float32 संख्याओं की base64 स्ट्रिंग के रूप में लौटती है: छोटी, और डाउनलोड व पार्स करने में तेज़। जब आप encoding_format छोड़ देते हैं, तो OpenAI का Python SDK खुद base64 माँगता है और उसे आपके लिए डिकोड कर देता है, यानी दोनों तरह आपको सादे floats ही मिलते हैं। अगर आप खुद base64 माँगते हैं, तो आपको स्ट्रिंग मिलती है, जिसे ऐसे डिकोड करें:

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]

अपने दस्तावेज़ एक बार एम्बेड करें और वेक्टर सहेज लें। सर्च करने के लिए, क्वेरी को उसी मॉडल से एम्बेड करें और दस्तावेज़ों को उससे cosine similarity के हिसाब से रैंक करें: 1 के जितना करीब, अर्थ में उतना ही करीब, चाहे कोई शब्द समान न हो। text-embedding-3 के वेक्टर की लंबाई 1 होती है, इसलिए dot product वही रैंकिंग देता है।

# 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

कुछ हज़ार से ज़्यादा दस्तावेज़ों के लिए, वेक्टर किसी वेक्टर डेटाबेस या वेक्टर इंडेक्स (pgvector, Qdrant, Pinecone, Weaviate, Chroma वगैरह) में रखें और रैंकिंग उसी से कराएँ।

रिट्रीवल (RAG)

रिट्रीवल-ऑगमेंटेड जनरेशन आपके ही दस्तावेज़ों से सवाल का जवाब देता है: सवाल से सबसे करीब के पैसेज खोजें, फिर उन्हें सवाल के साथ चैट मॉडल को दें। दोनों काम एक ही Zurelay की से हो जाते हैं।

# 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 और AI SDK

जिन फ़्रेमवर्क में OpenAI embeddings क्लास है, वे Zurelay के base URL और की के साथ काम करते हैं, और मॉडल ID OpenAI की ही रहती हैं।

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 का Python OpenAIEmbeddings डिफ़ॉल्ट रूप से टेक्स्ट को खुद टोकनाइज़ करता है और टोकन ID भेजता है। Zurelay टोकन ऐरे स्वीकार करता है, इसलिए डिफ़ॉल्ट सेटिंग्स जैसी हैं वैसी ही काम करती हैं।

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 सेट होने पर, आपका बनाया हर इंडेक्स और रिट्रीवर Zurelay के ज़रिए एम्बेड करता है। चैट मॉडल के लिए, LlamaIndex गाइड देखें।

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]));

ऐप्स और वेक्टर स्टोर

जो ऐप्स अपनी सेट की जा सकने वाली base URL के साथ OpenAI की embeddings कॉल करते हैं, वे भी इसी तरह काम करते हैं: उसे https://api.zurelay.com/v1 पर सेट करें, अपनी Zurelay की और ऊपर की कोई मॉडल ID इस्तेमाल करें। इनमें Open WebUI का दस्तावेज़ों के लिए OpenAI embedding इंजन, LibreChat का RAG API, n8n का Embeddings OpenAI नोड और Dify का OpenAI-संगत मॉडल प्रोवाइडर शामिल हैं।

OpenAI जैसे ही वेक्टर

text-embedding-3-small और text-embedding-3-large के अनुरोध OpenAI के अपने मॉडलों पर चलते हैं। हमने हर रूट को OpenAI के API के सामने जाँचा: एक ही टेक्स्ट और मॉडल के लिए वेक्टर OpenAI से मेल खाते हैं, 0.9999 या उससे ज़्यादा की cosine similarity के साथ। यानी OpenAI के API से बनाया आपका इंडेक्स तब भी काम करता है जब आप अपनी क्वेरी Zurelay से एम्बेड करते हैं, और Zurelay से बनाया इंडेक्स OpenAI के साथ चलता है। दोनों के बीच जाने पर दोबारा एम्बेड करने की ज़रूरत नहीं।

मॉडल बदलने का मतलब है दोबारा एम्बेडिंग

अलग-अलग मॉडलों के वेक्टर की तुलना नहीं हो सकती

text-embedding-3-small का वेक्टर text-embedding-3-large के वेक्टर के बगल में, या किसी भी दूसरे मॉडल के वेक्टर के बगल में, कुछ मायने नहीं रखता: हर मॉडल टेक्स्ट को अपनी अलग जगह में रखता है। इसलिए मॉडल बदलने के लिए, अपना सारा सहेजा हुआ डेटा नए मॉडल से दोबारा एम्बेड करें, और आगे से उसी मॉडल से क्वेरी करें।

इसी वजह से, एम्बेडिंग का अनुरोध हमेशा उसी मॉडल से पूरा होता है जिसका आपने नाम दिया। स्मार्ट रूटिंग इसे कभी किसी दूसरे मॉडल को नहीं देता, आपकी सेटिंग्स कुछ भी हों: अगर मॉडल डाउन है तो आपको 503 model_unavailable मिलता है, दोबारा कोशिश करने के लिए, न कि ऐसे वेक्टर जो आपके इंडेक्स से मेल न खाएँ।

सीमाएँ

  • एक अनुरोध में अधिकतम 2,048 इनपुट।
  • हर इनपुट में अधिकतम 8,192 टोकन, और पूरे अनुरोध में 300,000।
  • खाली स्ट्रिंग नहीं।
  • dimensions 1 से लेकर मॉडल की पूरी लंबाई तक: text-embedding-3-small पर 1,536, text-embedding-3-large पर 3,072।
  • सीमा से बढ़ा अनुरोध 400 के साथ अस्वीकार होता है जिसमें सीमा का नाम होता है, और उसका कोई खर्च नहीं लगता।
  • कुछ मॉडलों तक सीमित की में एम्बेडिंग मॉडल उसकी सूची में होना चाहिए। देखें की की सीमाएँ और नियम।

एम्बेडिंग का भुगतान

एम्बेडिंग्स का बिल सिर्फ़ इनपुट टोकन पर लगता है, जो OpenAI की तरह गिने जाते हैं, और वेक्टर मुफ़्त हैं। Text Embedding 3 Small का दाम $0.01 प्रति 1M टोकन है और Text Embedding 3 Large $0.065, यानी OpenAI के दाम से आधा। 100 टोकन वाले दस लाख टेक्स्ट, कुल 100M टोकन, Text Embedding 3 Small से एम्बेड करने पर $1.00 में पड़ेंगे और $6.50 के साथ Text Embedding 3 Large, जबकि OpenAI पर $2.00 और $13.00।

प्रति रिक्वेस्ट कोई न्यूनतम नहीं है: 10-टोकन वाली रिक्वेस्ट का बिल 10 टोकन ही है। छोटे dimensions और base64 का भी वही शुल्क है। हर जवाब के usage और x-zurelay-input-tokens हेडर बताते हैं कि बिल किस पर लगा, हर रिक्वेस्ट आपके रिक्वेस्ट लॉग में रहती है, और जो रिक्वेस्ट फेल होती हैं उनका कुछ भी नहीं लगता।

गड़बड़ियाँ

एरर OpenAI के ढाँचे में आते हैं, इसलिए OpenAI के SDK उन्हें वैसे ही रेज़ करते हैं जैसे OpenAI के लिए करते।

स्थितिकोडकब
400invalid_requestकोई फ़ील्ड गायब है या गलत है: खाली स्ट्रिंग, 2,048 से ज़्यादा इनपुट, dimensions जो पूर्ण संख्या न हो, या float या base64 के अलावा कोई encoding_format। मैसेज बता देता है कि कौन सा।
400invalid_valuedimensions मॉडल की पूरी लंबाई से बड़ा है।
400context_length_exceededकोई इनपुट 8,192 टोकन से ज़्यादा है, या रिक्वेस्ट 300,000 से ज़्यादा। टेक्स्ट को बाँटें, या एक बार में कम इनपुट भेजें।
503model_unavailableमॉडल कुछ समय के लिए अनुपलब्ध है। retry-after हेडर में दिए गए सेकंड के बाद दोबारा कोशिश करें।

कीज़, क्रेडिट, बजट और रेट लिमिट पर वही एरर आते हैं जो बाकी सभी endpoints पर आते हैं: देखें एरर। OpenAI के SDKs उन एरर को दोबारा आज़माते हैं जिन्हें दोबारा आज़माना ठीक रहता है।

पहले आज़माकर देखें

डैशबोर्ड के प्लेग्राउंड में एम्बेडिंग मॉडल चुनें, कुछ टेक्स्ट लिखें और उन्हें एम्बेड करें: आपको हर वेक्टर, बिल किए गए टोकन और हर जोड़ी की कोसाइन समानता दिखती है। इसका कोड पाएं बटन वही रिक्वेस्ट Python, Node.js या cURL के लिए लिख देता है।

कोई सवाल है, या कुछ छूट गया है? हमारी सहायता टीम से पूछें और हम ईमेल से जवाब देंगे, आम तौर पर एक मिनट के भीतर.