0Pricing
AI Prompt Engineering · Leçon

Sélection dynamique de quelques exemples

Récupérer des exemples pour chaque requête.

Sélection dynamique de quelques exemples est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.

Des exemples statiques aux exemples dynamiques

L’approche statique à quelques exemples utilise les mêmes exemples pour chaque requête. L’apprentissage dynamique à quelques exemples récupère, pour chaque requête, les exemples les plus pertinents dans un ensemble et conditionne le modèle avec des exemples qui ressemblent à l’input actuel.

Il s’agit d’un apprentissage en contexte augmenté par récupération : la pertinence des exemples augmente, ce qui constitue l’un des leviers les plus puissants pour améliorer la qualité de l’ICL, en particulier sur un trafic hétérogène.

class DynamicSelector:
    def __init__(self, pool, embedder, index):
        self.pool = pool          # candidate demonstrations
        self.embed = embedder
        self.index = index        # ANN index over pool embeddings
    def select(self, query, k):
        q = self.embed(query)
        ids = self.index.search(q, k)
        return [self.pool[i] for i in ids]

Vectorisation de l’ensemble d’exemples

Calculez à l’avance les représentations vectorielles de chaque exemple candidat et stockez-les dans un index de recherche des plus proches voisins approximatifs (FAISS, HNSW ou une base de données vectorielle). Au moment de la requête, appliquez embed une seule fois à l’input et récupérez les meilleures correspondances.

Choisissez un modèle de vectorisation adapté à la sémantique de votre tâche ; un modèle générique peut regrouper les éléments selon des caractéristiques de surface plutôt que selon la dimension qui prédit l’étiquette correcte.

import numpy as np

def build_index(pool, embed):
    vecs = np.stack([embed(d.input) for d in pool]).astype('float32')
    vecs /= np.linalg.norm(vecs, axis=1, keepdims=True)  # cosine via dot
    index = HNSW(dim=vecs.shape[1])
    index.add(vecs)
    return index

Invites kNN

La method canonique (Liu et al., 2022) récupère les k plus proches voisins de la requête dans l’ensemble annoté et les utilise comme exemples. La sélection fondée sur la récupération dépasse systématiquement la sélection aléatoire, car les exemples pertinents permettent de mieux cerner la tâche et fournissent le bon espace d’étiquettes.

Les étiquettes récupérées jouent également le rôle d’un a priori souple de classifieur kNN, qui oriente le modèle vers les réponses des voisins.

def knn_prompt(query, selector, k, build):
    demos = selector.select(query, k)
    demos = order_by_similarity(embed(query), demos)  # most similar last
    return build(demos, query)

Récupération tenant compte de la diversité

Une simple sélection des k premiers résultats peut renvoyer des quasi-doublons et gaspiller le contexte. Appliquez MMR ou un regroupement aux candidats récupérés afin de préserver la pertinence tout en veillant à ce que les exemples choisis couvrent des facettes distinctes de la requête.

C’est particulièrement important pour les entrées compositionnelles, dont les différents sous-aspects ont chacun besoin d’un exemple représentatif.

def diverse_retrieve(query, selector, k, pool_n=30, lam=0.7):
    cand = selector.select(query, pool_n)
    q = embed(query)
    return mmr_against_query(cand, q, k, lam)  # relevance + diversity

Latence et budget de récupération

La sélection dynamique ajoute un appel de vectorisation et une recherche dans un index ANN à chaque requête. Prévoyez ce coût : mettez en cache les représentations vectorielles des requêtes répétées, effectuez les recherches par lots et conservez l’index en mémoire.

Pour les systèmes à fort débit, l’étape de récupération doit prendre moins d’une milliseconde ; sinon, le gain de pertinence est annulé par l’augmentation de la latence de fin de traitement.

from functools import lru_cache

@lru_cache(maxsize=50_000)
def cached_embed(text):
    return embed(text)
# Plus: warm in-RAM HNSW, batched search, async prefetch

Conflit entre mise en cache et exemples dynamiques

Les exemples dynamiques empêchent la mise en cache du préfixe de l’invite, car le bloc d’exemples change à chaque requête. Limitez ce problème en conservant un préambule stable mis en cache (instructions et quelques exemples universels), puis en ajoutant uniquement les exemples récupérés et spécifiques à la requête après celui-ci.

Vous récupérez ainsi la majeure partie des économies liées à la mise en cache tout en préservant la pertinence de la fin pour chaque requête.

prompt = (
    STATIC_PREAMBLE          # cached: instructions + anchor demos
    + render(diverse_retrieve(query, selector, k))  # dynamic tail
    + format_query(query)
)

Éviter les fuites entre entraînement et évaluation

Si la requête elle-même se trouve dans l’ensemble (ce qui est fréquent lors de l’évaluation), la récupération peut renvoyer la réponse exacte et gonfler les métriques. Lors de l’évaluation, excluez toujours la requête ainsi que les voisins presque identiques dont la similarité dépasse un seuil.

