AI Prompt Engineering · Lezione

Selezione dinamica few-shot

Recuperare esempi per ogni query.

Lezione 4 di 413 passaggi

Selezione dinamica few-shot è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.

Dagli esempi statici agli esempi dinamici

Il few-shot statico utilizza gli stessi esempi per ogni query. Il few-shot dinamico recupera gli esempi più rilevanti per ogni query da un insieme, condizionando il modello su esempi simili all'input corrente.

Si tratta di in-context learning con retrieval: aumenta la rilevanza degli esempi, una delle leve più efficaci per la qualità dell'ICL, soprattutto in presenza di traffico eterogeneo.

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]

Generare gli embedding dell'insieme di esempi

Precalcoli gli embedding per ogni esempio candidato e li memorizzi in un indice approximate nearest neighbor (FAISS, HNSW o un vector DB). Al momento della query, generi l'embedding dell'input una sola volta e recuperi le corrispondenze migliori.

Scelga un modello di embedding coerente con la semantica del task; un embedder generico potrebbe raggruppare gli elementi in base a caratteristiche superficiali invece che alla dimensione che predice l'etichetta corretta.

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

Prompting kNN

Il metodo canonico (Liu et al., 2022) recupera i k vicini più prossimi alla query dall'insieme etichettato e li utilizza come esempi. La selezione basata sul retrieval supera sistematicamente quella casuale, perché gli esempi rilevanti identificano meglio il task e forniscono il corretto spazio delle etichette.

Le etichette recuperate fungono inoltre da prior morbido del classificatore kNN, orientando il modello verso le risposte dei vicini.

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)

Retrieval diversificato

Il puro top-k può restituire quasi duplicati, sprecando contesto. Applichi MMR o il clustering sui candidati recuperati per mantenere la rilevanza e garantire al contempo che gli esempi scelti coprano aspetti distinti della query.

Questo è particolarmente importante per gli input composizionali, nei quali ciascun sottoaspetto richiede un esempio rappresentativo.

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

Latenza e budget del retrieval

La selezione dinamica aggiunge una chiamata per gli embedding e una ricerca ANN a ogni richiesta. Pianifichi queste risorse: memorizzi nella cache gli embedding delle query ripetute, raggruppi le operazioni di retrieval e mantenga l'indice in memoria.

Per i sistemi ad alto QPS, il passaggio di retrieval deve richiedere meno di un millisecondo; altrimenti il guadagno in termini di rilevanza viene annullato dall'aumento della latenza di coda.

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

Conflitto tra caching ed esempi dinamici

Gli esempi dinamici interrompono il prompt-prefix caching, perché il blocco degli esempi cambia a ogni query. Mitighi il problema mantenendo un preambolo stabile memorizzato nella cache (istruzioni più alcuni esempi universali) e aggiungendo dopo di esso solo gli esempi recuperati e specifici per la query.

In questo modo recupera gran parte dei risparmi del caching, preservando al contempo la rilevanza per la query nella coda.

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

Evitare il leakage tra training e test

Se la query stessa si trova nell'insieme (caso comune durante la valutazione), il retrieval può restituire la risposta esatta, gonfiando le metriche. Durante la valutazione, escluda la query e i vicini quasi identici con similarità superiore a una soglia.

In produzione, deduplicare l'insieme e impedisca che un input precedente dello stesso utente venga riproposto come esempio.

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]

Cold start e crescita dell'insieme

All'inizio l'insieme è ridotto e il retrieval potrebbe restituire corrispondenze deboli. Avvii il sistema con un set statico curato, quindi faccia crescere l'insieme utilizzando tracce di produzione verificate, ricalcolando gli embedding e ricostruendo l'indice secondo una pianificazione.

Monitori l'utilizzo e l'esito di ogni esempio, così da poter eliminare quelli di scarso valore o obsoleti e mantenere snello l'indice.

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))

Selezione oltre la similarità

La rilevanza dei nearest neighbor è una buona impostazione predefinita, ma non sempre è ottimale. I selettori avanzati considerano l'informatività (l'esempio risolve l'ambiguità della query?), la diversità e la copertura delle etichette. Alcuni metodi apprendono una policy di selezione che massimizza l'accuratezza a valle invece della similarità grezza.

Consideri la selezione come la scelta dell'insieme di esempi che riduce maggiormente l'incertezza del modello su questa query.

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]]

Valutare una pipeline dinamica

Confronti il sistema dinamico con baseline statiche e casuali su dati tenuti da parte e con leakage controllato. Riporti l'accuratezza, la distribuzione delle similarità del retrieval, la latenza end-to-end e il tasso di riscontri nella cache.

Un sistema dinamico che migliora l'accuratezza ma compromette il riutilizzo della cache può avere un impatto negativo sui costi; valuti l'obiettivo complessivo, non solo 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(),
    }

Architettura di riferimento

End-to-end: un insieme verificato di esempi, un modello di embedding, un indice ANN in memoria, un selettore che applica protezioni contro il leakage, diversità e ordinamento per similarità, un preambolo stabile memorizzato nella cache e un ciclo di feedback che fa crescere e riduce l'insieme.

Questa architettura trasforma il prompting few-shot in un sistema di retrieval dotato della disciplina operativa che ne deriva.

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

Verifica rapida

Individui la causa di un risultato di valutazione ingannevolmente elevato.

Riepilogo

Concetti chiave:

  • Il few-shot dinamico recupera esempi per ogni query e supera gli approcci casuali o statici aumentando la rilevanza.
  • Generi gli embedding dell'insieme in un indice ANN; il prompting kNN è l'impostazione predefinita più solida, con ordinamento per similarità crescente.
  • Aggiunga diversità (MMR) e consideri selettori basati sull'informatività o sulla riduzione dell'incertezza.
  • Prevenga il leakage nel retrieval, gestisca la latenza e mantenga un preambolo statico memorizzato nella cache con una coda dinamica.
  • Faccia crescere e riduca l'insieme a partire da tracce verificate; valuti insieme accuratezza, latenza e tasso di riscontri nella cache.
Gratis per iniziare

Impara AI Prompt Engineering con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
53
Lezioni
199

Domande Frequenti

La lezione «Selezione dinamica few-shot» è gratuita?

Sì — il testo completo di «Selezione dinamica few-shot» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.

Cosa imparerò in «Selezione dinamica few-shot»?

Recuperare esempi per ogni query. Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Prompt Engineering?

Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Selezione dinamica few-shot»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?

Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Zero-shot, one-shot e few-shot
  2. Progettare esempi efficaci
  3. Ordine e attualità degli esempi
  4. Selezione dinamica few-shot
← Torna a AI Prompt Engineering