Developer Dashboard

Embeddings API Reference

The Embeddings API allows you to convert text into vector representations that can be used for semantic search, clustering, classification, and other machine learning tasks.

Embeddings preserve semantic relatedness: texts with similar meanings produce vectors that are closer together, while unrelated texts are farther apart. Use them when you need retrieval, recommendations, duplicate detection, anomaly detection, clustering, or lightweight classification over your own data.

Embedding Workflow

  1. Choose one model and dimension size for each index. Query vectors and stored document vectors should come from the same model and dimensionality.
  2. Normalize and chunk input text before embedding. Keep stable chunk IDs so unchanged documents do not need to be re-embedded.
  3. Store vectors with metadata such as source URL, document ID, permissions, language, and update timestamp.
  4. Search with cosine similarity or dot product depending on your vector store. Keep the same distance metric during indexing and querying.
  5. Pass retrieved snippets to /v1/responses or /v1/chat/completions instead of asking the model to guess from memory. For a complete workflow, see Manual RAG with Embeddings.

Endpoint

POST https://api.avalai.ir/v1/embeddings

Request Body

ParameterTypeRequiredDescription
modelstringYesID of the model to use. See Models for available embedding models.
inputstring or arrayYesThe text to embed. Can be a string or an array of strings.
encoding_formatstringNoThe format to return the embeddings in. Can be "float" or "base64". Defaults to "float".
dimensionsintegerNoThe number of dimensions the resulting output embeddings should have. Only supported in some models.
userstringNoA unique identifier representing your end-user, which can help monitor and detect abuse.

Request Notes

  • Send an array in input to embed multiple independent strings in one request. This is supported by the Embeddings API and is separate from AvalAI's hosted Batch API.
  • Plan embedding cost around the input you send. OpenAI-compatible text embedding responses report usage.prompt_tokens and usage.total_tokens; AvalAI pricing and provider-specific routes can vary, so check pricing before large backfills.
  • Use dimensions when the selected model supports shorter vectors. Smaller vectors reduce storage, memory, and search cost, but may trade off retrieval quality.
  • Use encoding_format: "float" for most vector databases and similarity calculations. Use base64 only when your pipeline explicitly benefits from compact transport.
  • Count or estimate tokens before embedding very large inputs; see Token Counting and your selected model's context window. For OpenAI text-embedding-3-* models, use the cl100k_base tokenizer.
  • Do not send empty strings. OpenAI's reference API documents per-input and aggregate request limits for embedding requests; AvalAI limits can differ by model, provider route, and account tier, so split large ingest jobs into bounded batches and retry failed chunks safely.

Examples

Basic Embedding Generation

bash
curl https://api.avalai.ir/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '{
  "model": "text-embedding-3-small",
  "input": "The food was delicious and the service was excellent."
}'
python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

response = client.embeddings.create(
    model="text-embedding-3-small",
    input="The food was delicious and the service was excellent.",
)

embeddings = response.data[0].embedding
print(f"Length of embedding vector: {len(embeddings)}")
print(f"First few values: {embeddings[:5]}")
javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AVALAI_API_KEY,
  baseURL: "https://api.avalai.ir/v1",
});

const response = await client.embeddings.create({
  model: "text-embedding-3-small",
  input: "The food was delicious and the service was excellent.",
});

const embeddings = response.data[0].embedding;
console.log(`Length of embedding vector: ${embeddings.length}`);
console.log(`First few values: ${embeddings.slice(0, 5)}`);
go
package main

import (
	"context"
	"fmt"
	openai "github.com/openai/openai-go"
	"os"
)

func main() {
	client := openai.NewClient(os.Getenv("AVALAI_API_KEY"))
	client.BaseURL = "https://api.avalai.ir/v1"

	resp, err := client.CreateEmbeddings(
		context.Background(),
		openai.EmbeddingRequest{
			Model: openai.TextEmbeddingSmall,
			Input: []string{"The food was delicious and the service was excellent."},
		},
	)

	if err != nil {
		fmt.Printf("Embedding error: %v\n", err)
		return
	}

	embeddings := resp.Data[0].Embedding
	fmt.Printf("Length of embedding vector: %d\n", len(embeddings))
	fmt.Printf("First few values: %v\n", embeddings[:5])
}
php
<?php
// PHP Example for Embeddings via AvalAI

