langchain学习笔记之小样本提示词Few-shot Prompt Template

引言

本节将介绍通过小样本提示词 ( Few-shot Prompt Templates ) (\text{Few-shot Prompt Templates}) (Few-shot Prompt Templates)进行提示词追加的方法。

Few-shot Prompt Templates \text{Few-shot Prompt Templates} Few-shot Prompt Templates简单介绍

提示词中添加交互样本的作用是为了模型能够更好地理解用户的想法,从而在回答问题/执行任务中,其结果能够更加满足用户的要求。而小样本提示词模板 ( Few-shot Prompt Templates ) (\text{Few-shot Prompt Templates}) (Few-shot Prompt Templates)旨在使用一组少量的示例来指导模型处理新的输入。

这些少量示例可以用来训练模型,并让模型更好地理解和回答类似的问题。

示例集创建

假设我们提出的问题是:梁思成和林徽因谁的寿命更长 ? ? ? 在对大模型进行提问之前,先准备一个示例数组examples,其里面包含若干个问答样例:
为节省篇幅,这里仅使用两个问答样例。

examples = [
    {
        "question": "穆罕默德·阿里和艾伦·图灵谁的寿命更长?",
        "answer": """
        这里需要跟进问题吗?是的
        跟进: 穆罕默德·阿里去世时多大?
        中间答案: 穆罕默德·阿里去世时74岁
        跟进: 艾伦·图灵去世时多大?
        中间答案: 艾伦·图灵去世时41岁
        最终答案: 穆罕默德·阿里
        """
    },
    {
        "question": "《大白鲨》和《007:皇家赌场》的导演都来自同一个国家吗?",
        "answer": """
        这里需要跟进问题吗?是的
        跟进: 《大白鲨》的导演是谁?
        中间答案: 《大白鲨》的导演是Steven Spielberg
        跟进: Steven Spielberg来自哪里?
        中间答案: 美国
        跟进: 《007:皇家赌场》的导演是谁?
        中间答案: 007:皇家赌场》的导演是Martin Campbell
        跟进: Martin Campbell来自哪里?
        中间答案: 新西兰
        最终答案: 不是
        """
    }
]

观察上述样例,我们发现:在样例的 answer \text{answer} answer部分,用户对模型的回答结果存在具体格式。例如:

  • 开头部分这里需要跟进问题吗?是的 这样一个开头描述;
  • 推理过程中的格式跟进中间答案 等格式字样;
  • 结论部分格式最终答案 格式字样。

创建 ExamplePrompt \text{ExamplePrompt} ExamplePrompt ExampleSelector \text{ExampleSelector} ExampleSelector

创建一个example_prompt,将用户给出的示例格式进行优化,用于后续FewShotPromptTemplate使用:

from langchain.prompts.prompt import PromptTemplate
example_prompt = PromptTemplate(
	input_variables=["question", "answer"],
	template="问题: {question} \n {answer}"
)

原始结果(示例):

{
    "question": "穆罕默德·阿里和艾伦·图灵谁的寿命更长?",
    "answer": """
    这里需要跟进问题吗?是的
    跟进: 穆罕默德·阿里去世时多大?
    中间答案: 穆罕默德·阿里去世时74岁
    跟进: 艾伦·图灵去世时多大?
    中间答案: 艾伦·图灵去世时41岁
    最终答案: 穆罕默德·阿里
    """
}

优化结果

问题: 穆罕默德·阿里和艾伦·图灵谁的寿命更长? 
 
        这里需要跟进问题吗?是的
        跟进: 穆罕默德·阿里去世时多大?
        中间答案: 穆罕默德·阿里去世时74岁
        跟进: 艾伦·图灵去世时多大?
        中间答案: 艾伦·图灵去世时41岁
        最终答案: 穆罕默德·阿里

出现一个新的问题,由于大模型的上下文长度有限,这意味着:输入的提示信息有限。基于该情况,一个朴素的想法是:从冗长示例中选择若干个相似示例作为最终的提示结果

