纲要
- 动态示例选择进阶:从长度约束到语义匹配
- 核心组件
SemanticSimilarityExampleSelector:基于向量相似度从示例池中选择与当前输入最相关的示例- 嵌入模型(Embedding Model):将文本映射为高维向量,常见实现包括
FakeEmbeddings、OpenAIEmbeddings、HuggingFaceEmbeddings - 向量数据库(VectorStore):存储并检索嵌入向量,本文使用
Chroma,生产环境可选FAISS、Pinecone、Milvus - 相似度度量:余弦相似度(Cosine Similarity),用于衡量向量空间中的距离
- 核心流程
- 准备示例池 → 定义嵌入模型 → 初始化向量数据库并写入示例向量 → 创建
SemanticSimilarityExampleSelector→ 组合FewShotPromptTemplate→ 调用大语言模型
- 准备示例池 → 定义嵌入模型 → 初始化向量数据库并写入示例向量 → 创建
- 涉及库与模块
langchain_core.example_selectorslangchain_core.promptslangchain_community.embeddings.fakelangchain_community.vectorstores
- 代码演示
- 完整可运行的 Python 脚本,使用
FakeEmbeddings模拟嵌入过程,无需外部 API Key - 展示跨语言(中/英)场景下,示例选择器如何根据输入语义动态匹配最相关的示例
- 完整可运行的 Python 脚本,使用
引言
在 Few Shot 提示词工程中,示例的选择策略直接影响 LLM 的推理质量。上一阶段介绍的 LengthBasedExampleSelector 通过控制示例总长度来适配上下文窗口限制,但其选择逻辑本质上是从示例列表头部开始顺序截取,既不感知示例与当前输入的内在关联,也无法应对示例池中主题分散、语言混杂的场景。
LangChain 提供的 SemanticSimilarityExampleSelector 将检索增强生成(RAG)的向量检索思路引入提示词构建阶段。该选择器首先将示例池中的每个样本通过嵌入模型转化为高维向量并存入向量数据库,当新输入到达时,将其同样向量化,并通过余弦相似度计算与所有示例向量的距离,最终返回语义最相似的 Top-K 个示例。该机制使得 Few Shot 示例的选择真正实现了“按需匹配”,无论是在跨语言情境还是多任务混合场景下,均能显著提升示例的参考价值。
核心组件与工作原理
工作流程
SemanticSimilarityExampleSelector 的完整工作流程可以拆解为离线索引构建与在线检索两个阶段:
- 索引构建阶段:遍历示例池,调用嵌入模型将每个示例的输入字段(或完整文本)转换为向量,并将向量与原始示例数据一并存入向量数据库。
- 在线检索阶段:接收用户输入,使用同一嵌入模型将其向量化,然后在向量数据库中执行相似度搜索(通常基于余弦相似度),返回距离最近的 K 个示例。
以下 Mermaid 流程图展示了整个数据流转过程:
关键组件说明
| 组件 | 作用 | 本示例中的实现 |
|---|---|---|
| 嵌入模型 | 将文本映射为稠密向量,捕捉语义信息 | FakeEmbeddings(随机向量,用于演示) |
| 向量数据库 | 存储示例向量并支持相似度检索 | Chroma(轻量级,基于本地文件) |
| 示例选择器 | 封装检索逻辑,接收输入返回最相似示例 | SemanticSimilarityExampleSelector |
| 提示词模板 | 组合前缀、动态示例和后缀,生成最终提示 | FewShotPromptTemplate |
完整代码实现
本示例使用 FakeEmbeddings 模拟嵌入过程,无需配置任何外部 API Key,即可在本地完整运行。实际生产环境中,可替换为 OpenAIEmbeddings 或 HuggingFaceEmbeddings,代码结构无需调整。
环境准备
安装所需依赖:
pip install langchain langchain-core langchain-community chromadb
代码结构
├── main.py # 核心脚本
└── chroma_store/ # Chroma 本地持久化目录(自动生成)
核心脚本
以下为完整可运行的 Python 代码:
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,需指定向量维度)
embedding_model = FakeEmbeddings(size=128)
# 4. 从示例池创建语义相似度示例选择器
# from_examples 方法会自动完成:向量化 → 存入 Chroma → 返回选择器实例
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples=examples,
embeddings=embedding_model,
vectorstore_cls=Chroma, # 传入向量数据库类,内部自动实例化
k=1, # 每次检索返回最相似的 1 个示例
)
# 5. 构建动态 Few Shot 提示词模板
dynamic_prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix="给出每个输入词的反义词:",
suffix="原词: {input}\n反义词:",
input_variables=["input"],
)
# 6. 测试:英文情绪词 → 期望匹配 happy/sad
print("=== 输入: worried ===")
print(dynamic_prompt.format(input="worried"))
print()
# 7. 测试:中文天气词 → 期望匹配 晴朗/阴沉 或 sunny/gloomy
print("=== 输入: 晴朗 ===")
print(dynamic_prompt.format(input="晴朗"))
代码说明
SemanticSimilarityExampleSelector.from_examples:类方法,内部依次执行示例向量化、写入向量数据库(默认使用余弦相似度),并返回配置完成的选择器实例。vectorstore_cls参数接收一个向量数据库类(而非实例),选择器内部会完成实例化。k参数:指定每次检索返回的示例数量,本示例设为 1,以清晰展示匹配结果。实际应用中可根据任务复杂度调整为 2 或 3。FakeEmbeddings的局限性:该实现生成随机向量,不具备真实语义理解能力,因此每次运行匹配结果可能略有差异(但通常仍能基于随机向量的相对距离产生一定的区分度)。在生产环境中替换为真实嵌入模型后,匹配质量将显著提升。
API 速览
本节梳理本示例涉及的核心 API。
SemanticSimilarityExampleSelector
所属库:langchain_core.example_selectors
类方法:
from_examples(examples, embeddings, vectorstore_cls, k, **kwargs)
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
examples | List[dict] | 示例列表,每个字典需包含输入字段(与后续模板变量对应) |
embeddings | Embeddings | 嵌入模型实例,需实现 embed_documents 和 embed_query 方法 |
vectorstore_cls | VectorStore 类 | 向量数据库类,如 Chroma、FAISS,选择器内部会实例化 |
k | int | 每次检索返回的最相似示例数量 |
**kwargs | 可选 | 传递给向量数据库初始化参数,如 collection_name、persist_directory |
返回值:SemanticSimilarityExampleSelector 实例
核心方法:
select_examples(input_variables):接收输入变量字典,返回筛选后的示例列表
FewShotPromptTemplate
所属库:langchain_core.prompts
初始化参数:
example_selector:示例选择器实例,用于动态获取示例example_prompt:PromptTemplate实例,定义单个示例的格式化方式prefix:提示词前缀(固定文本)suffix:提示词后缀,通常包含输入变量占位符input_variables:模板中需要填充的变量名称列表
与长度选择器的对比
| 特性 | LengthBasedExampleSelector | SemanticSimilarityExampleSelector |
|---|---|---|
| 选择依据 | 示例字符长度 + 列表顺序 | 输入与示例的向量余弦相似度 |
| 跨语言支持 | 不支持(按字符数截断) | 支持(嵌入模型通常具有跨语言泛化能力) |
| 计算开销 | 极低(仅累加长度) | 较高(需调用嵌入模型并进行向量检索) |
| 示例池适应性 | 对主题分布无感知 | 能自动匹配与输入语义相近的示例 |
| 适用场景 | 示例数量少、顺序敏感、追求极致性能 | 示例数量多、主题多元、对示例相关性要求高 |
使用建议与生产环境考量
- 嵌入模型选型:对于中文或中英混合场景,推荐使用
text-embedding-ada-002(OpenAI)或开源模型BAAI/bge-large-zh。FakeEmbeddings仅适用于功能演示和单元测试。 - Top-K 值设置:
k一般取 1~3 即可提供有效的 Few Shot 上下文,过大的k值可能引入与当前任务相关度较低的示例,反而稀释提示词的有效信息。 - 向量数据库选型:
- 开发/原型阶段:
Chroma轻量易用,支持本地持久化 - 生产环境:
FAISS(本地高性能)、Pinecone(云原生托管)、Milvus(大规模分布式)
- 开发/原型阶段:
- 示例池维护策略:随着业务需求演进,示例池需定期更新。每次更新后需重新构建向量索引,确保检索结果与最新语义对齐。可使用增量更新机制减少全量重建的开销。
- 缓存与性能优化:对于高频查询场景,可对嵌入向量结果进行缓存,避免重复调用嵌入模型,降低延迟与成本。
Demo 示例
本博客提供的代码即为一个完整可运行的 Demo,无需额外配置。
运行说明:
- 安装依赖:
pip install langchain langchain-core langchain-community chromadb - 保存上述核心脚本为
main.py - 在终端执行:
python main.py - 观察控制台输出,验证不同输入下示例选择的差异
代码说明:
- 使用
FakeEmbeddings模拟嵌入,规避外部依赖 - 示例池涵盖中英文反义词对,涵盖情绪、天气、尺寸三个语义域
- 通过两次不同输入(
worried和晴朗)展示选择器的动态匹配能力
技术点总结:
SemanticSimilarityExampleSelector的创建与使用流程FewShotPromptTemplate与动态示例选择器的集成方式- 向量数据库在提示词工程中的典型应用模式
参考文档
官方文档:
参考链接:
总结
本文围绕 SemanticSimilarityExampleSelector 这一组件,系统阐述了基于语义相似度的动态 Few Shot 示例选择机制。核心要点包括:
- 该选择器将 RAG 中的向量检索思想引入提示词构建阶段,通过嵌入模型将示例和输入统一映射到向量空间,利用余弦相似度实现语义级别的匹配。
- 与长度选择器相比,语义选择器突破了顺序截断的局限,能够根据输入的实际语义内容从大规模示例池中精准检索最相关的示例,尤其在跨语言和多任务混合场景下优势明显。
- 代码实现层面,通过
FakeEmbeddings模拟嵌入过程,提供了无需外部 API Key 的完整可运行示例,覆盖了从示例池构建、向量数据库初始化到动态提示词模板生成的全链路。 - 生产环境部署时,需根据实际场景选择适配的嵌入模型(如
text-embedding-ada-002或BAAI/bge-large-zh)和向量数据库(如Chroma、FAISS、Pinecone),并合理设置k值以及构建缓存机制以优化性能。
402



被折叠的 条评论
为什么被折叠?



