1. 什么是示例选择器?

        简单来说,示例选择器是在使用大型语言模型进行“少样本学习”或“上下文学习”时,从大量候选示例中智能地挑选出最相关、最有效的几个示例,并将其构建成提示词的一部分,从而引导模型生成更好结果的一种组件或策略。

  • 示例选择器服务的对象是“少样本学习”
    • 零样本学习: 直接给模型一个任务指令,不给例子。

      提示词:请将以下中文翻译成英文:今天天气真好。
    • 少样本学习: 在指令的基础上,提供几个输入和输出的例子,然后再给出真正的问题。

      提示词:
      请将以下中文翻译成英文:
      示例1 - 输入:你好 -> 输出:Hello
      示例2 - 输入:我爱你 -> 输出:I love you
      示例3 - 输入:今天天气真好 -> 输出:

      在少样本学习中,上述提供的“示例1”、“示例2”就是示例。它们的作用是在模型的上下文中演示任务应该怎么做,让模型更好地理解我们的意图和期望的输出格式。

2. 示例选择器的类型

  • 根据长度要求智能选择示例
  • 根据输入相似度选择示例(最大边际相关性)
  • 根据输入相似度选择示例(最大余弦相似度)

 在 LangChain 框架中的应用:

  • SemanticSimilarityExampleSelector:基于向量相似度,通常默认或优先使用余弦相似度。

  • MaxMarginalRelevanceExampleSelector:基于 MMR。

  • LengthBasedExampleSelector:基于长度。

选择器类型 核心选择策略 适用场景
LengthBasedExampleSelector 根据输入长度和预设的最大长度限制,智能选择或截断示例,以确保提示内容不超出模型上下文窗口。 需要严格控制提示词总长度的场景,例如某些API有严格的字符数限制。
SemanticSimilarityExampleSelector 利用嵌入模型计算输入与示例之间的语义相似度(如余弦相似度),并选择最相似的示例。 需要根据语义相关性来寻找最合适示例的自然语言处理任务。
MaxMarginalRelevanceExampleSelector (MMR) 在保证与输入语义相关性的同时,兼顾所选示例之间的多样性,避免返回高度相似的示例。 信息检索、推荐系统和多轮对话等需要结果多样性的任务。

3.根据长度要求智能选择示例

# 根据输入的提示词长度综合计算最终长度,智能获取或者添加提示词的示例
from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate 
from langchain.prompts.example_selector import LengthBasedExampleSelector

# 假设的提示词示例
examples = [
    {"input":"happy","output":"sad"},
    {"input":"tall","output":"short"},
    {"input":"big","output":"small"},
    {"input":"sunny","output":"gloomy"},
    {"input":"windy","output":"calm"},
    {"input":"高兴","output":"悲伤"}
]

#构造提示词模板
example_prompt = PromptTemplate(
    input_variables=["input","output"],
    template="原词:{input}\n反义:{output}"
)

#调用长度示例选择器
example_selector = LengthBasedExampleSelector(
    #传入提示词示例组
    examples = examples,

    #传入提示词模板
    example_prompt = example_prompt,

    #设置格式化后的最大长度
    max_length=25,

)

#使用小样本提示词模板来实现动态示例调用
dynamic_prompt = FewShotPromptTemplate(
    example_selector = example_selector,
    example_prompt = example_prompt,
    prefix = "给出每个输入词的反义词",  #前缀
    suffix = "原词:{adjective}\n反义:", 
    input_variables=["adjective"]
)
#小样本获得所有实例
print(dynamic_prompt.format(adjective="old"))

print("-----------------------------------------------------------")

# 如果输入长度很长,则最终输出会根据长度要求减少
long_str = "big and huge and massive and large and gigantic and tall and much much much bigger than everyone"
print(dynamic_prompt.format(adjective=long_str))

注意:两个测试需要分开,得到的结果如下:

图1 小样本所获得示例

图2 长输入所获得示例

请注意!!!!!!

进行下面(chromadb包在余弦相似度处用到)的操作需要安装几个包,如果安装速度过慢可以通过镜像安装。

pip install faiss-cpu
pip install tiktoken
pip install sentence-transformers
pip install chromadb

