Cohere

Cohere provides multimodal embedding models through its Embed API. There are two ways to use them with Qdrant:

  • Call the Cohere API from your application and send the vectors to Qdrant. This works with any Qdrant deployment, and it’s what most of this page covers.
  • On Qdrant Cloud, pass text or images to Qdrant and let Qdrant Cloud Inference call Cohere for you.

Models

ModelDimensionsContextInput
embed-v5.0-pro2048 (default), 1536, 1024, 768, 512, 256128k tokensText, images, mixed
embed-v5.0-fast2048 (default), 1536, 1024, 768, 512, 256128k tokensText, images, mixed
embed-v4.01536 (default), 1024, 512, 256128k tokensText, images, mixed

embed-v5.0-pro targets retrieval quality and embed-v5.0-fast targets latency. The two share an embedding space, and Cohere recommends indexing with Pro and querying with Fast. The v3 models, such as embed-english-v3.0 and embed-multilingual-v3.0, are the previous generation, with fixed dimensions and a 512-token context. Use an Embed v5 model for new projects.

Cohere lists cosine similarity, dot product, and Euclidean distance as supported metrics, and doesn’t document whether its vectors are normalized. These examples use Cosine, which doesn’t depend on vector length.

Setup

Install the Cohere SDK and the Qdrant client:

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

Create both clients and a collection sized for the model. The Cohere client reads your API key from the CO_API_KEY environment variable.

import cohere
from qdrant_client import QdrantClient, models

co = cohere.ClientV2()
client = QdrantClient(url="http://localhost:6333")

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

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

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

Embed Documents

Set input_type to search_document for content you store. The response returns one vector per input, in input order, so this example uses the input position as the point ID:

documents = [
    "Qdrant is a vector search engine.",
    "Cohere Embed models turn text and images into dense vectors.",
]

response = co.embed(
    model="embed-v5.0-pro",
    input_type="search_document",
    texts=documents,
    embedding_types=["float"],
)
vectors = response.embeddings.float_
assert vectors is not None

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

const response = await cohere.embed({
  model: "embed-v5.0-pro",
  inputType: "search_document",
  texts: documents,
  embeddingTypes: ["float"],
});

await client.upsert("{collection_name}", {
  points: response.embeddings.float!.map((vector, idx) => ({
    id: idx,
    vector,
    payload: { text: documents[idx] },
  })),
});

A request accepts up to 96 texts. Split larger datasets into several requests, and see Upload Points for batching on the Qdrant side.

Embed Queries

Set input_type to search_query for search queries. The input type tells the model how a vector will be used, so pair search_document for stored content with search_query for queries. This example embeds the query with embed-v5.0-fast, which shares the embedding space of embed-v5.0-pro:

response = co.embed(
    model="embed-v5.0-fast",
    input_type="search_query",
    texts=["What is Qdrant?"],
    embedding_types=["float"],
)
query_vectors = response.embeddings.float_
assert query_vectors is not None

hits = client.query_points(
    collection_name="{collection_name}",
    query=query_vectors[0],
    limit=3,
).points
const queryResponse = await cohere.embed({
  model: "embed-v5.0-fast",
  inputType: "search_query",
  texts: ["What is Qdrant?"],
  embeddingTypes: ["float"],
});

const queryVector = queryResponse.embeddings.float?.[0];
if (!queryVector) throw new Error("Cohere returned no query embedding");

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

The classification and clustering input types prepare vectors for those tasks instead of search.

Embed Images

Embed v5 and v4 models place images in the same embedding space as text, so a text query can find an image. Pass images as base64 data URLs in images. This example adds an image to the collection from Embed Documents:

import base64

with open("diagram.png", "rb") as f:
    image_url = "data:image/png;base64," + base64.b64encode(f.read()).decode()

response = co.embed(
    model="embed-v5.0-pro",
    input_type="search_document",
    images=[image_url],
    embedding_types=["float"],
)
image_vectors = response.embeddings.float_
assert image_vectors is not None

client.upsert(
    collection_name="{collection_name}",
    points=[models.PointStruct(id=2, vector=image_vectors[0], payload={"image": "diagram.png"})],
)
import { readFile } from "node:fs/promises";

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

const imageResponse = await cohere.embed({
  model: "embed-v5.0-pro",
  inputType: "search_document",
  images: [imageUrl],
  embeddingTypes: ["float"],
});

await client.upsert("{collection_name}", {
  points: [{ id: 2, vector: imageResponse.embeddings.float![0], payload: { image: "diagram.png" } }],
});

