Skip to main content
Lesson 11 of 14 · Codestral and Coding Agents: From Devstral to Vibe Code

Codestral Embed: Code Embeddings

Lesson 11 of 14 Updated November 2, 2026 Developer
On this page
  1. Codestral Embed: Semantic Search for Code
  2. What Is a Code Embedding?
  3. Technical Specifications
  4. Using the API
  5. Semantic Search in a Codebase
  6. Advanced Use Cases
  7. Key Takeaways

Codestral Embed: Semantic Search for Code

Generating and completing code isn’t enough. You also need to find the file in a repository of hundreds that already solves your problem. That’s the job of Mistral AI’s third specialized tool: Codestral Embed (v25.05). This embedding model turns code snippets into numerical vectors, enabling semantic search across repositories.

What Is a Code Embedding?

An embedding is a dense vector representation of text or a code snippet. The key property is simple: two semantically similar snippets produce vectors that are close together in vector space, even if their syntax looks nothing alike. Consider the two functions below. They have different names, different variable names, and different implementations.

# Function 1
def calculer_moyenne(nombres):
    return sum(nombres) / len(nombres)

# Function 2
def average(values):
    total = 0
    for v in values:
        total += v
    return total / len(values)

A grep search would never find the second function starting from the first. Codestral Embed, however, produces nearby vectors for both because they solve the same problem.

Technical Specifications

The model ID is codestral-embed-latest (v25.05). You call it on the /v1/embeddings endpoint. It handles source code in all languages supported by Codestral. Its standout feature is configurable dimensions, ranging from 1536 to 3072. The 1536-dimensional setting offers a solid quality-to-cost ratio and works for most use cases. The 3072-dimensional setting targets maximum quality for the most demanding searches. The rule is constant: more dimensions mean better semantic precision, but also higher storage costs and more computation for every comparison. For a medium-sized repository, start at 1536 and only increase if results seem fuzzy.

Using the API

The basic call looks like the chat endpoint: instantiate the client, pass a snippet, and get a vector back.

from mistralai.client import Mistral
import os

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

code_snippet = """
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
"""

response = client.embeddings.create(
    model="codestral-embed-latest",
    inputs=[code_snippet],
)

embedding = response.data[0].embedding
print(f"Dimensions: {len(embedding)}")
print(f"First values: {embedding[:5]}")

Note that the inputs parameter is a list. This detail matters: to index an entire repository, you send multiple snippets in a single request rather than one request per file. On a real repository, the difference adds up to minutes saved.

code_snippets = [
    "def tri_bulle(liste): ...",
    "def tri_rapide(liste): ...",
    "def tri_fusion(liste): ...",
    "def recherche_binaire(liste, cible): ...",
]

response = client.embeddings.create(
    model="codestral-embed-latest",
    inputs=code_snippets,
)

embeddings = [item.embedding for item in response.data]

Semantic Search in a Codebase

The primary use case follows directly from this: instead of searching by keywords, you search by intent. The pipeline has two steps. First, index the codebase once, attaching an embedding to each file. Then, transform the query into a vector and rank files by cosine similarity, the standard measure of proximity between two vectors.

import numpy as np
from mistralai.client import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# 1. Index the codebase (do this once)
def index_codebase(files: list[dict]) -> list[dict]:
    """Indexes a list of files with their embeddings."""
    contents = [f["content"] for f in files]

    response = client.embeddings.create(
        model="codestral-embed-latest",
        inputs=contents,
    )

    for i, file in enumerate(files):
        file["embedding"] = response.data[i].embedding

    return files

# 2. Search by intent
def search_code(query: str, index: list[dict], top_k: int = 5) -> list[dict]:
    """Semantic search in the indexed codebase."""
    response = client.embeddings.create(
        model="codestral-embed-latest",
        inputs=[query],
    )
    query_vector = np.array(response.data[0].embedding)

    # Calculate cosine similarity
    results = []
    for file in index:
        file_vector = np.array(file["embedding"])
        similarity = np.dot(query_vector, file_vector) / (
            np.linalg.norm(query_vector) * np.linalg.norm(file_vector)
        )
        results.append({**file, "score": similarity})

    results.sort(key=lambda x: x["score"], reverse=True)
    return results[:top_k]

# 3. Usage
results = search_code(
    "function that validates an email address",
    index=my_index
)

Look at the final query: “function that validates an email address.” It contains no project identifiers, no file names, and no code keywords. That’s the whole difference compared to text search, and it makes the tool usable even for someone new to the repository.

Advanced Use Cases

The most powerful combination chains Codestral Embed with Codestral or a general-purpose model like Mistral Small 4. This is the RAG (Retrieval-Augmented Generation) pattern applied to code. You first retrieve relevant files, inject them into the system message, and then ask your question. The model then answers based on your codebase, not just its general knowledge of the language.

# 1. Find relevant files with Codestral Embed
results = search_code("HTTP error handling", index)

# 2. Build context
context = "\n\n".join([r["content"] for r in results[:3]])

# 3. Generate a response with Codestral
response = client.chat.complete(
    model="codestral-latest",
    messages=[
        {"role": "system", "content": f"Here is the relevant code from the project:\n{context}"},
        {"role": "user", "content": "How can I improve HTTP error handling in this project?"}
    ],
)

The same index serves a less flashy but highly valuable task: duplicate code detection. By comparing every pair of functions and flagging those with similarity above a threshold, you get a list of refactoring candidates that no one on the team had spotted.

# Compare every pair of functions
for i, func_a in enumerate(functions):
    for j, func_b in enumerate(functions):
        if i >= j:
            continue
        similarity = cosine(func_a["embedding"], func_b["embedding"])
        if similarity > 0.90:
            print(f"Potential duplication: {func_a['name']} <-> {func_b['name']}")

You should tune the 0.90 threshold on your own code before drawing conclusions. Set it too low, and it flags functions that look alike but do different things. Set it too high, and it catches only literal copy-pastes—the ones you would have found anyway.

Key Takeaways

  • Codestral Embed (v25.05) turns code into vectors for semantic search
  • It supports 1536 to 3072 dimensions depending on your precision needs
  • Semantic search lets you search by intent, not keywords
  • The RAG pattern (retrieval + generation) is the most powerful use case
  • Embeddings also enable duplicate detection and code clustering