如上例中:问题:梁思成与林徽因谁的寿命更长 ? ? ? 对应的示例明显是第一个:穆罕默德·阿里和艾伦·图灵谁的寿命更长 ? ? ? 因为它们之间描述的语义相似,只是名字部分有所区别。

如何找到与问题相似的示例信息 ? ? ? 需要创建一个示例选择器 ( ExampleSelector ) (\text{ExampleSelector}) (ExampleSelector)来执行这个操作:

from langchain.prompts.example_selector import SemanticSimilarityExampleSelector

一个示例选择器的具体格式示例如下:

from langchain_community.vectorstores import DashVector
from langchain_community.embeddings import DashScopeEmbeddings

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples=examples,
    embeddings=DashScopeEmbeddings(),
    vectorstore_cls=DashVector,
    vectorstore_kwargs={
        "endpoint": DASHVECTOR_ENDPOINT,
        "api_key": DASHVECTOR_API_KEY
    },
    k=1
)

这是一个通过计算问题与各示例样本之间的语义相似度的方式来获取示例样本的选择器。其中:

  • examples:可供选择的示例列表
  • embedding:用于生成 embedding \text{embedding} embedding的类,由于我们使用的 Qwen \text{Qwen} Qwen模型,因此使用DashScopeEmbedding将问题以及示例中的文字进行向量化处理
  • vectorstore_cls:与 Qwen \text{Qwen} Qwen匹配,使用DashVector Embedding \text{Embedding} Embedding结果进行存储以及相似度检索工作的vectorstore类。
  • vectorstore_kwargs:阿里云的向量检索服务需要申请相应的api-keyend-points使向量检索正常运行。
    其中api-key可以从阿里云百炼中进行申请; end-points可以在阿里云的向量检索服务中创建 Cluster \text{Cluster} Cluster进行获取,有免费使用额度。
  • k:表示example_selector要生成的示例数。

这个选择器就可以通过语义相似度找出与问题相关的示例信息:

select_res = example_selector.select_examples({"question": question_input})

在本例中如果将question_input中加入上述问题:梁思成与林徽因谁的寿命更长 ? ? ?,其最终返回的是examples中的第一个样本。

  • 由于example_selector中参数k=1的缘故,因而select_examples方法返回的select_res列表中仅包含一个样本,结合我们提供的示例长度,以及 llm \text{llm} llm支持的上下文长度,适当地调整k值,以便得到更满足要求的问答结果。
{'question': '穆罕默德·阿里和艾伦·图灵谁的寿命更长?', 'answer': '\n        这里需要跟进问题吗?是的\n        跟进: 穆罕默德·阿里去世时多大?\n        中间答案: 穆罕默德·阿里去世时74岁\n        跟进: 艾伦·图灵去世时多大?\n        中间答案: 艾伦·图灵去世时41岁\n        最终答案: 穆罕默德·阿里\n        '}

创建 FewShotPromptTemplate \text{FewShotPromptTemplate} FewShotPromptTemplate

至此,已经通过example_selector找到相似的示例信息,需要将示例信息与问题进行整合,并生成新的prompt