$apiKey = getenv('AVALAI_API_KEY'); // Or replace with your key directly
$apiUrl = 'https://api.avalai.ir/v1/embeddings';

$data = [
'model' => 'text-embedding-3-small',
'input' => 'The food was delicious and the service was excellent.'
// Add other parameters like encoding_format, dimensions etc. if needed
// 'encoding_format' => 'float',
// 'dimensions' => 1024
];

$jsonData = json_encode($data);

$ch = curl_init($apiUrl);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey,
'Content-Length: ' . strlen($jsonData)
]);

$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);

curl_close($ch);

if ($err) {
  echo "cURL Error #:" . $err;
} elseif ($httpcode >= 400) {
  echo "HTTP Error: " . $httpcode . "\n";
  echo $response;
} else {
  $responseData = json_decode($response, true);
  if (isset($responseData['data'][0]['embedding'])) {
    $embedding = $responseData['data'][0]['embedding'];
    echo "Length of embedding vector: " . count($embedding) . "\n";
    echo "First few values: [" . implode(', ', array_slice($embedding, 0, 5)) . "]\n";
  } else {
    echo "Response received:\n";
    print_r($responseData);
  }
}
?>

Multiple Inputs

The Embeddings API supports batching inputs by passing an array of strings to input. AvalAI's hosted /v1/batches API is a separate offline processing feature; use this inline array form when you want one immediate response containing embeddings for several texts.

You can embed multiple texts in a single request:

python
response = client.embeddings.create(
    model="text-embedding-3-small",
    input=[
        "The food was delicious and the service was excellent.",
        "The restaurant was very expensive and the food was mediocre.",
        "I highly recommend this restaurant for its amazing atmosphere.",
    ],
)

# Process each embedding
for i, embedding in enumerate(response.data):
    print(f"Embedding {i}, length: {len(embedding.embedding)}")

Custom Dimensions

When the selected model supports dimensions, set the target size at embedding time so every vector in the index has the same shape:

python
response = client.embeddings.create(
    model="text-embedding-3-large",
    input="Summarize AvalAI's model routing documentation.",
    dimensions=1024,
    encoding_format="float",
)

vector = response.data[0].embedding
print(len(vector))
javascript
const response = await client.embeddings.create({
  model: "text-embedding-3-large",
  input: "Summarize AvalAI's model routing documentation.",
  dimensions: 1024,
  encoding_format: "float",
});

const vector = response.data[0].embedding;
console.log(vector.length);
bash
curl https://api.avalai.ir/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '{
    "model": "text-embedding-3-large",
    "input": "Summarize AvalAI'\''s model routing documentation.",
    "dimensions": 1024,
    "encoding_format": "float"
  }'

If you must truncate vectors after generation, normalize the shortened vectors before comparing them. Prefer the API parameter because it keeps generation, storage, and search dimensions explicit.

Response Format

json
{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "embedding": [
        0.0023064255,
        -0.009327292,
        -0.0028842222,
        ...
      ],
      "index": 0
    }
  ],
  "model": "text-embedding-3-small",
  "usage": {
    "prompt_tokens": 8,
    "total_tokens": 8
  }
}

Response Parameters

ParameterTypeDescription
objectstringThe object type, which is always "list".
dataarrayAn array of embedding objects.
modelstringThe model used for generating embeddings.
usageobjectAn object containing token usage information.

Embedding Object

ParameterTypeDescription
objectstringThe object type, which is always "embedding".
embeddingarrayThe embedding vector, which is an array of floats. The length of this array depends on the model used.
indexintegerThe index of the embedding in the input array.

Usage Object

ParameterTypeDescription
prompt_tokensintegerThe number of tokens used in the input.
total_tokensintegerThe total number of tokens used (same as prompt_tokens for embeddings).

FAQ

How should I retrieve K nearest vectors quickly?

Use a vector database or search service when you have more than a small in-memory set. Store each vector with source IDs, tenant and permission metadata, language, timestamps, and document type so you can filter before similarity search.

Which distance function should I use?

Cosine similarity is a safe default. OpenAI text embeddings are normalized to length 1, so cosine similarity and Euclidean distance usually produce the same ranking, and dot product can be used as a faster cosine-equivalent path for those normalized vectors.

Do embeddings know about recent events?