The images in one request can total up to 20 MB, in JPEG, PNG, WebP, or GIF format. To embed text and images together as one vector, use the inputs parameter, described in the Embed API reference.

Reduce Vector Size

Embed v5 and v4 models accept an output_dimension parameter (outputDimension in TypeScript) that returns a shorter vector. Set the collection’s size to the same value, and pass the same output_dimension when you embed queries:

response = co.embed(
    model="embed-v5.0-pro",
    input_type="search_document",
    texts=documents,
    output_dimension=512,
    embedding_types=["float"],
)
const reduced = await cohere.embed({
  model: "embed-v5.0-pro",
  inputType: "search_document",
  texts: documents,
  outputDimension: 512,
  embeddingTypes: ["float"],
});

Qdrant Cloud Inference

On Qdrant Cloud, Qdrant can call Cohere for you. Instead of a vector, send a Document or an Image with the model name prefixed with cohere/. Pass your Cohere API key in the cohere-api-key request header or in the options object. Qdrant does not store the key, so send it with every request. Cohere parameters such as output_dimension also go in options, and the collection’s vector size must match them, which is 512 in these examples. These examples use embed-v4.0, and images must be base64 data URLs.

To ingest an image:

PUT /collections/{collection_name}/points?wait=true
{
  "points": [
    {
      "id": 1,
      "vector": {
        "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC",
        "model": "cohere/embed-v4.0",
        "options": {
          "cohere-api-key": "<YOUR_COHERE_API_KEY>",
          "output_dimension": 512
        }
      }
    }
  ]
}
from qdrant_client import QdrantClient, models
from qdrant_client.context_headers import headers

client = QdrantClient(
    url="https://xyz-example.qdrant.io:6333", 
    api_key="<your-qdrant-api-key>",
    cloud_inference=True
)

with headers({"cohere-api-key": "<YOUR_COHERE_API_KEY>"}):
    client.upsert(
        collection_name="{collection_name}",
        points=[
            models.PointStruct(
                id=1,
                vector=models.Image(
                    image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC",
                    model="cohere/embed-v4.0",
                    options={
                        "output_dimension": 512
                    }
                )
            )
        ]
    )
import { QdrantClient, withHeaders } from "@qdrant/js-client-rest";

await withHeaders({ 'cohere-api-key': '<YOUR_COHERE_API_KEY>' }, () =>
    client.upsert("{collection_name}", {
        points: [
            {
                id: 1,
                vector: {
                    image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC',
                    model: 'cohere/embed-v4.0',
                    options: {
                        output_dimension: 512,
                    },
                },
            },
        ],
    })
);
use qdrant_client::{
    Payload, Qdrant,
    qdrant::{Image, PointStruct, UpsertPointsBuilder},
};
use std::collections::HashMap;

let mut options = HashMap::new();
options.insert("output_dimension".to_string(), 512.into());

client
    .with_header("cohere-api-key", "<YOUR_COHERE_API_KEY>")
    .upsert_points(UpsertPointsBuilder::new("{collection_name}",
        vec![
            PointStruct::new(1,
                Image {
                  image: Some("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC".into()),
                  model: "cohere/embed-v4.0".into(),
                  options,
                  },
                Payload::default())
            ]).wait(true))
        .await?;
import static io.qdrant.client.PointIdFactory.id;
import static io.qdrant.client.ValueFactory.value;
import static io.qdrant.client.VectorsFactory.vectors;

