(15-2-01)langchain模型I/O与数据增强:示例选择器(Example Selector)-1

示例选择器(Example Selector)是LangChain框架中的一个关键组件,其作用是从大量可用的示例中选择最相关和最有用的示例,以便在构建提示(prompt)时使用。这个过程对于提高语言模型的理解和输出质量至关重要,尤其是在需要少量示例(few-shot)学习的场景中。

3.2.1  创建示例选择器

在与语言模型交互时,提供相关的示例可以帮助模型更好地理解任务的上下文和目标。示例选择器使得开发者能够根据输入动态地选择最合适的示例,而不是随机选择或手动筛选,从而提高交互的准确性和效率。示例选择器(Example Selector)用于从大量示例中选择适合包含在提示中的示例,在构建语言模型的提示时,示例选择器非常有用,因为它可以帮助模型理解上下文并生成更准确的输出。

示例选择器的作用是根据输入的特定条件来选择示例,以便为语言模型提供合适的上下文。例如,根据输入的长度、语义相似度、最大边际相关性等因素来选择示例。

在LangChain中,抽象基类BaseExampleSelector定义了示例选择器的基本接口,该接口包含了如下所示的成员方法:

  1. select_examples(input_variables: Dict[str, str]) -> List[dict]:根据输入的变量选择要包含在提示中的示例,并返回一个示例列表。
  2. add_example(example: Dict[str, str]) -> Any:向示例选择器中添加新的示例。

我们可以根据任务的需求来定制示例选择器的具体实现,在LangChain中提供了如下4种不同类型的示例选择器,包括根据长度、语义相似度、最大边际相关性等进行选择。

  1. Similarity:基于输入和示例之间的语义相似度来选择示例。
  2. MMR (Max Marginal Relevance):选择与输入最相关且多样性最高的示例。
  3. LengthBasedExampleSelector:根据示例的长度来选择,以适应特定的提示长度限制。
  4. Ngram:基于输入和示例之间的n-gram重叠来选择示例。

在构建示例选择器提示时可以灵活选择类型,可以根据具体的情况选择合适的示例,从而提高语言模型的表现和准确性。例如在下面的实例中,演示了根据输入单词长度选择示例选择器的过程。