Do not use embeddings as a facts database. OpenAI text-embedding-3-large and text-embedding-3-small are not designed to know recent events; embed your current private or public documents and retrieve them at answer time.

Can I store or share embeddings?

Treat embeddings as derived user data. They are not readable text, but they can reveal similarity patterns or membership in a corpus, so apply the same retention, deletion, access-control, and tenant-isolation policies as the source documents.

Available Models

AvalAI currently exposes these embedding-mode model IDs. Use Model Details, pricing, and the rate-limit pages for the latest limits and costs.

ProviderModelVector size / input windowNotes
OpenAItext-embedding-3-large3072 dimensions; 8191 input tokensHigher-dimensional OpenAI text embedding; supports shorter vectors with dimensions.
OpenAItext-embedding-3-small1536 dimensions; 8191 input tokensEfficient OpenAI text embedding for search, clustering, classification, and recommendations.
OpenAItext-embedding-ada-0021536 dimensions; 8191 input tokensLegacy OpenAI-compatible embedding model for existing indexes.
Googlegemini-embedding-2Up to 3072 dimensions; 8192 input tokensMultimodal Gemini embedding model for text, image, audio, video, and PDF workflows where supported.
Googlegemini-embedding-001Up to 3072 dimensions; 2048 input tokensGemini embedding model with task-specific controls through provider-specific parameters.
Cohereembed-v-4-0Up to 3072 dimensions; 128k input tokensCohere Embed v4 via Azure AI; supports text and image inputs on /v1/embeddings.
Coherecohere.embed-v4:0Up to 1536 dimensions; 128k input tokensCohere Embed v4 via AWS Bedrock; supports multimodal retrieval workflows.
Coherecohere.embed-multilingual-v31024 dimensions; provider input windowMultilingual Cohere embeddings for cross-language search and classification.
Alibabatext-embedding-v42048 dimensions; 1024 input tokensLatest Qwen text embedding for semantic search and RAG.
Alibabatext-embedding-v31024 dimensions; 1024 input tokensMultilingual Qwen text embedding for existing text indexes.
Alibabatongyi-embedding-vision-plus1152 dimensions; 1024 input tokensMultimodal embedding for cross-modal retrieval with text, images, and video inputs.
Alibabatongyi-embedding-vision-flash768 dimensions; 1024 input tokensFaster multimodal embedding for lower-latency cross-modal search.
Cloudflarecf.plamo-embedding-1bProvider vector size; 4096 input tokensPLaMo embedding model served through Cloudflare.
Cloudflarecf.embeddinggemma-300mProvider vector size; 2048 input tokensCompact Gemma-based embedding model for lightweight search.
Nvidia NIMnvidia_nim.nv-embedqa-e5-v5Provider vector sizeNIM-hosted embedding model for question-answering retrieval.
Nvidia NIMnvidia_nim.nv-embed-v1Provider vector sizeNIM-hosted general embedding model.
BAAI via Nvidia NIMnvidia_nim.bge-m3Provider vector sizeMultilingual BGE embedding model served through Nvidia NIM.

Similarity and Distance

For retrieval, compute a query embedding with the same model and dimensions as your stored document embeddings, then rank documents by vector similarity. Cosine similarity is a good default; OpenAI embeddings are normalized to length 1, so dot product and cosine similarity usually produce the same ranking for those models. If you shorten vectors manually after generation, normalize them before storing or comparing.

Do not mix embeddings from different providers or dimensions in the same index unless your vector store and evaluation set prove the ranking quality is acceptable. Keep a small labeled eval set for important retrieval workflows so you can compare model, chunking, and dimension changes safely.

Stored vectors are derived data. Apply the same tenant isolation, retention, deletion, and access-control policy to vectors and metadata that you apply to the source documents they represent.

Common Use Cases

Embeddings can be used to find semantically similar documents:

python
import os
import numpy as np
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)


# Function to compute cosine similarity
def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))


# Create embeddings for a query and documents
query = "delicious pasta"
documents = [
    "The restaurant serves amazing Italian food.",
    "The new smartphone has excellent battery life.",
    "Their pasta dishes are incredibly tasty and authentic.",
]

# Get query embedding
query_response = client.embeddings.create(model="text-embedding-3-small", input=query)
query_embedding = query_response.data[0].embedding