En production, dédupliquez l’ensemble et empêchez qu’une entrée input antérieure de l’utilisateur lui soit renvoyée comme exemple.

def leak_safe_select(query, selector, k, sim_cap=0.97):
    cand = selector.select(query, k + 5)
    q = embed(query)
    cand = [d for d in cand if cos(q, d.emb) < sim_cap]
    return cand[:k]

Démarrage à froid et croissance de l’ensemble

Au début, l’ensemble est réduit et la récupération peut renvoyer de faibles correspondances. Initialisez-le avec un ensemble statique sélectionné, puis faites croître l’ensemble à partir de traces de production vérifiées, en recalculant les représentations vectorielles et en réindexant selon un calendrier défini.

Suivez l’utilisation et le résultat de chaque exemple afin de pouvoir supprimer les exemples peu utiles ou obsolètes et conserver un index compact.

def maybe_add_to_pool(trace, verified):
    if verified and novelty(trace, index) > THRESH:
        emb = embed(trace.input)
        index.add(emb)
        pool.append(Demo(trace.input, trace.output, trace.meta))

Une sélection au-delà de la similarité

La pertinence des plus proches voisins constitue un bon choix par défaut, mais elle n’est pas toujours optimale. Les sélecteurs avancés pondèrent l’valeur informative (l’exemple lève-t-il l’ambiguïté de la requête ?), la diversité et la couverture des étiquettes. Certaines méthodes apprennent une stratégie de sélection qui maximise l’exactitude finale plutôt que la similarité brute.

Considérez la sélection comme le choix de l’ensemble d’exemples qui réduit le plus l’incertitude du modèle sur cette requête.

def select_by_uncertainty_reduction(query, pool, k):
    base = entropy(model_probs(build([], query)))
    gains = []
    for d in pool:
        h = entropy(model_probs(build([d], query)))
        gains.append((d, base - h))   # info gain per demo
    return [d for d, _ in sorted(gains, key=lambda x: -x[1])[:k]]

Évaluer une chaîne de traitement dynamique

Comparez le système dynamique à des références statiques et aléatoires sur des données mises de côté et contrôlées contre les fuites. Indiquez l’exactitude, la distribution des similarités de récupération, la latence de bout en bout et le taux d’utilisation du cache.

Un système dynamique qui gagne en exactitude mais dégrade fortement la réutilisation du cache peut avoir un bilan négatif en matière de coût ; évaluez l’objectif global, pas uniquement la qualité.

def eval_pipeline(eval_set):
    return {
        'acc_dynamic': run(dynamic, eval_set),
        'acc_static':  run(static, eval_set),
        'acc_random':  run(random_sel, eval_set),
        'p95_latency': latency_p95(),
        'cache_hit':   cache_hit_rate(),
    }

Architecture de référence

De bout en bout : un ensemble d’exemples vérifiés, un modèle de vectorisation, un index ANN en mémoire, un sélecteur qui applique des protections contre les fuites, la diversité et le classement par similarité, un préambule stable mis en cache, ainsi qu’une boucle de rétroaction qui fait croître et réduit l’ensemble.

Cette architecture transforme les invites à quelques exemples en système de récupération, avec la rigueur opérationnelle que cela implique.

def answer(query):
    demos = leak_safe_select(query, selector, k=4)
    demos = mmr_against_query(demos, embed(query), 4)
    demos = order_by_similarity(embed(query), demos)
    prompt = STATIC_PREAMBLE + render(demos) + format_query(query)
    out = llm(prompt)
    log_for_pool_growth(query, out)
    return out

Vérification rapide

Diagnostiquez un résultat d’évaluation trompeusement élevé.

Récapitulatif

Points essentiels :

  • L’apprentissage dynamique à quelques exemples récupère des exemples pour chaque requête et dépasse les approches aléatoires ou statiques en augmentant la pertinence.
  • Vectorisez l’ensemble dans un index ANN ; les invites kNN constituent un bon choix par défaut, classé par similarité croissante.
  • Ajoutez de la diversité (MMR) et envisagez des sélecteurs fondés sur la valeur informative ou la réduction de l’incertitude.
  • Protégez-vous contre les fuites de récupération, maîtrisez la latence et conservez un préambule statique mis en cache avec une fin dynamique.
  • Faites croître et réduisez l’ensemble à partir de traces vérifiées ; évaluez conjointement l’exactitude, la latence et l’utilisation du cache.

Questions Fréquemment Posées

La leçon « Sélection dynamique de quelques exemples » est-elle gratuite ?

Oui — le texte complet de « Sélection dynamique de quelques exemples » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Sélection dynamique de quelques exemples » ?

Récupérer des exemples pour chaque requête. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?

Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Sélection dynamique de quelques exemples » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?

Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Zéro, un ou quelques exemples
  2. Concevoir des exemples efficaces
  3. Ordre et récence des exemples
  4. Sélection dynamique de quelques exemples
← Retour à AI Prompt Engineering