Lección 2 — Comprendre les embeddings

gemini-embedding-2 : préfixes de tâche, dimensions et pièges

5 min de lectura

Este contenido aún no está traducido. Se muestra la versión original.

gemini-embedding-2 : préfixes de tâche, dimensions et pièges

Les « task types » version gemini-embedding-2

Un même texte n'a pas le même embedding idéal selon l'usage : pour une recherche, la question courte doit tomber près du document long qui y répond ; pour un clustering, on veut regrouper des textes de même nature. Avec l'ancien modèle gemini-embedding-001, on le précisait avec le paramètre task_type (RETRIEVAL_QUERY, RETRIEVAL_DOCUMENT, CLUSTERING…).

Avec gemini-embedding-2, ce paramètre ne s'utilise pas : la documentation demande d'écrire la tâche dans le texte lui-même, avec un préfixe.

UsageFormat de la requêteFormat du document
Recherche (asymétrique)task: search result | query: {texte}title: {titre} | text: {contenu} (title: none sans titre)
Question-réponsetask: question answering | query: {texte}title: {titre} | text: {contenu}
Clustering (symétrique)task: clustering | query: {texte}même format
Similarité de phrasestask: sentence similarity | query: {texte}même format (pas pour la recherche)
Classificationtask: classification | query: {texte}même format

Asymétrique : la requête et le document ont des formats différents (une question courte contre une fiche). Symétrique : tous les textes ont le même rôle.

files/moteur.py (extrait)
def texte_document(p: dict) -> str:
    return f"title: {p['nom']} | text: {p['categorie']}. {p['description']}"


def texte_requete(q: str) -> str:
    return f"task: search result | query: {q}"


def texte_symetrique(p: dict, tache: str) -> str:
    """Pour le clustering ou la similarité : même format des deux côtés."""
    return f"task: {tache} | query: {p['nom']}. {p['description']}"

Le piège de l'agrégation

flowchart LR
  A["contents = ['texte 1', 'texte 2', 'texte 3']"] --> B["1 seul vecteur agrégé"]
  C["contents = [Content(texte 1), Content(texte 2), Content(texte 3)]"] --> D["3 vecteurs, un par texte"]

Avec gemini-embedding-2, une liste de chaînes est vue comme un seul contenu en plusieurs morceaux : vous recevez un vecteur unique qui résume le tout. Pour obtenir un vecteur par texte, on envoie une liste d'objets Content, un par texte :

files/moteur.py (extrait)
# Une Content par texte : une liste de str donnerait UN seul vecteur agrégé.
contents = [types.Content(parts=[types.Part(text=t)]) for t in textes[i:i + lot]]
r = client.models.embed_content(
    model=EMBED_MODEL, contents=contents,
    config=types.EmbedContentConfig(output_dimensionality=dim))

Sur Vertex AI, l'appel avec plusieurs Content est refusé pour ce modèle (« only supports one content at a time ») : le lab passe alors à un texte par requête.

Choisir la dimension

Par défaut, le modèle renvoie 3072 nombres. output_dimensionality permet d'en demander moins (768 et 1536 sont recommandés par la documentation). C'est possible grâce à l'apprentissage Matryoshka (comme les poupées russes) : les premières valeurs du vecteur portent déjà l'essentiel du sens. gemini-embedding-2 renormalise automatiquement les vecteurs réduits.

DimensionTaille pour 1 million de fiches (float32)Usage
3072environ 12 Goqualité maximale
768environ 3 Gobon compromis (choix du lab)
256environ 1 Gogros volumes, qualité un peu moindre

Le calcul : 1 000 000 × dimension × 4 octets.

Vous appelez embed_content(model="gemini-embedding-2", contents=["a", "b", "c"]). Combien de vecteurs recevez-vous ?

Comment indiquer à gemini-embedding-2 que le texte est une requête de recherche ?

Exercice : préparer une FAQ

Vous indexez une FAQ RH (question + réponse) pour un moteur de question-réponse. Écrivez les deux fonctions de formatage, pour la requête de l'employé et pour chaque entrée de la FAQ.

Voir la solution
def texte_requete_qa(question: str) -> str:
    return f"task: question answering | query: {question}"

def texte_faq(entree: dict) -> str:
    return f"title: {entree['question']} | text: {entree['reponse']}"

La question de la FAQ fait un excellent title : elle résume le document. La requête utilise la tâche question answering plutôt que search result, puisqu'on cherche une réponse.

Résultat obtenu

Vérifications exécutées le 2026-10-15 avec la clé d'API Gemini :

# démo de la leçon 1 : liste de chaînes
liste de str -> 1 vecteur(s)
# même appel avec deux objets Content
content list -> 2
# un texte : dimension et norme par défaut, puis avec output_dimensionality=768
3072 0.9999999373014921 768 0.9999997619101519
# cosinus entre la troncature locale (3072 -> 768, renormalisée) et le vecteur 768 natif
cos trunc vs 768 0.9999997619101513

Et sur Vertex AI, gemini-embedding-2 répondait en global mais pas en europe-west1 (404 « Publisher model … not found ») : la région compte.

Je sais faire

  • Formater requêtes et documents avec les préfixes de tâche de gemini-embedding-2
  • Envoyer une Content par texte pour obtenir un vecteur par texte
  • Choisir output_dimensionality en fonction du volume
  • Tronquer et renormaliser un vecteur localement
Siguiente