# Get document embeddings
doc_response = client.embeddings.create(model="text-embedding-3-small", input=documents)
doc_embeddings = [item.embedding for item in doc_response.data]

# Compute similarities
similarities = [
    cosine_similarity(query_embedding, doc_embedding)
    for doc_embedding in doc_embeddings
]

# Print results
for i, similarity in enumerate(similarities):
    print(f"Document {i}: Similarity = {similarity:.4f}")
    print(f"Text: {documents[i]}")

Text Classification

Embeddings can be used with traditional ML models for classification:

python
import os
from sklearn.linear_model import LogisticRegression
import numpy as np
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

# Sample training data
texts = [
    "I love this product, it's amazing!",
    "This is the best purchase I've ever made.",
    "I'm very disappointed with the quality.",
    "This product is terrible, don't buy it.",
]
labels = [1, 1, 0, 0]  # 1 for positive, 0 for negative

# Get embeddings for training data
response = client.embeddings.create(model="text-embedding-3-small", input=texts)
embeddings = [item.embedding for item in response.data]

# Train a classifier
classifier = LogisticRegression()
classifier.fit(embeddings, labels)

# Classify new text
new_texts = ["I really enjoy using this.", "This doesn't work as advertised."]
new_response = client.embeddings.create(model="text-embedding-3-small", input=new_texts)
new_embeddings = [item.embedding for item in new_response.data]

# Predict
predictions = classifier.predict(new_embeddings)
for text, prediction in zip(new_texts, predictions):
    sentiment = "positive" if prediction == 1 else "negative"
    print(f"Text: '{text}' - Predicted sentiment: {sentiment}")

Google Gemini Embeddings

Google's Gemini embedding models offer advanced features including task-specific optimization, flexible dimensionality control, and superior performance for various NLP tasks. AvalAI supports Gemini embeddings through both OpenAI-compatible and native Google GenAI SDK approaches.

Using Gemini Embeddings with OpenAI Schema

You can use Gemini embeddings through the standard v1/embeddings endpoint with additional parameters in extra_body for advanced features:

Basic Gemini Embedding

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

# Basic Gemini embedding
response = client.embeddings.create(
    model="gemini-embedding-001",
    input="The quick brown fox jumps over the lazy dog",
)

embedding = response.data[0].embedding
print(f"Embedding dimensions: {len(embedding)}")
print(f"First few values: {embedding[:5]}")
javascript
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.AVALAI_API_KEY,
    baseURL: "https://api.avalai.ir/v1",
});

// Basic Gemini embedding
const response = await client.embeddings.create({
    model: "gemini-embedding-001",
    input: "The quick brown fox jumps over the lazy dog",
});

const embedding = response.data[0].embedding;
console.log(`Embedding dimensions: ${embedding.length}`);
console.log(`First few values: ${embedding.slice(0, 5)}`);
bash
curl https://api.avalai.ir/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '{
    "model": "gemini-embedding-001",
    "input": "The quick brown fox jumps over the lazy dog"
  }'

Advanced Gemini Features with Task Types

Gemini embeddings support task-specific optimization and custom dimensionality:

python
# Advanced Gemini embedding with task type and custom dimensions
response = client.embeddings.create(
    model="gemini-embedding-001",
    input=[
        "What is the meaning of life?",
        "What is the purpose of existence?",
        "How do I bake a cake?",
    ],
    extra_body={"task_type": "SEMANTIC_SIMILARITY", "output_dimensionality": 768},
)

# Calculate cosine similarity between embeddings
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

embeddings = [item.embedding for item in response.data]
embeddings_matrix = np.array(embeddings)
similarity_matrix = cosine_similarity(embeddings_matrix)

print(f"Similarity between first two texts: {similarity_matrix[0, 1]:.4f}")
print(f"Similarity between first and third texts: {similarity_matrix[0, 2]:.4f}")

# Normalize embeddings for dimensions < 3072 (recommended)
if len(embeddings[0]) < 3072:
    normalized_embeddings = []
    for embedding in embeddings:
        embedding_array = np.array(embedding)
        normalized = embedding_array / np.linalg.norm(embedding_array)
        normalized_embeddings.append(normalized)
    print("Embeddings normalized for optimal performance")
