纲要

  • 动态示例选择进阶:从长度到语义
  • 核心概念
    • SemanticSimilarityExampleSelector:基于语义相似度从示例池中选择与输入最相关的示例
    • 向量嵌入(Embedding)与向量数据库(如 Chroma
    • 余弦相似度:衡量向量空间距离的常用算法
  • 关键流程:准备示例 → 定义嵌入模型和向量数据库 → 创建选择器 → 组合 Few Shot 提示词模板 → 调用 LLM
  • 涉及组件:langchain_core.example_selectorslangchain_community.embeddingslangchain_community.vectorstores
  • 代码演示:完整可运行的 Python 脚本,使用 FakeEmbeddings 模拟嵌入过程,无需外部 API Key

引言

在上一篇文章中,我们介绍了根据长度动态截取示例的 LengthBasedExampleSelector,它虽然能够控制上下文窗口的大小,但选择逻辑过于机械:只是从列表头部开始依次添加示例,完全不考虑示例与当前输入的相关性。如果示例池里混杂了中文和英文、天气和情绪等多种场景,长度选择器很可能给出与当前任务毫不相干的例子。

LangChain 提供了另一种更智能的选择器——SemanticSimilarityExampleSelector,它利用文本嵌入技术,将输入和示例都映射到向量空间,然后通过计算余弦相似度,从示例池中选出语义最接近的 Top-K 个示例。这种方式可以轻松实现跨语言、跨领域的精准匹配,让 Few Shot 提示真正“看懂”输入的内容。

工作原理

其本质是检索增强生成(RAG)在提示词构建阶段的应用,整体流程如下:

示例池

向量化并存入Chroma

用户输入

向量化

在Chroma中做相似度搜索

返回Top-K最相似示例

组合进Few Shot提示词模板

  • 向量化:使用嵌入模型(Embedding Model)将文本转换为高维向量。
  • 存储:将示例向量存入向量数据库(本文使用轻量级的 Chroma)。
  • 查询:将用户输入也向量化,通过余弦相似度计算与各示例向量的距离,返回距离最近(即语义最相似)的 K 个示例。

完整可运行代码

为了让你无需任何外部 API Key 即可运行,本示例使用 FakeEmbeddings 模拟向量嵌入。实际项目中只需替换为真实的嵌入模型(如 OpenAI 或 HuggingFace 模型),代码结构完全一致。

首先安装依赖:

pip install langchain langchain-core langchain-community chromadb

核心代码:

from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_community.embeddings.fake import FakeEmbeddings
from langchain_community.vectorstores import Chroma

# 1. 准备示例池(反义词任务)
examples = [
    {"input": "happy", "output": "sad"},
    {"input": "高兴", "output": "悲伤"},
    {"input": "sunny", "output": "gloomy"},
    {"input": "晴朗", "output": "阴沉"},
    {"input": "big", "output": "small"},
]

# 2. 定义示例格式化模板
example_prompt = PromptTemplate(
    input_variables=["input", "output"],
    template="原词: {input}\n反义词: {output}"
)

# 3. 创建语义相似度示例选择器
#    使用 FakeEmbeddings 模拟嵌入,size 参数指定向量维度
embedding_model = FakeEmbeddings(size=128)

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples=examples,
    embeddings=embedding_model,
    vectorstore_cls=Chroma,      # 使用 Chroma 作为向量数据库
    k=1,                         # 每次选择最相似的 1 个示例
)

# 4. 构建动态 Few Shot 提示词模板
dynamic_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个输入词的反义词:",
    suffix="原词: {input}\n反义词:",
    input_variables=["input"],
)

# 5. 测试:输入英文情绪词,期望选中情绪相关示例
print("=== 输入: worried ===")
print(dynamic_prompt.format(input="worried"))
print()

# 6. 测试:输入中文天气词,期望选中天气相关示例
print("=== 输入: 晴朗 ===")
print(dynamic_prompt.format(input="晴朗"))

运行后可以看到,worried 会匹配到情绪相关的示例(如 happy/sad),晴朗 则匹配到天气相关的示例(如 sunny/gloomy晴朗/阴沉)。注意 FakeEmbeddings 使用随机向量,因此结果可能略有随机性;若换成真实嵌入模型,匹配会非常精准。

与长度选择器的对比

特性 长度选择器 (LengthBasedExampleSelector) 语义选择器 (SemanticSimilarityExampleSelector)
选择依据 示例字符数 + 顺序 输入与示例的语义相似度
能否跨语言 不支持 支持(嵌入模型通常跨语言)
计算开销 极低 较高(需向量化和相似度搜索)
适用场景 示例少且顺序重要 示例多、任务多变、要求高相关性

使用建议

  • 嵌入模型选型:对中文任务推荐使用 text-embedding-ada-002(OpenAI)或开源的 BAAI/bge-large-zh,它们对中英文混合场景支持良好。
  • Top-K 设置k 值一般设为 1~3,过多示例可能引入噪声。可根据实际效果调整。
  • 向量数据库:Chroma 适合原型开发和小规模数据;生产环境可考虑 FAISS、Pinecone、Milvus 等。
  • 示例池维护:定期更新示例池并重新生成向量,以保持与最新任务的语义一致性。

总结

SemanticSimilarityExampleSelector 将检索增强生成(RAG)的向量检索思路应用于提示词工程,让 Few Shot 示例的选择从“机械截断”进化为“智能检索”。

它充分利用了嵌入模型捕捉语义的能力,无论输入是中文还是英文,都能从庞大的示例池中精准捞出最有参考价值的样例,大幅提升 Few Shot 的命中率和回答质量。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