from langchain.prompts.few_shot import FewShotPromptTemplate
prompt = FewShotPromptTemplate(
        example_selector=example_selector,
        example_prompt=example_prompt,
        suffix=f"问题:{question_input}",

其中:

  • example_selector:上面建立的样本选择器
  • example_prompt:将选择出的样本进行使用example_prompt进行格式上的优化;
  • suffix:输入我们要提问的问题question_input。在FewShotPromptTemplatequestion_input执行了两个动作:一个是提供给example_selector找出语义相似的样本信息(example_selector自身不包含问题信息);另一个是将格式优化好的prompt信息与问题进行整合。

最终生成的prompt表示如下:

print(prompt.format(input="梁思成和林徽因谁的寿命更长"))

"""
问题: 穆罕默德·阿里和艾伦·图灵谁的寿命更长? 
 
        这里需要跟进问题吗?是的
        跟进: 穆罕默德·阿里去世时多大?
        中间答案: 穆罕默德·阿里去世时74岁
        跟进: 艾伦·图灵去世时多大?
        中间答案: 艾伦·图灵去世时41岁
        最终答案: 穆罕默德·阿里
        

问题:梁思成和林徽因谁的寿命更长?
"""

将上述结果分成 3 3 3个部分,前 2 2 2个部分是example_selector找到的语义相似的示例样本并使用example_prompt优化后的效果;最后一个部分是我们提出的问题。上述结果作为最终的 prompt \text{prompt} prompt与大模型进行交互。

比对结果

如果没有example_selector产生的信息,仅将问题部分作为prompt与大模型进行交互,对应结果表示如下:

"""
问题:梁思成和林徽因谁的寿命更长?
"""
梁思成(1901420日-197219日),享年70岁。
林徽因(1904610日-195541日),享年50岁。
因此,梁思成的寿命更长。

很明显,语义没有任何问题,只是格式并不是我们想要的格式;如果使用example_selectorFewShotPromptTemplate处理后的prompt,它的对应结果表示如下:

"""
问题: 穆罕默德·阿里和艾伦·图灵谁的寿命更长? 
 
        这里需要跟进问题吗?是的
        跟进: 穆罕默德·阿里去世时多大?
        中间答案: 穆罕默德·阿里去世时74岁
        跟进: 艾伦·图灵去世时多大?
        中间答案: 艾伦·图灵去世时41岁
        最终答案: 穆罕默德·阿里
        

问题:梁思成和林徽因谁的寿命更长?
"""

为了回答这个问题,我们需要了解梁思成和林徽因各自的寿命。

跟进: 梁思成去世时多大?
中间答案: 梁思成出生于1901420日,去世于197219日,享年70岁。

跟进: 林徽因去世时多大?
中间答案: 林徽因出生于1904610日,去世于195541日,享年51岁。

最终答案: 梁思成的寿命更长。

这次结果的语义正确,并且格式上也和示例中的格式非常相似。这是因为处理后的prompt llm \text{llm} llm提供了更丰富的上下文信息

完整代码

"""
样本交互:
若Human单独地提出一个prompt,assistant的回答结果 -> 可能是[宽泛]的
这里的[宽泛]是指:回答结果的语义/格式和Human想要的结果之间存在差异

朴素策略:
通过一系列对话的方式引导assistant反馈给我们更精准/更满足条件的答案
[一系列对话]会给assistant提供上下文的记忆(memory)

或者说,在prompt之前,Human主动提供一些示例 -> 供assistant参考
可以看作是一种[微型的]finetune操作
"""
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import DashVector
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.llms import Tongyi

# 自行申请相应的api-key和end-point
DASHVECTOR_API_KEY = 'YOUR_DASHVECTOR_API_KEY'
DASHVECTOR_ENDPOINT = 'YOUR_DASHVECTOR_ENDPOINT'

examples = [
    {
        "question": "穆罕默德·阿里和艾伦·图灵谁的寿命更长?",
        "answer": """
        这里需要跟进问题吗?是的
        跟进: 穆罕默德·阿里去世时多大?
        中间答案: 穆罕默德·阿里去世时74岁
        跟进: 艾伦·图灵去世时多大?
        中间答案: 艾伦·图灵去世时41岁
        最终答案: 穆罕默德·阿里
        """
    },
    {
        "question": "《大白鲨》和《007:皇家赌场》的导演都来自同一个国家吗?",
        "answer": """
        这里需要跟进问题吗?是的
        跟进: 《大白鲨》的导演是谁?
        中间答案: 《大白鲨》的导演是Steven Spielberg
        跟进: Steven Spielberg来自哪里?
        中间答案: 美国
        跟进: 《007:皇家赌场》的导演是谁?
        中间答案: 007:皇家赌场》的导演是Martin Campbell
        跟进: Martin Campbell来自哪里?
        中间答案: 新西兰
        最终答案: 不是
        """
    }
]

def langchain_few_shot_interaction(question_input):

    example_selector = SemanticSimilarityExampleSelector.from_examples(
        examples=examples,
        embeddings=DashScopeEmbeddings(),
        vectorstore_cls=DashVector,
        vectorstore_kwargs={
            "endpoint": DASHVECTOR_ENDPOINT,
            "api_key": DASHVECTOR_API_KEY
        },
        k=1
    )

    example_prompt = PromptTemplate(
        input_variables=["question", "answer"],
        template="问题: {question} \n {answer}"
    )
    prompt = FewShotPromptTemplate(
        example_selector=example_selector,
        example_prompt=example_prompt,
        suffix=f"问题:{question_input}",
    )
    return (example_selector.select_examples({"question": question_input}),
            prompt.format(input=question_input))


def console(question_input, model_input):

    select_res, template = langchain_few_shot_interaction(question_input)
    template_original = question_input
    prompt_original = PromptTemplate.from_template(template_original)
    prompt = PromptTemplate.from_template(template)

    # 仅将question_input作为prompt
    # chain_original = prompt_original | model_input
    # result = chain_original.stream({
    #     "question": question_input
    # })

    chain = prompt | model_input
    result = chain.stream({
        "question": question_input
    })
    return result

if __name__ == '__main__':
    q = "梁思成和林徽因谁的寿命更长?"
    llm = Tongyi(
        model_name="tongyi-7b-chinese",
        temperature=0.5,
        max_tokens=100,
    )
    res = console(q, llm)
    for chunk in res:
        print(chunk, end="", flush=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/968696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VMware Windows_10_x64 安装 VM Tools 后无法将本机文件复制到虚拟机

有一种情况,安装VM Tools死活安装不上去。这时不要急不要慌,重启本机就好了(本人情况就是如此)。 windows键 R 输入 service.msc 打开服务管理器 找到Virtual Disk服务,选择属性设置为自动,应用后启用服…

python知识和项目经验

一些功能的实现 从.py文件中获取函数对象和参数 的字典 在给定的Python脚本中,通过模块导入和反射机制,如何动态获取包含模型函数的模块中的函数及其默认参数,并构建一个字典以便后续使用? 解决方案 test.py # test.py impor…

Unity下ML-Agents第一个示例

本文写于2025年2月12日,需要提前安装好Anaconda。按文中步骤测试了两次都可正常运行。 一、准备Python端 1.下载并解压 ML-Agents Release 22(使用git clone大概率会失败) 解压路径为 C:\Users\Administrator(Administrator为电…

FastExcel + Java:打造高效灵活的Excel数据导入导出解决方案

作者:后端小肥肠 🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: 基于AOP的数据字典实现…

解决IDEA中gitlab登录只有token选项,没有账号密码选项

如图,当点击gitlab账户登录的时候,只显示server和token,而没有账号选项。期望通过账号密码登录。 解决方式: 插件 - GitLab - 禁用即可。

AI语言模型的技术之争:DeepSeek与ChatGPT的架构与训练揭秘

云边有个稻草人-CSDN博客 目录 第一章:DeepSeek与ChatGPT的基础概述 1.1 DeepSeek简介 1.2 ChatGPT简介 第二章:模型架构对比 2.1 Transformer架构:核心相似性 2.2 模型规模与参数 第三章:训练方法与技术 3.1 预训练与微调…

PHP 中的除以零错误

除以零错误(Division by zero)是指数字除以零的情况, 这在数学上是未定义的。在 PHP 中,处理这种错误的方式取决于 PHP 版本: PHP 7: 使用 / 运算符会产生一个警告 (E_WARNING) 并返回 false。 使用 intd…

【设计模式】01- 一文理解常用设计模式-“创建型模式”篇

一、前言 最近在复习设计模式,撰写、整理了内容和代码片段,和大家一起交流学习。 设计模式是软件设计中常见问题的典型解决方案。 二、模式分类 模式可以根据其意图或目的来分类。常见的设计模式包括: 创建型模式提供创建对象的机制&#x…

数据结构-链式二叉树

文章目录 一、链式二叉树1.1 链式二叉树的创建1.2 根、左子树、右子树1.3 二叉树的前中后序遍历1.3.1前(先)序遍历1.3.2中序遍历1.3.3后序遍历 1.4 二叉树的节点个数1.5 二叉树的叶子结点个数1.6 第K层节点个数1.7 二叉树的高度1.8 查找指定的值(val)1.9 二叉树的销毁 二、层序…

游戏引擎学习第99天

仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:制作一些光场(Light Field) 当前的目标是为游戏添加光照系统,并已完成了法线映射(normal maps)的管道,但还没有创建可以供这些正常映射采样的光场。为了继续推进&…

LSTM变种模型

GRU GRU简介 门控循环神经网络 (Gated Recurrent Neural Network,GRNN) 的提出,旨在更好地捕捉时间序列中时间步距离较大的依赖关系。它通过可学习的门来控制信息的流动。其中,门控循环单元 (Gated Recurrent Unit , GRU) 是…

业务开发 | 基础知识 | Maven 快速入门

Maven 快速入门 1.Maven 全面概述 Apache Maven 是一种软件项目管理和理解工具。基于项目对象模型的概念(POM),Maven 可以从中央信息中管理项目的构建,报告和文档。 2.Maven 基本功能 因此实际上 Maven 的基本功能就是作为 Ja…

新一代SCADA: 宏集Panorama Suite 2025 正式发布,提供更灵活、符合人体工学且安全的应用体验

宏集科技宣布正式推出全新Panorama Suite 2025 SCADA软件!全新版本标志着 Panorama Suite的一个重要里程碑,代表了从 Panorama Suite 2022 开始并跨越三个版本(2022、2023、2025)的开发过程的顶峰。 此次重大发布集中在六个核心主…

PAT乙级真题 — 1080 MOOC期终成绩(java)【测试点3超时】

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计…

【Oracle篇】浅谈执行计划中的多表连接(含内连接、外连接、半连接、反连接、笛卡尔连接五种连接方式和嵌套、哈希、排序合并三种连接算法)

💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…

TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示

知乎的一个问题很有意思:“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节?” 这种问题很适合我这种搞历史的人,大年初一我给出了一个简短的解释,但仔细探究这个问题,我们将会获得 TCP/IP 被定义的过程。 文…

oracle表分区--范围分区

文章目录 oracle表分区分区的原因分区的优势oracle表分区的作用oracle表分区类型一、范围分区二、 创建分区表和使用:1、按照数值范围划分2、按照时间范围3、MAXVALUE2. 向现有表添加新的分区3、 分区维护和重新组织(合并/删除) oracle表分区…

蓝桥杯(B组)-每日一题(求最大公约数最小公倍数)

题目&#xff1a; 代码展现&#xff1a; #include<iostream> using namespace std; int main() {int m,n,x,y;cin>>m>>n;//输入两个整数int b;bm%n;//取余数xm;//赋值yn;while(b)//当余数不为0的时候{xy;//辗转相除求最小公约数yb;bx%y;}cout<<y<&…

基于STM32的学习环境控制系统设计

&#x1f91e;&#x1f91e;大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是学习环境控制。 设备的详细功能见网盘中的文章《21、基于STM32的学习环境控制系统设计》&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1uWSZX2zbZwy9sY…

WPS接入DeepSeek模型

1.wps 下载安装 WPS-支持多人在线协作编辑Word、Excel和PPT文档_WPS官方网站 &#xff08;最好是安装最新的wps&#xff09; 2.offieceAi工具下载安装 软件下载 | OfficeAI助手 下载后安装下载下来的两个工具。安装路径可以自行修改 3.打开WPS,点击文件-》 选项-》信任中心 勾…