javascript
// Advanced Gemini embedding with task type and custom dimensions
const response = await client.embeddings.create({
    model: "gemini-embedding-001",
    input: [
        "What is the meaning of life?",
        "What is the purpose of existence?",
        "How do I bake a cake?"
    ],
    // @ts-expect-error extra_body is a provider-specific parameter
    extra_body: {
        task_type: "SEMANTIC_SIMILARITY",
        output_dimensionality: 768
    }
});

const embeddings = response.data.map(item => item.embedding);
console.log(`Generated ${embeddings.length} embeddings with ${embeddings[0].length} dimensions`);

// Simple dot product similarity (for normalized embeddings)
function dotProduct(a, b) {
    return a.reduce((sum, val, i) => sum + val * b[i], 0);
}

const similarity = dotProduct(embeddings[0], embeddings[1]);
console.log(`Similarity between first two texts: ${similarity.toFixed(4)}`);
bash
curl https://api.avalai.ir/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '{
    "model": "gemini-embedding-001",
    "input": ["What is the meaning of life?", "What is the purpose of existence?"],
    "extra_body": {
      "task_type": "SEMANTIC_SIMILARITY",
      "output_dimensionality": 768
    }
  }'

Supported Task Types

Task TypeDescriptionBest For
SEMANTIC_SIMILARITYOptimized for measuring text similarityRecommendation systems, duplicate detection
CLASSIFICATIONOptimized for text classification tasksSentiment analysis, spam detection
CLUSTERINGOptimized for grouping similar textsDocument organization, market research
RETRIEVAL_DOCUMENTOptimized for document indexingRAG systems, search engines
RETRIEVAL_QUERYOptimized for search queriesCustom search applications
CODE_RETRIEVAL_QUERYOptimized for code search queriesCode search, documentation lookup
QUESTION_ANSWERINGOptimized for Q&A systemsChatbots, FAQ systems
FACT_VERIFICATIONOptimized for fact-checkingAutomated verification systems

Using Native Gemini API

You can also use Gemini embeddings through the native Google GenAI SDK endpoint for full access to Gemini-specific features:

python
import os
from google import genai

client = genai.Client(
    api_key=os.environ["AVALAI_API_KEY"],
    http_options={"api_version": "v1beta", "base_url": "https://api.avalai.ir"},
)

# Basic embedding with native API
result = client.models.embed_content(
    model="gemini-embedding-001", contents="What is the meaning of life?"
)

embedding = result.embeddings[0]
print(f"Embedding dimensions: {len(embedding.values)}")
print(f"First few values: {embedding.values[:5]}")

# Advanced usage with task type and custom dimensions
from google.genai import types

result = client.models.embed_content(
    model="gemini-embedding-001",
    contents=[
        "What is the meaning of life?",
        "What is the purpose of existence?",
        "How do I bake a cake?",
    ],
    config=types.EmbedContentConfig(
        task_type="SEMANTIC_SIMILARITY", output_dimensionality=768
    ),
)

# Calculate similarities using the embeddings
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

embeddings_matrix = np.array([emb.values for emb in result.embeddings])
similarity_matrix = cosine_similarity(embeddings_matrix)

print(
    f"Similarity between 'meaning of life' and 'purpose of existence': {similarity_matrix[0, 1]:.4f}"
)
print(
    f"Similarity between 'meaning of life' and 'bake a cake': {similarity_matrix[0, 2]:.4f}"
)
javascript
import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    apiKey: process.env.AVALAI_API_KEY,
    httpOptions: {"apiVersion": "v1beta", "baseUrl": "https://api.avalai.ir"}}
});

// Basic embedding with native API
const response = await ai.models.embedContent({
    model: "gemini-embedding-001",
    contents: "What is the meaning of life?"
});

const embedding = response.embeddings[0];
console.log(`Embedding dimensions: ${embedding.values.length}`);
console.log(`First few values: ${embedding.values.slice(0, 5)}`);

// Advanced usage with task type and custom dimensions
const advancedResponse = await ai.models.embedContent({
    model: "gemini-embedding-001",
    contents: [
        "What is the meaning of life?",
        "What is the purpose of existence?",
        "How do I bake a cake?"
    ],
    taskType: "SEMANTIC_SIMILARITY",
    outputDimensionality: 768
});

console.log(`Generated ${advancedResponse.embeddings.length} embeddings`);
bash
# Basic embedding with native API
curl "https://api.avalai.ir/v1beta/models/gemini-embedding-001:embedContent" \
  -H "x-goog-api-key: $AVALAI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "contents": [
      {"parts": [{"text": "What is the meaning of life?"}]}
    ]
  }'