import io.grpc.Context;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.RequestHeaders;
import io.qdrant.client.grpc.Points.Image;
import io.qdrant.client.grpc.Points.PointStruct;
import java.util.List;
import java.util.Map;

    Context ctx = RequestHeaders.withHeader(
        Context.current(), "cohere-api-key", "<YOUR_COHERE_API_KEY>");

    ctx.call(() -> client
        .upsertAsync(
            "{collection_name}",
            List.of(
                PointStruct.newBuilder()
                    .setId(id(1))
                    .setVectors(
                        vectors(
                            Image.newBuilder()
                                .setModel("cohere/embed-v4.0")
                                .setImage(
                                    value(
                                        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC"))
                                .putAllOptions(
                                    Map.of(
                                        "output_dimension",
                                        value(512)))
                                .build()))
                    .build()))
        .get());
using Qdrant.Client;
using Qdrant.Client.Grpc;

using (RequestHeaders.Use("cohere-api-key", "<YOUR_COHERE_API_KEY>"))
    await client.UpsertAsync(
        collectionName: "{collection_name}",
        points: new List<PointStruct>
        {
            new()
            {
                Id = 1,
                Vectors = new Image()
                {
                    Model = "cohere/embed-v4.0",
                    Image_ =
                        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC",
                    Options =
                    {
                        ["output_dimension"] = 512,
                    },
                },
            },
        }
    );
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

ctx := qdrant.WithHeader(context.Background(), "cohere-api-key", "<YOUR_COHERE_API_KEY>")

client.Upsert(ctx, &qdrant.UpsertPoints{
	CollectionName: "{collection_name}",
	Points: []*qdrant.PointStruct{
		{
			Id: qdrant.NewIDNum(uint64(1)),
			Vectors: qdrant.NewVectorsImage(&qdrant.Image{
				Model: "cohere/embed-v4.0",
				Image: qdrant.NewValueString("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNk+M9Qz0AEYBxVSF+FAAhKDveksOjmAAAAAElFTkSuQmCC"),
				Options: qdrant.NewValueMap(map[string]any{
					"output_dimension": 512,
				}),
			}),
		},
	},
})

To search with text:

POST /collections/{collection_name}/points/query
{
  "query": {
    "text": "a green square",
    "model": "cohere/embed-v4.0",
    "options": {
      "cohere-api-key": "<YOUR_COHERE_API_KEY>",
      "output_dimension": 512
    }
  }
}
from qdrant_client import QdrantClient, models
from qdrant_client.context_headers import headers

client = QdrantClient(
    url="https://xyz-example.qdrant.io:6333", 
    api_key="<your-qdrant-api-key>",
    cloud_inference=True
)

with headers({"cohere-api-key": "<YOUR_COHERE_API_KEY>"}):
    client.query_points(
        collection_name="{collection_name}",
        query=models.Document(
            text="a green square", 
            model="cohere/embed-v4.0", 
            options={
                "output_dimension": 512
            }
        )
    )
import { QdrantClient, withHeaders } from "@qdrant/js-client-rest";

await withHeaders({ 'cohere-api-key': '<YOUR_COHERE_API_KEY>' }, () =>
    client.query("{collection_name}", {
        query: {
            text: 'a green square',
            model: 'cohere/embed-v4.0',
            options: {
                output_dimension: 512,
            },
        },
    })
);
use qdrant_client::{
    Qdrant,
    qdrant::{Document, Query, QueryPointsBuilder, Value},
};
use std::collections::HashMap;

let mut options = HashMap::<String, Value>::new();
options.insert("output_dimension".to_string(), 512.into());

client
    .with_header("cohere-api-key", "<YOUR_COHERE_API_KEY>")
    .query(
        QueryPointsBuilder::new("{collection_name}")
            .query(Query::new_nearest(Document {
                text: "a green square".into(),
                model: "cohere/embed-v4.0".into(),
                options,
            }))
            .build(),
    )
    .await?;
import static io.qdrant.client.QueryFactory.nearest;
import static io.qdrant.client.ValueFactory.value;

import io.grpc.Context;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.RequestHeaders;
import io.qdrant.client.grpc.Points.Document;
import io.qdrant.client.grpc.Points.QueryPoints;
import java.util.Map;

    Context ctx = RequestHeaders.withHeader(
        Context.current(), "cohere-api-key", "<YOUR_COHERE_API_KEY>");

    ctx.call(() -> client
        .queryAsync(
            QueryPoints.newBuilder()
                .setCollectionName("{collection_name}")
                .setQuery(
                    nearest(
                        Document.newBuilder()
                            .setModel("cohere/embed-v4.0")
                            .setText("a green square")
                            .putAllOptions(
                                Map.of(
                                    "output_dimension",
                                    value(512)))
                            .build()))
                .build())
        .get());
using Qdrant.Client;
using Qdrant.Client.Grpc;

using (RequestHeaders.Use("cohere-api-key", "<YOUR_COHERE_API_KEY>"))
    await client.QueryAsync(
        collectionName: "{collection_name}",
        query: new Document()
        {
            Model = "cohere/embed-v4.0",
            Text = "a green square",
            Options = { ["output_dimension"] = 512 },
        }
    );
import (
	"context"

	"github.com/qdrant/go-client/qdrant"
)

ctx := qdrant.WithHeader(context.Background(), "cohere-api-key", "<YOUR_COHERE_API_KEY>")

client.Query(ctx, &qdrant.QueryPoints{
	CollectionName: "{collection_name}",
	Query: qdrant.NewQueryDocument(&qdrant.Document{
		Text:  "a green square",
		Model: "cohere/embed-v4.0",
		Options: qdrant.NewValueMap(map[string]any{
			"output_dimension": 512,
		}),
	}),
})

For other ways to pass the key, see External Providers.

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.