4.根据输入相似度选择示例(最大边际相关性)

  • MMR是一种在信息检索中常用的方法,它的目标是在相关性和多样性之间找到一个平衡
  • MMR会首先找出与输入最相似(即余弦相似度最大)的样本
  • 然后在迭代添加样本的过程中,对于与已选择样本过于接近(即相似度过高)的样本进行惩罚
  • MMR既能确保选出的样本与输入高度相关,又能保证选出的样本之间有足够的多样性
  • 关注如何在相关性和多样性之间找到一个平衡
#使用MMR来检索相关示例,以使示例尽量符合输入
from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector
from langchain.vectorstores import FAISS #向量数据库 
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts import PromptTemplate

# 使用专业的双语嵌入模型
embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)

# 假设已经有这么多的提示词示例
examples = [
    {"input":"happy","output":"sad"},
    {"input":"tall","output":"short"},
    {"input":"big","output":"small"},
    {"input":"sunny","output":"gloomy"},
    {"input":"windy","output":"calm"},
    {"input": "高兴", "output": "悲伤"},
    {"input": "快乐", "output": "痛苦"},
    {"input": "开心", "output": "难过"},
    {"input": "喜欢", "output": "讨厌"},
    {"input": "美丽", "output": "丑陋"}
]

#构造提示词模板
example_prompt = PromptTemplate(
    input_variables=["input","output"],
    template="原词:{input}\n反义:{output}"
)

# 调用MMR模板
example_selector = MaxMarginalRelevanceExampleSelector.from_examples(
    examples = examples,    #传入示例数据集
    embeddings = embeddings,  #使用嵌入模型
    vectorstore_cls = FAISS,  #设置向量数据库类
    k=2   #最终选择的示例数量
)

#使用小样本模板
mmr_prompt = FewShotPromptTemplate(
    example_selector = example_selector,
    example_prompt = example_prompt,
    prefix = "给出每个输入词的反义词",
    suffix = "原词:{adjective}\n反义:",
    input_variables=["adjective"]
)

# 测试
print(mmr_prompt.format(adjective = "poor"))

输出结果如下:

图3 基于MMR输入所得示例

5.根据输入相似度选择示例(最大余弦相似度)

  • 一种常见的相似度计算方法

  • 它通过计算两个向量(在这里,向量可以代表文本、句子或者词语)之间的余弦值来衡量它们的相似度

  • 余弦值越接近1,表示两个向量越相似

  • 主要关注的是如何准确衡量两个向量的相似度

#使用最大余弦相似度来检索相关示例,以使示例尽量符合输入
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings 
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts import PromptTemplate

    
# 使用专业的双语嵌入模型
embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)

# 假设已经有这么多的提示词示例
examples = [
    {"input":"happy","output":"sad"},
    {"input":"tall","output":"short"},
    {"input":"big","output":"small"},
    {"input":"sunny","output":"gloomy"},
    {"input":"windy","output":"calm"},
    {"input": "高兴", "output": "悲伤"},
    {"input": "快乐", "output": "痛苦"},
    {"input": "开心", "output": "难过"},
    {"input": "喜欢", "output": "讨厌"},
    {"input": "美丽", "output": "丑陋"}
]

#构造提示词模板
example_prompt = PromptTemplate(
    input_variables=["input","output"],
    template="原词:{input}\n反义:{output}"
)

# 调用余弦相似度模板
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples = examples,
    embeddings = embeddings,
    vectorstore_cls = Chroma,
    k=1,
)

#使用小样本模板
similar_prompt = FewShotPromptTemplate(
    example_selector = example_selector,
    example_prompt = example_prompt,
    prefix = "给出每个输入词的反义词", 
    suffix = "原词:{adjective}\n反义:", 
    input_variables=["adjective"]
)

print(similar_prompt.format(adjective = "huge"))

输出结果如下:

图4 基于最大余弦相似度输入所得示例

5.deepseek生成模式与专业嵌入模式结合

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts import PromptTemplate
import requests


embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)

deepseek_api_key="sk-xxx" #API密钥