# Advanced usage with task type and custom dimensions
curl "https://api.avalai.ir/v1beta/models/gemini-embedding-001:embedContent" \
  -H "x-goog-api-key: $AVALAI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "contents": [
      {"parts": [{"text": "What is the meaning of life?"}]},
      {"parts": [{"text": "What is the purpose of existence?"}]}
    ],
    "embedding_config": {
      "task_type": "SEMANTIC_SIMILARITY",
      "output_dimensionality": 768
    }
  }'

Gemini Embedding Response Format (Native API)

When using the native Gemini API, the response format differs from the OpenAI schema:

json
{
  "embeddings": [
    {
      "values": [
        0.0023064255,
        -0.009327292,
        -0.0028842222,
        ...
      ]
    }
  ]
}

Output Dimensionality Control

Gemini embeddings support Matryoshka Representation Learning (MRL), allowing you to use smaller dimensions without significant quality loss:

  • 3072 dimensions: Full model capacity (default, pre-normalized)
  • 1536 dimensions: Balanced performance and efficiency
  • 768 dimensions: Efficient with good performance
  • 512 dimensions: Compact with acceptable performance
  • 256 dimensions: Very compact
  • 128 dimensions: Minimal size

Important

For dimensions other than 3072, you should normalize the embeddings for optimal semantic similarity performance:

python
import numpy as np


# Normalize embeddings for dimensions < 3072
def normalize_embedding(embedding):
    embedding_array = np.array(embedding)
    return embedding_array / np.linalg.norm(embedding_array)


# Example usage
if len(embedding) < 3072:
    normalized_embedding = normalize_embedding(embedding)

RAG System Example with Gemini Embeddings

Here's a complete example of using Gemini embeddings for a Retrieval-Augmented Generation (RAG) system:

python
import os
import numpy as np
from openai import OpenAI
from sklearn.metrics.pairwise import cosine_similarity

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

# Sample knowledge base
documents = [
    "Paris is the capital of France and known for the Eiffel Tower.",
    "Tokyo is the capital of Japan and famous for its technology and culture.",
    "London is the capital of England and home to Big Ben.",
    "Berlin is the capital of Germany and known for its rich history.",
    "Rome is the capital of Italy and famous for the Colosseum.",
]

# Create embeddings for knowledge base using RETRIEVAL_DOCUMENT task type
doc_response = client.embeddings.create(
    model="gemini-embedding-001",
    input=documents,
    extra_body={"task_type": "RETRIEVAL_DOCUMENT", "output_dimensionality": 768},
)

doc_embeddings = np.array([item.embedding for item in doc_response.data])

# Normalize embeddings for optimal similarity computation
doc_embeddings = doc_embeddings / np.linalg.norm(doc_embeddings, axis=1, keepdims=True)


def search_knowledge_base(query, top_k=2):
    # Create query embedding using RETRIEVAL_QUERY task type
    query_response = client.embeddings.create(
        model="gemini-embedding-001",
        input=query,
        extra_body={"task_type": "RETRIEVAL_QUERY", "output_dimensionality": 768},
    )

    query_embedding = np.array(query_response.data[0].embedding)
    query_embedding = query_embedding / np.linalg.norm(query_embedding)

    # Calculate similarities
    similarities = cosine_similarity([query_embedding], doc_embeddings)[0]

    # Get top-k most similar documents
    top_indices = np.argsort(similarities)[-top_k:][::-1]

    results = []
    for idx in top_indices:
        results.append({"document": documents[idx], "similarity": similarities[idx]})

    return results


# Example usage
query = "What's the capital of France?"
results = search_knowledge_base(query)

print(f"Query: {query}")
for i, result in enumerate(results):
    print(f"{i+1}. {result['document']} (similarity: {result['similarity']:.4f})")

Error Handling

The API may return various error codes:

Status CodeDescription
400Bad Request - Your request is invalid.
401Unauthorized - Your API key is wrong.
403Forbidden - You don't have permission to access this resource.
404Not Found - The specified resource could not be found.
429Too Many Requests - You have exceeded your rate limit.
500Internal Server Error - We had a problem with our server.

For more information on handling errors, see the Error Handling guide.