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