AI Prompt Engineering · Урок

Динамический выбор примеров для малообразцового режима

Получение примеров для каждого запроса

Урок 4 из 413 шагов

«Динамический выбор примеров для малообразцового режима» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.

От статических к динамическим демонстрациям

При статическом обучении по нескольким примерам для каждого запроса используются одни и те же примеры. Динамическое обучение по нескольким примерам извлекает из пула наиболее релевантные демонстрации для каждого запроса, подбирая для модели примеры, похожие на текущие входные данные.

Это обучение в контексте с дополнением извлечёнными данными: оно повышает релевантность демонстраций, что является одним из самых сильных факторов качества ICL, особенно при неоднородном потоке запросов.

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]

Построение векторных представлений пула демонстраций

Заранее постройте векторные представления для каждой демонстрации-кандидата и сохраните их в индексе приближённого поиска ближайших соседей (FAISS, HNSW или векторная база данных). Во время обработки запроса один раз примените embed к входным данным и извлеките наиболее близкие совпадения.

Выбирайте модель построения векторных представлений, соответствующую смыслу Вашей задачи: универсальная модель может группировать данные по поверхностным признакам, а не по измерению, которое позволяет предсказать правильную метку.

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

Формирование промптов с помощью kNN

Канонический метод (Liu и др., 2022) извлекает из размеченного пула k ближайших соседей запроса и использует их как демонстрации. Выбор на основе извлечения стабильно превосходит случайный выбор, поскольку релевантные демонстрации лучше задают задачу и предоставляют правильное пространство меток.

Извлечённые метки также выступают как априорный сигнал мягкого классификатора kNN, склоняя модель к ответам соседей.

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)

Извлечение с учётом разнообразия

Простой выбор top-k может вернуть почти дублирующиеся примеры, напрасно расходуя контекст. Применяйте MMR или кластеризацию к извлечённым кандидатам, чтобы сохранить релевантность и одновременно обеспечить охват выбранными демонстрациями разных аспектов запроса.

Это особенно важно для составных входных данных, где для каждого отдельного аспекта нужен свой показательный пример.

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

Задержка и бюджет извлечения

Динамический выбор добавляет вызов для построения векторного представления и поиск в индексе ANN к каждому запросу. Учитывайте это в бюджете: кэшируйте векторные представления повторяющихся запросов, выполняйте извлечение пакетами и храните индекс в памяти.

В системах с высоким QPS этап извлечения должен занимать менее миллисекунды; иначе выигрыш в релевантности будет поглощён увеличением хвостовой задержки.

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

Противоречие между кэшированием и динамическими демонстрациями

Динамические демонстрации нарушают кэширование префикса промпта, поскольку блок примеров меняется для каждого запроса. Уменьшить этот эффект можно с помощью стабильного кэшируемого пролога (инструкций и нескольких универсальных примеров), добавляя после него только извлечённые демонстрации, зависящие от запроса.

Так сохраняется большая часть экономии от кэширования, а хвост по-прежнему остаётся релевантным для каждого запроса.

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

Предотвращение утечки между обучением и тестированием

Если сам запрос находится в пуле, что часто бывает во время оценки, извлечение может вернуть точный ответ и завысить метрики. Во время оценки всегда исключайте запрос и почти идентичные соседние элементы, превышающие порог сходства.

В рабочей среде удаляйте дубликаты из пула и не допускайте возврата пользователю его собственного предыдущего ввода в качестве демонстрации.

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]

Холодный старт и расширение пула

Вначале пул невелик, поэтому извлечение может возвращать слабые совпадения. Начните с отобранного статического набора, а затем расширяйте пул проверенными рабочими примерами, периодически заново создавая векторные представления и перестраивая индекс.

Отслеживайте использование и результат для каждой демонстрации, чтобы удалять малоценные или устаревшие примеры и поддерживать компактность индекса.

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

Выбор не только по сходству

Релевантность ближайших соседей — хорошая настройка по умолчанию, но не всегда оптимальная. Продвинутые методы выбора учитывают информативность (устраняет ли демонстрация неоднозначность запроса?), разнообразие и охват меток. Некоторые методы обучают стратегию выбора, которая максимизирует итоговую точность, а не только исходное сходство.

Рассматривайте выбор как подбор набора демонстраций, который сильнее всего уменьшает неопределённость модели для данного запроса.

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

Оценка динамического конвейера

Сравнивайте динамический вариант со статическими и случайными базовыми вариантами на отложенных данных с контролем утечек. Отчитывайтесь о точности, распределении сходства извлечённых элементов, сквозной задержке и доле обращений к кэшу.

Динамическая система, которая выигрывает по точности, но резко снижает повторное использование кэша, может в итоге повысить стоимость; оценивайте всю целевую функцию, а не только качество.

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(),
    }

Эталонная архитектура

Сквозной процесс включает проверенный пул демонстраций, модель построения векторных представлений, хранящийся в памяти индекс ANN, модуль выбора с защитой от утечек, обеспечением разнообразия и упорядочиванием по сходству, стабильный кэшируемый пролог и цикл обратной связи, который расширяет и сокращает пул.

Такая архитектура превращает обучение по нескольким примерам в систему извлечения с соответствующей операционной дисциплиной.

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

Быстрая проверка

Определите причину подозрительно высокого результата оценки.

Итоги

Основные выводы:

  • Динамическое обучение по нескольким примерам извлекает демонстрации для каждого запроса и превосходит случайный и статический подходы благодаря повышению релевантности.
  • Создавайте векторные представления пула в индексе ANN; формирование промптов с помощью kNN — хорошая настройка по умолчанию, при этом примеры следует упорядочивать по возрастающему сходству.
  • Добавляйте разнообразие с помощью MMR и учитывайте методы выбора по информативности и снижению неопределённости.
  • Защищайтесь от утечек при извлечении, контролируйте задержку и сохраняйте статический кэшируемый пролог с динамическим хвостом.
  • Расширяйте и сокращайте пул на основе проверенных рабочих примеров; оценивайте точность, задержку и долю обращений к кэшу вместе.
Можно начать бесплатно

Изучай AI Prompt Engineering с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
53
Уроки
199

Часто задаваемые вопросы

Урок «Динамический выбор примеров для малообразцового режима» бесплатный?

Да — полный текст урока «Динамический выбор примеров для малообразцового режима» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.

Чему я научусь в уроке «Динамический выбор примеров для малообразцового режима»?

Получение примеров для каждого запроса Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Prompt Engineering?

Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Динамический выбор примеров для малообразцового режима»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Prompt Engineering?

Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Нулевой, одно- и малообразцовый режим
  2. Проектирование эффективных примеров
  3. Порядок примеров и их актуальность
  4. Динамический выбор примеров для малообразцового режима
← Назад к AI Prompt Engineering