动态少样本选择
针对每个查询检索示例。
动态少样本选择 是 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 indexkNN 提示
经典方法(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 反馈 — 无需本地设置。
此课程中的所有课时
- 零样本、单样本与少样本
- 设计有效示例
- 示例顺序与时效性
- 动态少样本选择