# DeepSeek API 调用函数
class DeepSeekGenerator:
    def __init__(self, api_key, api_base="https://api.deepseek.com/v1"):
        self.api_key = api_key
        self.api_base = api_base
    
    def generate(self, prompt):
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }
        
        data = {
            "model": "deepseek-chat",
            "messages": [{"role": "user", "content": prompt}],
            "stream": False,
            "temperature": 0.1 
        }
        
        response = requests.post(f"{self.api_base}/chat/completions", 
                               headers=headers, json=data)
        
        if response.status_code == 200:
            return response.json()["choices"][0]["message"]["content"]
        else:
            return f"Error: {response.status_code} - {response.text}"

deepseek_generator = DeepSeekGenerator(api_key = deepseek_api_key)

# 示例数据
examples = [
    {"input":"happy","output":"sad"},
    {"input":"tall","output":"short"},
    {"input":"big","output":"small"},
    {"input":"sunny","output":"gloomy"},
    {"input":"windy","output":"calm"},
    {"input":"hot","output":"cold"},
    {"input":"fast","output":"slow"},
    {"input":"rich","output":"poor"},
    {"input":"strong","output":"weak"},
    {"input":"beautiful","output":"ugly"},
    {"input":"good","output":"bad"},
    {"input":"light","output":"dark"},
    {"input":"soft","output":"hard"},
    {"input":"high","output":"low"},
    
    {"input": "高兴", "output": "悲伤"},
    {"input": "快乐", "output": "痛苦"},
    {"input": "开心", "output": "难过"},
    {"input": "喜欢", "output": "讨厌"},
    {"input": "美丽", "output": "丑陋"},
    {"input": "大", "output": "小"},
    {"input": "高", "output": "矮"},
    {"input": "快", "output": "慢"},
    {"input": "热", "output": "冷"},
    {"input": "强", "output": "弱"},
    {"input": "富有", "output": "贫穷"},
    {"input": "光明", "output": "黑暗"},
    {"input": "软", "output": "硬"},
]

example_prompt = PromptTemplate(
    input_variables=["input","output"],
    template="原词: {input} -> 反义: {output}"
)

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples = examples,
    embeddings = embeddings,
    vectorstore_cls = FAISS,
    k=3
    
)

cosine_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="请根据以下反义词示例,为输入词提供反义词:\n示例:",
    suffix="输入:{adjective}\n",
    input_variables=["adjective"]
)

def get_antonym_with_hybrid_model(word):
    prompt_with_examples = cosine_prompt.format(adjective=word)
    print("=================== 检索到的示例 =====================")
    print(prompt_with_examples)
    # print("=" * 50)
    
    final_prompt = f"""
    基于以下上下文示例,给出输入词的反义词:
    {prompt_with_examples}
    请只输出反义词,不要额外解释。
    """
   
    result = deepseek_generator.generate(final_prompt)
    return result.strip()


# 测试混合模型
test_words = ["mild", "和平", "amazing", "干净"]
for i, word in enumerate(test_words, 1):
    print(f"测试 {i}/4: '{word}'")
    antonym = get_antonym_with_hybrid_model(word)
    print(f"最终结果: '{antonym}'")
    print(f"{'-'*60}")

输出结果如下:

测试 1/4: 'mild'
=================== 检索到的示例 =====================
请根据以下反义词示例,为输入词提供反义词:
示例:

原词: 软 -> 反义: 硬

原词: 强 -> 反义: 弱

原词: 高 -> 反义: 矮

输入:mild

最终结果: 'harsh'
------------------------------------------------------------
测试 2/4: '和平'
=================== 检索到的示例 =====================
请根据以下反义词示例,为输入词提供反义词:
示例:

原词: 开心 -> 反义: 难过

原词: 强 -> 反义: 弱

原词: 高兴 -> 反义: 悲伤

输入:和平

最终结果: '战争'
------------------------------------------------------------
测试 3/4: 'amazing'
=================== 检索到的示例 =====================
请根据以下反义词示例,为输入词提供反义词:
示例:

原词: 大 -> 反义: 小

原词: 开心 -> 反义: 难过

原词: 强 -> 反义: 弱

输入:amazing

最终结果: 'unimpressive'
------------------------------------------------------------
测试 4/4: '干净'
=================== 检索到的示例 =====================
请根据以下反义词示例,为输入词提供反义词:
示例:

原词: 强 -> 反义: 弱

原词: 快 -> 反义: 慢

原词: 大 -> 反义: 小

输入:干净

最终结果: '脏'
------------------------------------------------------------

ok!!!!!!结束。又该学习咯

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