0Pricing
AI Prompt Engineering · 课时

动态少样本选择

针对每个查询检索示例。

动态少样本选择 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 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)

考虑多样性的检索

纯粹选择前 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]]

评估动态 pipeline

在控制泄漏的留出数据上,将动态方案与静态方案和随机基线进行比较。请报告准确率、检索相似度的分布、端到端延迟以及缓存命中率。

动态系统即使在准确率上胜出,但如果缓存复用率大幅下降,也可能在成本上得不偿失;请评估完整目标,而不只是质量。

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 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「动态少样本选择」这节课中我会学到什么?

针对每个查询检索示例。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「动态少样本选择」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 零样本、单样本与少样本
  2. 设计有效示例
  3. 示例顺序与时效性
  4. 动态少样本选择
← 返回 AI Prompt Engineering