Voyage AI

Voyage AI provides text, code, and multimodal embedding models. There are two ways to use them with Qdrant:

  • Call the Voyage AI API from your application and send the vectors to Qdrant. This is what most of this page covers.
  • Run the open-weight voyage-4-nano model on your own hardware.

Models

ModelDimensionsContextInput
voyage-4-large1024 (default), 2048, 512, 25632,000 tokensText
voyage-41024 (default), 2048, 512, 25632,000 tokensText
voyage-4-lite1024 (default), 2048, 512, 25632,000 tokensText
voyage-code-41024 (default), 2048, 512, 25632,000 tokensText (code)
voyage-multimodal-3.51024 (default), 2048, 512, 25632,000 tokensText, images, video
voyage-4-nano (open weights)2048 (default), 1024, 512, 25632,000 tokensText

voyage-4-large targets retrieval quality, voyage-4 balances quality and cost, and voyage-4-lite targets latency and cost. The Voyage 4 series models, including voyage-4-nano, share an embedding space, so you can index with one model and query with another. Voyage AI also offers the domain models voyage-finance-2 and voyage-law-2. Earlier general-purpose models, such as voyage-3.5, voyage-3-large, and voyage-large-2, are the previous generation. Use a Voyage 4 series model for new projects.

Voyage AI embeddings are normalized to length 1, so the Cosine, Dot, and Euclidean distance metrics rank results identically. These examples use Cosine.

Setup

Install the Voyage AI SDK and the Qdrant client:

  • Python: pip install voyageai qdrant-client
  • TypeScript: npm install voyageai @qdrant/js-client-rest

Create both clients and a collection sized for the model. The Voyage AI client reads your API key from the VOYAGE_API_KEY environment variable. To create a key, see API Key and Installation.

import voyageai
from qdrant_client import QdrantClient, models

vo = voyageai.Client()
client = QdrantClient(url="http://localhost:6333")

client.create_collection(
    collection_name="{collection_name}",
    vectors_config=models.VectorParams(size=1024, distance=models.Distance.COSINE),
)
import { VoyageAIClient } from "voyageai";
import { QdrantClient } from "@qdrant/js-client-rest";

const voyage = new VoyageAIClient();
const client = new QdrantClient({ url: "http://localhost:6333" });

await client.createCollection("{collection_name}", {
  vectors: { size: 1024, distance: "Cosine" },
});

Embed Documents

Set input_type to document for content you store. The vectors come back in input order, and each item of the API response carries the index of its input. These examples use that position as the point ID:

documents = [
    "Qdrant is a vector search engine.",
    "Voyage AI embedding models turn text into dense vectors.",
]

response = vo.embed(documents, model="voyage-4-large", input_type="document")

client.upsert(
    collection_name="{collection_name}",
    points=[
        models.PointStruct(id=idx, vector=vector, payload={"text": text})
        for idx, (vector, text) in enumerate(zip(response.embeddings, documents))
    ],
)
const documents = [
  "Qdrant is a vector search engine.",
  "Voyage AI embedding models turn text into dense vectors.",
];

const response = await voyage.embed({
  input: documents,
  model: "voyage-4-large",
  inputType: "document",
});

await client.upsert("{collection_name}", {
  points: response.data!.map((item) => ({
    id: item.index!,
    vector: item.embedding!,
    payload: { text: documents[item.index!] },
  })),
});

A request accepts up to 1,000 texts. The total token limit per request is 120,000 for voyage-4-large, 320,000 for voyage-4, and 1,000,000 for voyage-4-lite. Split larger datasets into several requests, and see Upload Points for batching on the Qdrant side.

Embed Queries

Set input_type to query for search queries. Voyage AI prepends a retrieval prompt that differs for queries and documents, which tailors each vector for retrieval:

query_vector = vo.embed(
    ["What is Qdrant?"], model="voyage-4-large", input_type="query"
).embeddings[0]

hits = client.query_points(
    collection_name="{collection_name}",
    query=query_vector,
    limit=3,
).points
const queryResponse = await voyage.embed({
  input: ["What is Qdrant?"],
  model: "voyage-4-large",
  inputType: "query",
});