实例3-5根据输入单词长度选择示例选择器(源码路径:codes\3\Selector01.py

实例文件Selector01.py的具体实现代码如下所示。

from typing import List, Dict, Any


class LengthBasedExampleSelector:
    def __init__(self, examples: List[Dict[str, str]]):
        self.examples = examples

    def select_examples(self, input_word: str) -> List[Dict[str, str]]:
        # 获取输入单词的长度
        input_length = len(input_word)
        # 选择与输入单词长度相同的示例
        selected_examples = [example for example in self.examples if len(example["input"]) == input_length]
        return selected_examples

# 示例数据
examples = [
    {"input": "apple", "output": "苹果"},
    {"input": "banana", "output": "香蕉"},
    {"input": "orange", "output": "橙子"},
]

# 创建示例选择器实例
example_selector = LengthBasedExampleSelector(examples)

# 选择与“please”长度相同的示例
selected_examples = example_selector.select_examples("please")
print(selected_examples) 

在上述代码中,在类LengthBasedExampleSelector中定义了方法select_examples,它接收一个输入单词并返回与输入单词长度相同的示例列表。在示例数据中有一些英文单词和它们的翻译,然后创建了一个示例选择器实例,并使用它来选择与输入单词长度相同的示例。最后,测试了示例选择器,选择了与单词 "please" 长度相同的示例,并打印了选择的示例列表。执行后会输出:

[{'input': 'banana', 'output': '香蕉'}, {'input': 'orange', 'output': '橙子'}]

3.2.2  Length示例选择器

Length示例选择器是一种用于根据示例的长度来选择要包含在提示中的示例的选择器。当我们担心构建的提示会超出上下文窗口的长度时,此选择器非常有用。对于较长的输入,它会选择包含较少示例的提示,而对于较短的输入,它会选择包含更多示例的提示。

在LangChain中,通过LengthBasedExampleSelector实现Length示例选择器,LengthBasedExampleSelector的作用是根据输入长度选择合适的示例,以确保生成的提示不会超过指定的最大长度。

  1. LengthBasedExampleSelector的构造函数接受以下参数 :
  2. example_prompt:用于格式化示例的PromptTemplate。
  3. examples:期望的示例列表。
  4. get_text_length:用于测量提示长度的函数,默认为单词计数。
  5. max_length:格式化后的示例的最大长度。

BaseExampleSelector中的内置成员

  1. elect_examples(input_variables: Dict[str, str]) -> List[dict]:根据输入的长度选择要包含在提示中的示例。
  2. add_example(example: Dict[str, str]) -> None:向选择器中添加新的示例。
  3. construct(**values: Any) -> Model:通过解析和验证关键字参数中的输入数据来创建一个新模型。
  4. copy():复制一个模型,可以选择包含、排除和更改哪些字段。
  5. dict():生成模型的字典表示。
  6. json():生成模型的JSON表示。
  7. 其他辅助方法如parse_obj、parse_raw等:用于解析和验证数据的方法。

在选择示例时,Length示例选择器将考虑输入的长度,并选择与输入长度相匹配的示例,确保生成的提示不会超过指定的最大长度。例如下面是一个使用 LengthBasedExampleSelector 示例选择器的例子,这个例子的任务是创建词语的反义词,预先提供了一些中文词语及其对应的反义词作为示例。

实例3-6创建词语的反义词(源码路径:codes\3\Selector02.py

通过这个例子,可以了解到如何根据特定的需求,使用示例选择器来动态选择适合的示例,从而生成多样化的提示内容。实例文件Selector02.py的具体实现代码如下所示。

from langchain.prompts import FewShotPromptTemplate, PromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector

# 示例:假设任务是创建词语的反义词
examples = [
    {"input": "高兴", "output": "悲伤"},
    {"input": "高", "output": "矮"},
    {"input": "充满活力", "output": "无精打采"},
    {"input": "晴朗", "output": "阴暗"},
    {"input": "刮风", "output": "风平浪静"},
]

# 创建用于格式化示例的 PromptTemplate
example_prompt = PromptTemplate(
    input_variables=["input", "output"],
    template="输入:{input}\n输出:{output}",
)

# 创建 LengthBasedExampleSelector 实例
example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,  # 添加 example_prompt 参数
    max_length=25,
)

# 创建 FewShotPromptTemplate 实例
dynamic_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个输入词的反义词",
    suffix="输入:{adjective}\n输出:",
    input_variables=["adjective"],
)

# 打印示例
print(dynamic_prompt.format(adjective="大"))

对上述代码的具体说明如下所示:

  1. 首先,创建了一个示例选择器 LengthBasedExampleSelector 的实例,指定了示例的列表、用于格式化示例的模板以及最大长度。
  2. 然后,创建了一个 FewShotPromptTemplate 实例,将示例选择器和示例模板传递给它,同时指定了输入变量。
  3. 最后,使用这个 FewShotPromptTemplate 实例来生成一个动态提示,根据输入的词语来选择相应的示例,并将其格式化为最终的提示输出。执行后会输出:
给出每个输入词的反义词

输入:高兴
输出:悲伤

输入:高
输出:矮

输入:充满活力
输出:无精打采

输入:晴朗
输出:阴暗

输入:刮风
输出:风平浪静

输入:大
输出:

3.2.3  Similarity示例选择器

在LangChain中,Similarity示例选择器通常使用余弦相似性作为度量文本之间相似性的主要方法。余弦相似性是通过计算两个文本向量之间的夹角余弦值来衡量它们的相似性。这种方法可以有效地捕捉到文本的语义信息,因为即使在词汇不同的情况下,具有相似含义的文本也会具有较高的余弦相似性。

