Mistral

Mistral AI provides a text embedding model and a code embedding model through its Embeddings API. There are two ways to use them with Qdrant:

  • Call the Mistral 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 to Qdrant and let Qdrant Cloud Inference call Mistral Embed through OpenRouter for you.

Models

ModelDimensionsReducibleMax Tokens per Input
mistral-embed1024No8192
codestral-embed1536 (up to 3072)Yes8192

mistral-embed is for general text. codestral-embed is for code retrieval. To pin a version, use mistral-embed-2312 or codestral-embed-2505.

Mistral embeddings are normalized to length 1, so the Cosine, Dot, and Euclidean distance metrics rank results identically. This page uses Cosine.

Setup

Install the Mistral SDK and the Qdrant client:

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

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

from mistralai.client import Mistral
from qdrant_client import QdrantClient, models

mistral_client = Mistral()
client = QdrantClient(url="http://localhost:6333")

MODEL = "mistral-embed"

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

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

const MODEL = "mistral-embed";

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

Embed Documents

One request embeds a list of inputs. Each item in the response carries the index of its input, which this example uses as the point ID. The SDKs type index and embedding as optional, so the example asserts that they’re set:

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

response = mistral_client.embeddings.create(model=MODEL, inputs=documents)

points = []
for item in response.data:
    assert item.index is not None and item.embedding is not None
    points.append(
        models.PointStruct(
            id=item.index,
            vector=item.embedding,
            payload={"text": documents[item.index]},
        )
    )

client.upsert(collection_name="{collection_name}", points=points)
const documents = [
  "Qdrant is a vector search engine.",
  "Mistral embedding models turn text into dense vectors.",
];

const response = await mistral.embeddings.create({ model: MODEL, inputs: documents });

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

Embed Queries

Mistral models have no separate query mode. Embed the query with the same model you used for the documents:

query_vector = (
    mistral_client.embeddings.create(model=MODEL, inputs=["What is Qdrant?"])
    .data[0]
    .embedding
)
assert query_vector is not None

hits = client.query_points(
    collection_name="{collection_name}",
    query=query_vector,
    limit=3,
).points
const queryResponse = await mistral.embeddings.create({
  model: MODEL,
  inputs: ["What is Qdrant?"],
});

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

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

Reduce Vector Size

codestral-embed accepts an output_dimension parameter of up to 3072. Its dimensions are ordered by relevance, so a smaller value keeps the most informative ones. Set the collection’s size to the same value, and pass the same output_dimension when you embed queries:

response = mistral_client.embeddings.create(
    model="codestral-embed",
    inputs=["def add(a, b):\n    return a + b"],
    output_dimension=512,
)
const reduced = await mistral.embeddings.create({
  model: "codestral-embed",
  inputs: ["def add(a, b):\n    return a + b"],
  outputDimension: 512,
});

mistral-embed always returns 1024 dimensions. To store its vectors in less memory, use Binary Quantization, which shrinks each vector by 32 times. In this test of mistral-embed, recall against the exact nearest neighbors reaches 94.5% at an oversampling of 3 and a limit of 100, with rescoring enabled:

Oversampling112233
RescoreFalseTrueFalseTrueFalseTrue
Limit
100.534440.8577780.5344440.9188890.5333330.941111
200.5083330.8377780.5083330.9038890.5083330.927778
500.4922220.8344440.4922220.9035560.4928890.940889
1000.4991110.8454440.4985560.9183330.4976670.944556

Qdrant Cloud Inference

On Qdrant Cloud, Qdrant can call Mistral Embed for you through OpenRouter. Instead of a vector, send a Document with the model name openrouter/mistralai/mistral-embed-2312. Pass your OpenRouter API key in the openrouter-api-key request header or in the options object. Qdrant does not store the key, so send it with every request. The collection’s vector size must be 1024.

To ingest documents:

PUT /collections/{collection_name}/points?wait=true
{
  "points": [
    {
      "id": 1,
      "vector": {
        "text": "Recipe for baking chocolate chip cookies",
        "model": "openrouter/mistralai/mistral-embed-2312",
        "options": {
          "openrouter-api-key": "<YOUR_OPENROUTER_API_KEY>"
        }
      }
    }
  ]
}
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({"openrouter-api-key": "<YOUR_OPENROUTER_API_KEY>"}):
    client.upsert(
        collection_name="{collection_name}",
        points=[
            models.PointStruct(
                id=1,
                vector=models.Document(
                    text="Recipe for baking chocolate chip cookies",
                    model="openrouter/mistralai/mistral-embed-2312",
                )
            )
        ]
    )
import { QdrantClient, withHeaders } from "@qdrant/js-client-rest";

await withHeaders({ 'openrouter-api-key': '<YOUR_OPENROUTER_API_KEY>' }, () =>
    client.upsert("{collection_name}", {
        points: [
            {
                id: 1,
                vector: {
                    text: 'Recipe for baking chocolate chip cookies',
                    model: 'openrouter/mistralai/mistral-embed-2312',
                },
            },
        ],
    })
);
use qdrant_client::{
    Payload, Qdrant,
    qdrant::{Document, PointStruct, UpsertPointsBuilder},
};
use std::collections::HashMap;

