Aller au contenu principal

Cas d'Usage : Code Embeddings

Au-delà de la recherche

Les embeddings de code ne servent pas uniquement à la recherche sémantique. Ils ouvrent la porte à des applications avancées : analytics de répertoire, clustering, détection de doublons, et assistants de développement. Dans cette leçon, vous allez explorer ces cas d’usage avec du code Python concret.

Analytics de répertoire

Analysez la structure sémantique d’un projet pour comprendre comment le code est organisé :

import numpy as np
from sklearn.cluster import KMeans
from mistralai import Mistral

client = Mistral(api_key=api_key)

def analyze_repo(code_files, n_clusters=5):
    """Analyser la structure sémantique d'un répertoire."""
    # Encoder tous les fichiers
    inputs = [f["content"][:3000] for f in code_files]
    response = client.embeddings.create(
        model="codestral-embed",
        inputs=inputs,
    )
    embeddings = np.array([d.embedding for d in response.data])

    # Clustering K-Means
    kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
    labels = kmeans.fit_predict(embeddings)

    # Regrouper les fichiers par cluster
    clusters = {}
    for i, label in enumerate(labels):
        if label not in clusters:
            clusters[label] = []
        clusters[label].append(code_files[i]["path"])

    return clusters

# Utilisation
clusters = analyze_repo(code_files, n_clusters=5)
for cluster_id, files in clusters.items():
    print(f"\nCluster {cluster_id} ({len(files)} fichiers):")
    for f in files[:5]:
        print(f"  - {f}")

Détection de doublons

Identifiez le code dupliqué ou quasi-dupliqué dans votre base :

from sklearn.metrics.pairwise import cosine_similarity

def find_duplicates(code_files, embeddings, threshold=0.95):
    """Trouver les paires de fichiers quasi-identiques."""
    sim_matrix = cosine_similarity(embeddings)
    duplicates = []

    for i in range(len(code_files)):
        for j in range(i + 1, len(code_files)):
            if sim_matrix[i][j] >= threshold:
                duplicates.append({
                    "file_a": code_files[i]["path"],
                    "file_b": code_files[j]["path"],
                    "similarity": float(sim_matrix[i][j]),
                })

    # Trier par similarité décroissante
    duplicates.sort(key=lambda x: x["similarity"], reverse=True)
    return duplicates

# Trouver les doublons
dupes = find_duplicates(code_files, embeddings, threshold=0.92)
print(f"{len(dupes)} paires de doublons potentiels trouvées:")
for d in dupes[:10]:
    print(f"  {d['similarity']:.3f} : {d['file_a']} <-> {d['file_b']}")

Clustering par fonctionnalité

Regroupez automatiquement le code par domaine fonctionnel :

from sklearn.cluster import DBSCAN

def cluster_by_functionality(code_files, embeddings, eps=0.3, min_samples=2):
    """Regrouper le code par fonctionnalité avec DBSCAN."""
    # DBSCAN sur les distances cosinus
    distance_matrix = 1 - cosine_similarity(embeddings)
    clustering = DBSCAN(eps=eps, min_samples=min_samples, metric="precomputed")
    labels = clustering.fit_predict(distance_matrix)

    # Organiser par cluster
    groups = {}
    for i, label in enumerate(labels):
        group_name = f"Groupe {label}" if label >= 0 else "Non classé"
        if group_name not in groups:
            groups[group_name] = []
        groups[group_name].append(code_files[i]["path"])

    return groups

groups = cluster_by_functionality(code_files, embeddings)
for name, files in groups.items():
    print(f"\n{name} ({len(files)} fichiers):")
    for f in files[:3]:
        print(f"  - {f}")

Assistant de code contextuel

Construisez un assistant qui trouve le contexte pertinent pour répondre à une question de développement :

def code_assistant(question, code_files, embeddings, top_k=3):
    """Trouver le code pertinent pour répondre à une question."""
    # Encoder la question
    response = client.embeddings.create(
        model="codestral-embed",
        inputs=[question],
    )
    query_emb = np.array(response.data[0].embedding)

    # Trouver le code le plus pertinent
    sims = cosine_similarity([query_emb], embeddings)[0]
    top_indices = np.argsort(sims)[::-1][:top_k]

    context_parts = []
    for idx in top_indices:
        if sims[idx] > 0.5:  # Seuil minimal
            context_parts.append(
                f"# Fichier: {code_files[idx]['path']}\n"
                f"{code_files[idx]['content'][:1500]}"
            )

    context = "\n\n---\n\n".join(context_parts)

    # Construire le prompt pour le LLM
    prompt = f"""Voici du code pertinent de notre projet :

{context}

Question du développeur : {question}

Répondez en vous basant sur le code ci-dessus."""

    # Appeler le LLM avec le contexte
    chat_response = client.chat.complete(
        model="mistral-large-latest",
        messages=[{"role": "user", "content": prompt}],
    )

    return chat_response.choices[0].message.content

# Utilisation
answer = code_assistant(
    "Comment fonctionne l'authentification dans ce projet ?",
    code_files,
    embeddings,
)
print(answer)

Métriques de qualité de code

Utilisez les embeddings pour détecter les fichiers atypiques qui pourraient nécessiter une revue :

def detect_outliers(code_files, embeddings, threshold=2.0):
    """Détecter les fichiers de code atypiques."""
    # Calculer le centroïde (vecteur moyen)
    centroid = embeddings.mean(axis=0)

    # Distance de chaque fichier au centroïde
    distances = np.linalg.norm(embeddings - centroid, axis=1)

    # Fichiers au-delà de N écarts-types
    mean_dist = distances.mean()
    std_dist = distances.std()

    outliers = []
    for i, dist in enumerate(distances):
        z_score = (dist - mean_dist) / std_dist
        if z_score > threshold:
            outliers.append({
                "path": code_files[i]["path"],
                "z_score": float(z_score),
            })

    outliers.sort(key=lambda x: x["z_score"], reverse=True)
    return outliers

outliers = detect_outliers(code_files, embeddings)
print(f"{len(outliers)} fichiers atypiques:")
for o in outliers:
    print(f"  z={o['z_score']:.2f} : {o['path']}")

Points clés à retenir

  • Les embeddings de code permettent le clustering automatique par fonctionnalité
  • La détection de doublons utilise un seuil de similarité cosinus (0.92-0.95)
  • Un assistant de code combine la recherche sémantique avec un LLM pour du RAG sur le code
  • Les fichiers atypiques (outliers) peuvent signaler du code à réviser
  • DBSCAN est préférable à K-Means quand le nombre de groupes est inconnu