Similarity示例选择器的主要特点如下所示:

  1. 基于语义的筛选:SemanticSimilarityExampleSelector不仅仅关注词汇的表面相似性,而是深入理解文本的语义内容,选择在意义上与输入最接近的示例。
  2. 动态选择:该选择器可以根据输入变量动态地调整和选择示例,这意味着它能够适应不同类型的查询和任务需求。
  3. 高效性能:通过仅选择必要的示例,该选择器可以显著减少数据处理的时间和资源消耗,同时保持或提高最终模型的性能。
  4. 灵活性:SemanticSimilarityExampleSelector允许用户自定义参数,如示例键、输入键和向量存储,以适应特定的应用场景和需求。

在LangChain中,通过SemanticSimilarityExampleSelector实现Similarity示例选择器,用于从一组数据中选择最具代表性的样本。SemanticSimilarityExampleSelector的核心方法如下所示。

  1. aadd_example:异步方法,用于将新的示例添加到向量存储中。
  2. aselect_examples:异步方法,根据语义相似性选择示例。
  3. afrom_examples:异步类方法,使用示例列表和嵌入创建k-shot示例选择器,并根据查询相似性动态重新洗牌示例。
  4. construct:创建并设置__dict__和__fields_set__的新模型实例。
  5. copy:复制模型实例,可以选择包含、排除或更新特定字段。
  6. dict:生成模型的字典表示,可以选择包含或排除特定字段。
  7. json:生成模型的JSON表示,可以选择包含或排除特定字段。

SemanticSimilarityExampleSelector可以应用于多种NLP任务,如聊天机器人、推荐系统、文本分类等。在这些任务中,理解输入的语义并选择相关的数据对于提高模型的准确性和用户体验至关重要。

例如当构建一个聊天机器人时,可以使用 SemanticSimilarityExampleSelector 来选择与用户输入语义上最接近的历史对话片段,以生成更加相关和自然的回复。例如,假设我们有一个包含历史对话片段的数据库,每个片段都有一个用户输入和相应的机器人回复。

实例3-7聊天机器人的相似性回复(源码路径:codes\3\Selector03.py

实例文件Selector03.py的具体实现代码如下所示。

from langchain_core.example_selectors.semantic_similarity import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

# 假设有一个包含历史对话片段的数据库
conversation_history = [
    {"user_input": "你好", "robot_reply": "你好,请问有什么可以帮助你的吗?"},
    {"user_input": "请问你会做什么?", "robot_reply": "我可以回答问题、提供建议等。"},
    {"user_input": "天气预报", "robot_reply": "今天的天气晴朗,气温适中。"},
    {"user_input": "谢谢", "robot_reply": "不客气,有其他问题随时问我吧。"}
]

# 初始化语义相似性示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    conversation_history,
    OpenAIEmbeddings(),
    Chroma,
    k=1,
)

# 用户输入
user_input = "你好吗?"

# 根据用户输入选择历史对话片段
selected_example = example_selector.select_examples({"user_input": user_input})

# 生成机器人回复
robot_reply = selected_example[0]["robot_reply"]
print(robot_reply)

上述代码的实现流程如下所示:

  1. 定义历史对话片段:使用列表 conversation_history存储了一些历史对话片段,每个片段包含用户输入和机器人回复两个字段。
  2. 初始化语义相似性示例选择器:使用 SemanticSimilarityExampleSelector.from_examples()方法初始化了一个语义相似性示例选择器,传入了历史对话片段、嵌入生成器和向量存储等参数。
  3. 用户输入:定义了一个用户输入 user_input,模拟用户向机器人提问的情景。
  4. 选择历史对话片段:使用 example_selector.select_examples()方法根据用户输入选择了与其语义最接近的历史对话片段,即选取了其中的一条。
  5. 生成机器人回复:将选择的历史对话片段中的机器人回复提取出来,存储在 robot_reply 变量中。
  6. 打印输出机器人回复:最后打印出机器人的回复,即模拟了聊天机器人根据用户输入生成并输出回复的过程。执行后会输出下面的结果,这是因为用户输入 "你好吗?" 在历史对话片段中与 "你好" 这个对话语句语义上最接近,因此选择了这个历史对话片段作为机器人的回复。
你好,请问有什么可以帮助你的吗?

未完待续

  • 16
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值