client
    .with_header("openrouter-api-key", "<YOUR_OPENROUTER_API_KEY>")
    .upsert_points(UpsertPointsBuilder::new("{collection_name}",
        vec![
            PointStruct::new(1,
                Document {
                  text: "Recipe for baking chocolate chip cookies".into(),
                  model: "openrouter/mistralai/mistral-embed-2312".into(),
                  options: HashMap::new(),
                  },
                Payload::default())
            ]).wait(true))
        .await?;
import static io.qdrant.client.PointIdFactory.id;
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.Document;
import io.qdrant.client.grpc.Points.PointStruct;
import java.util.List;

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

ctx.call(() -> client
    .upsertAsync(
        "{collection_name}",
        List.of(
            PointStruct.newBuilder()
                .setId(id(1))
                .setVectors(
                    vectors(
                        Document.newBuilder()
                            .setModel("openrouter/mistralai/mistral-embed-2312")
                            .setText("Recipe for baking chocolate chip cookies")
                            .build()))
                .build()))
    .get());
using Qdrant.Client;
using Qdrant.Client.Grpc;

using (RequestHeaders.Use("openrouter-api-key", "<YOUR_OPENROUTER_API_KEY>"))
    await client.UpsertAsync(
        collectionName: "{collection_name}",
        points: new List<PointStruct>
        {
            new()
            {
                Id = 1,
                Vectors = new Document()
                {
                    Model = "openrouter/mistralai/mistral-embed-2312",
                    Text = "Recipe for baking chocolate chip cookies",
                },
            },
        }
    );
import (
	"context"

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

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

client.Upsert(ctx, &qdrant.UpsertPoints{
	CollectionName: "{collection_name}",
	Points: []*qdrant.PointStruct{
		{
			Id: qdrant.NewIDNum(uint64(1)),
			Vectors: qdrant.NewVectorsDocument(&qdrant.Document{
				Model: "openrouter/mistralai/mistral-embed-2312",
				Text:  "Recipe for baking chocolate chip cookies",
			}),
		},
	},
})

To search:

POST /collections/{collection_name}/points/query
{
  "query": {
    "text": "How to bake cookies?",
    "model": "openrouter/mistralai/mistral-embed-2312",
    "options": {
      "openrouter-api-key": "<YOUR_OPENROUTER_API_KEY>"
    }
  }
}
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({"openrouter-api-key": "<YOUR_OPENROUTER_API_KEY>"}):
    client.query_points(
        collection_name="{collection_name}",
        query=models.Document(
            text="How to bake cookies?",
            model="openrouter/mistralai/mistral-embed-2312",
        )
    )
import { QdrantClient, withHeaders } from "@qdrant/js-client-rest";

await withHeaders({ 'openrouter-api-key': '<YOUR_OPENROUTER_API_KEY>' }, () =>
    client.query("{collection_name}", {
        query: {
            text: 'How to bake cookies?',
            model: 'openrouter/mistralai/mistral-embed-2312',
        },
    })
);
use qdrant_client::{
    Qdrant,
    qdrant::{Document, Query, QueryPointsBuilder},
};
use std::collections::HashMap;

client
    .with_header("openrouter-api-key", "<YOUR_OPENROUTER_API_KEY>")
    .query(
        QueryPointsBuilder::new("{collection_name}")
            .query(Query::new_nearest(Document {
                text: "How to bake cookies?".into(),
                model: "openrouter/mistralai/mistral-embed-2312".into(),
                options: HashMap::new(),
            }))
            .build(),
    )
    .await?;
import static io.qdrant.client.QueryFactory.nearest;

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;

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

ctx.call(() -> client
    .queryAsync(
        QueryPoints.newBuilder()
            .setCollectionName("{collection_name}")
            .setQuery(
                nearest(
                    Document.newBuilder()
                        .setModel("openrouter/mistralai/mistral-embed-2312")
                        .setText("How to bake cookies?")
                        .build()))
            .build())
    .get());
using Qdrant.Client;
using Qdrant.Client.Grpc;

using (RequestHeaders.Use("openrouter-api-key", "<YOUR_OPENROUTER_API_KEY>"))
    await client.QueryAsync(
        collectionName: "{collection_name}",
        query: new Document()
        {
            Model = "openrouter/mistralai/mistral-embed-2312",
            Text = "How to bake cookies?",
        }
    );
import (
	"context"

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

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

client.Query(ctx, &qdrant.QueryPoints{
	CollectionName: "{collection_name}",
	Query: qdrant.NewQueryDocument(&qdrant.Document{
		Model: "openrouter/mistralai/mistral-embed-2312",
		Text:  "How to bake cookies?",
	}),
})

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.