# Comment fonctionnent les embeddings ?

# Introduction

Un embedding est une représentation mathématique d'un texte (ou du code) sous forme de vecteur de nombres. C'est la base de la recherche sémantique.

# Principe de base

# Du texte aux nombres

Au lieu de comparer des mots directement, on convertit le code en vecteurs :

Texte original : "def authenticate_user(username, password)"
                      ↓
Embedding (vecteur simplifié) : [0.12, -0.45, 0.89, 0.34, ...]
                                 ↑
                        384 ou 768 nombres

# Pourquoi des vecteurs ?

Les vecteurs permettent de mesurer la similarité sémantique :

"authenticate user"     → [0.8, 0.2, 0.1]
"login with password"   → [0.7, 0.3, 0.15]  ← Proche ! (même concept)
"delete database"       → [0.1, 0.9, 0.05]  ← Très différent

Distance entre vecteurs = similarité de sens

# Comment ça marche dans mgrep

# Étape 1 : Indexation

# Code à indexer
code = """
def validate_email(email):
    pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
    return re.match(pattern, email)
"""

# Le modèle d'embedding le convertit
embedding = model.encode(code)
# → [0.23, -0.56, 0.12, ..., 0.89]  (768 nombres)

# Stocké dans Elasticsearch
elasticsearch.index(code_content=code, embedding=embedding)

# Étape 2 : Recherche

# Votre requête
query = "check if email is valid"

# Convertie en vecteur avec le MÊME modèle
query_embedding = model.encode(query)
# → [0.25, -0.52, 0.15, ..., 0.87]

# Elasticsearch trouve les vecteurs les plus proches
# Plus le vecteur est proche, plus le code est pertinent !

# Visualisation simplifiée

Imaginez un espace 3D (en réalité c'est 768D) :

            authenticate_user()
                  ●
                 /
                /
               /  Distance courte = similaire
              /
             ●  "login verification"



                          ● "delete file"
                    (loin = pas similaire)

# Les dimensions d'un embedding

# Qu'est-ce qu'une dimension ?

  • 384 dimensions = vecteur de 384 nombres
  • 768 dimensions = vecteur de 768 nombres

# Plus de dimensions = Plus d'information ?

Oui, généralement :

Modèle 384 dims : [0.12, -0.45, 0.89, ..., 0.34]  (384 valeurs)
                   ↓
            Peut capturer : syntaxe basique, mots-clés

Modèle 768 dims : [0.12, -0.45, 0.89, ..., 0.67]  (768 valeurs)
                   ↓
            Peut capturer : nuances sémantiques, contexte, relations

Trade-off :

  • Plus de dimensions = meilleure précision
  • Plus de dimensions = plus lent, index plus gros

# Types de modèles d'embedding

# 1. Modèles génériques (texte)

Exemple : all-MiniLM-L6-v2

Entraîné sur : Wikipedia, livres, articles
              ↓
Bon pour : texte naturel, documentation
Limité pour : code source, syntaxe spécifique

# 2. Modèles spécialisés code

Exemple : jinaai/jina-embeddings-v2-base-code

Entraîné sur : GitHub, millions de dépôts
              ↓
Bon pour : code source, noms de fonctions, patterns
Comprend : camelCase, snake_case, conventions de nommage

# 3. Modèles BERT adaptés (mean pooling)

Exemple : microsoft/codebert-base

Entraîné pour : complétion de code, classification
              ↓
Adapté avec mean pooling pour : embeddings (sous-optimal)
Résultat : moins bon pour recherche sémantique

# Mean Pooling : le problème actuel de mgrep

# Qu'est-ce que le mean pooling ?

BERT produit un vecteur pour chaque mot du code :

Code : "def login(user, pwd)"

BERT produit :
  "def"   → [0.1, 0.2, ...]
  "login" → [0.5, 0.8, ...]
  "user"  → [0.3, 0.1, ...]
  "pwd"   → [0.2, 0.4, ...]

Mean pooling = faire la moyenne de tout :

Embedding final = moyenne([
    [0.1, 0.2, ...],  # def
    [0.5, 0.8, ...],  # login
    [0.3, 0.1, ...],  # user
    [0.2, 0.4, ...]   # pwd
])
= [0.275, 0.375, ...]

# Pourquoi c'est sous-optimal ?

Perte de structure :

  • Tous les mots ont le même poids
  • def (mot-clé) = même importance que user (variable)

Pas entraîné pour ça :

  • CodeBERT a appris à compléter du code, pas à chercher
  • La moyenne n'est qu'une approximation

Solution : Utiliser un modèle natif sentence-transformers qui a appris la meilleure façon d'agréger les mots.

# Comparaison concrète

# Requête : "authenticate user with password"

Avec CodeBERT (mean pooling) :

Trouve :
1. create_app (config JWT)     ← Pas vraiment lié
2. MongoDB.init_app             ← Pas du tout lié
3. authenticate_user            ← Correct mais rank 3

Avec Jina Code (natif) :

Trouve :
1. authenticate_user            ← Exact !
2. verify_password              ← Très pertinent
3. check_credentials            ← Pertinent

# En résumé

Concept Explication simple
Embedding Traduction du code en vecteur de nombres
Dimensions Nombre de valeurs dans le vecteur (plus = mieux mais plus lourd)
Similarité Distance entre vecteurs = similarité sémantique
Mean pooling Moyenne simple (sous-optimal)
Modèle natif Entraîné spécifiquement pour produire de bons embeddings

# Prochaines étapes

Pour améliorer mgrep :

  1. Comprendre les embeddings (ce document)
  2. → Tester des modèles natifs (Jina Code recommandé)
  3. → Comparer les résultats quantitativement