const queryVector = queryResponse.data?.[0]?.embedding;
if (!queryVector) throw new Error("Voyage AI returned no query embedding");

const { points: hits } = await client.query("{collection_name}", {
  query: queryVector,
  limit: 3,
});

Reduce Vector Size

The models in the Models table with several dimensions accept an output_dimension parameter (outputDimension in TypeScript). Set the collection’s size to the same value, and pass the same output_dimension when you embed queries:

response = vo.embed(
    documents,
    model="voyage-4-large",
    input_type="document",
    output_dimension=512,
)
const reduced = await voyage.embed({
  input: documents,
  model: "voyage-4-large",
  inputType: "document",
  outputDimension: 512,
});

To keep the full vectors but store them in less memory, use Quantization.

Embed Images

voyage-multimodal-3.5 embeds text, images, and video in one embedding space, so a text query can find an image. It’s not part of the Voyage 4 series, so store its vectors in a separate collection. In Python, each input is a list that can mix strings and Pillow images:

from PIL import Image

client.create_collection(
    collection_name="{image_collection_name}",
    vectors_config=models.VectorParams(size=1024, distance=models.Distance.COSINE),
)

image_inputs = [[Image.open("diagram.png")]]

image_response = vo.multimodal_embed(
    image_inputs,
    model="voyage-multimodal-3.5",
    input_type="document",
)

client.upsert(
    collection_name="{image_collection_name}",
    points=[models.PointStruct(id=0, vector=image_response.embeddings[0], payload={"image": "diagram.png"})],
)

query_inputs = [["How is Qdrant deployed?"]]

query_vector = vo.multimodal_embed(
    query_inputs, model="voyage-multimodal-3.5", input_type="query"
).embeddings[0]

hits = client.query_points(
    collection_name="{image_collection_name}",
    query=query_vector,
    limit=3,
).points
import { readFile } from "node:fs/promises";

await client.createCollection("{image_collection_name}", {
  vectors: { size: 1024, distance: "Cosine" },
});

const imageBase64 = "data:image/png;base64," + (await readFile("diagram.png")).toString("base64");

const imageResponse = await voyage.multimodalEmbed({
  inputs: [{ content: [{ type: "image_base64", imageBase64 }] }],
  model: "voyage-multimodal-3.5",
  inputType: "document",
});

await client.upsert("{image_collection_name}", {
  points: [{ id: 0, vector: imageResponse.data![0].embedding!, payload: { image: "diagram.png" } }],
});

const imageQuery = await voyage.multimodalEmbed({
  inputs: [{ content: [{ type: "text", text: "How is Qdrant deployed?" }] }],
  model: "voyage-multimodal-3.5",
  inputType: "query",
});

const imageQueryVector = imageQuery.data?.[0]?.embedding;
if (!imageQueryVector) throw new Error("Voyage AI returned no query embedding");

const { points: imageHits } = await client.query("{image_collection_name}", {
  query: imageQueryVector,
  limit: 3,
});

A request accepts up to 1,000 inputs and 320,000 tokens in total. Each image can be up to 16 million pixels and 20 MB. For video input, see Multimodal Embeddings.

Run voyage-4-nano Locally

voyage-4-nano is an open-weight model on Hugging Face, released under the Apache 2.0 license, with about 340 million parameters. The Python SDK runs it locally through sentence-transformers, without an API key. It requires Python 3.10 or later:

pip install "voyageai[local]"

Pass voyage-4-nano as the model, with the same calls as the API models. Because it shares the Voyage 4 embedding space, this example embeds a query locally and searches the documents indexed with voyage-4-large in Embed Documents. Set output_dimension to match the collection’s vector size:

query_vector = vo.embed(
    ["What is Qdrant?"],
    model="voyage-4-nano",
    input_type="query",
    output_dimension=1024,
).embeddings[0]

hits = client.query_points(
    collection_name="{collection_name}",
    query=query_vector,
    limit=3,
).points

To run without the API entirely, embed the documents with voyage-4-nano too.

Store and Search the Vectors

Next Steps

Was this page useful?

Thank you for your feedback! 🙏

We are sorry to hear that. 😔 You can edit this page on GitHub, or create a GitHub issue.