LangChain学习笔记2 Prompt 模板

安装 langchain 库

pip install langchain

1、概念:提示和提示工程

在大语言模型(LLMs)时代,通过简单地更改提示中的指令,同一个模型可以执行多种任务。这一特性让 LLMs 在各类应用场景中都显得非常灵活和强大。然而,这种灵活性也依赖于提示的设计质量。糟糕的提示往往会导致糟糕的输出,而精心设计的提示则能够引导模型发挥出其强大的潜力。

**提示(Prompt)**是用户提供给模型的输入文本,通常用于指导模型完成特定任务或生成特定风格的文本。一个好的提示不仅能够清晰地传达任务意图,还能够提供足够的上下文信息,以引导模型生成高质量的输出。提示的形式可以是问题、指令、上下文说明等。良好的提示设计需要考虑到以下几个方面:

  • 指令 :告诉模型该怎么做,如何使用外部信息(如果提供),如何处理查询并构建 Out。
  • 明确性:提示要清晰明确,让模型能够准确理解用户的意图。
  • 外部信息或上下文信息:提供足够的背景信息或限制条件,以帮助模型生成更具相关性和准确性的答案。充当模型的附加知识来源。这些可以手动插入到提示中,通过矢量数据库 (Vector Database) 检索(检索增强)获得,或通过其他方式(API、计算等)引入。
  • 任务引导:根据任务类型选择合适的提示结构,比如命令式、问题式或描述式提示,以引导模型生成期望的输出。

**提示工程学(Prompt Engineering)**是一个跨学科的领域,旨在设计和优化与大语言模型交互的提示词。提示工程学不仅仅是简单地编写问题或请求,而是通过精确的结构化和策略性设计,使得模型能够在特定任务中表现得更为出色。它包括以下几个方面:

  • 提示词设计:如何根据任务的需要,构造合适的提示语句。
  • 调优和迭代:根据模型的反馈,不断调整提示词,以提高模型生成的质量。
  • 上下文管理:有效地为模型提供足够的上下文,确保生成的答案与期望的一致。

2、LangChain Prompt 模板

2.1 PromptTemplate(String PromptTemplates)

这些提示模板用于格式化单个字符串,通常用于更简单的输入。
方法:
from_template 用于快速创建 PromptTemplate 实例。通过从简单的模板字符串生成一个 PromptTemplate 对象,可以在模板中使用占位符来定义动态内容。
invoke 方法用于执行模板的逻辑,并生成最终的结果。这是 PromptTemplate 类中用于将动态变量填充到模板中并直接获取最终结果的方法。
format 方法是 PromptTemplate 类中用于填充模板中变量的主要方法。它接收命名参数并将它们插入到模板中,生成最终的字符串

方法含义输入参数返回值
from_template创建包含占位符的模板对象,用于生成动态内容的 PromptTemplate 实例模板字符串(带占位符)PromptTemplate 对象
invoke使用字典填充模板变量并直接生成结果字符串变量字典字符串(填充后的模板结果)
format用命名参数填充模板变量并返回结果字符串命名参数(键值对)字符串(填充后的模板结果)

例1

from langchain_core.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template("Tell me a joke about {topic}")

result = prompt_template.invoke({"topic": "cats"})
print(result)

会生成字符串

text=‘Tell me a joke about cats’
Process finished with exit code 0

例2

from langchain.prompts import PromptTemplate
# 定义一个模板 字符串
template = """Question1: {question1} 
Question2: {question2}   
Answer:"""
prompt1 = PromptTemplate(template=template, input_variables=['question1', 'question2'])

prompt2 = PromptTemplate.from_template("Question1: {question1} Question2: {question2} Answer:")
# 用户问题
question1 = "Which NFL team won the Super Bowl in the 2010 season?"
question2 = "Who won the Super Bowl in 2010?"
# 格式化模板
result1 = prompt1.format(question1=question1, question2=question2)
result2 = prompt2.format(question1=question1, question2=question2)
print(result1)
print(result2)

会生成字符串

Question1: Which NFL team won the Super Bowl in the 2010 season?
Question2: Who won the Super Bowl in 2010?
Answer:
Question1: Which NFL team won the Super Bowl in the 2010 season? Question2: Who won the Super Bowl in 2010? Answer:
Process finished with exit code 0

2.2 ChatPromptTemplate(ChatPromptTemplates)

这些提示模板用于设置消息列表的格式。这些 “模板” 由模板本身的列表组成。通常用于聊天机器人,会生成聊天消息列表。

方法名含义返回值
.from_template创建系统消息模板,用于定义模型的角色或行为。SystemMessagePromptTemplate/ AIMessagePromptTemplate/ HumanMessagePromptTemplate
.from_messages创建聊天消息模板,将多条消息组合为一个整体提示。ChatPromptTemplate
.format_messages格式化聊天模板中的占位符并生成消息列表。消息字典列表
.invoke填充模板中的占位符并生成最终的文本。字符串
.format_prompt格式化模板,返回一个可以进一步处理的 ChatPromptValue 对象。ChatPromptValue对象
.to_string将 ChatPromptValue 转换为完整的字符串,用于直接作为模型输入。字符串
.to_messages将 ChatPromptValue 转换为消息列表,适用于聊天场景,兼容 ChatGPT 等模型。消息对象列表(list[dict])

2.2.1 通过消息数组创建聊天消息模板

from langchain_core.prompts import ChatPromptTemplate

# 通过消息数组创建聊天消息模板
# 数组每一个元素代表一条消息,包含role和content两部分
# role的值可以是system、user、assistant
# content的值是消息的内容

chat_template = ChatPromptTemplate.from_messages(
    [
        ("system", "你是一个翻译官,名叫{name}"),
        ("user", "你好"),
        ("assistant", "你好,我是{name},你好!"),
        ("user", "请帮我翻译这句话:{input}"),
    ]
)
# 通过模板参数格式化模板内容
messages = chat_template.format_messages(name="小智", input="请帮我写一篇关于AI的文章")
print(messages)

[SystemMessage(content=‘你是一个翻译官,名叫小智’), HumanMessage(content=‘你好’), AIMessage(content=‘你好,我是小智,你好!’), HumanMessage(content=‘请帮我翻译这句话:请帮我写一篇关于AI的文章’)]
Process finished with exit code 0

在 ChatPromptTemplate 中,role 字段的值通常可以是以下几种:
system:表示系统角色。通常用于向模型提供上下文或背景信息,比如设置模型的行为或规则。
user:表示用户角色。通常是用户发出的请求或问题,模型需要根据这些输入生成响应。
assistant:表示助手角色。通常是模型生成的响应,回答用户的问题或根据用户请求执行任务。

2.2.2 通过具体的消息提示模板类的实例数组创建聊天消息模板

from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate

# 通过具体的消息提示模板类的实例数组创建聊天消息模板
system_message_prompt = SystemMessagePromptTemplate.from_template("你是一个翻译官")
human_message_prompt = HumanMessagePromptTemplate.from_template("请帮我翻译这句话:{input}")
# messages列表
messages = [
    system_message_prompt,
    human_message_prompt
]
chat_prompt = ChatPromptTemplate(messages=messages)
messages = chat_prompt.format_messages(input="请帮我写一篇关于AI的文章")
print(messages)

[SystemMessage(content=‘你是一个翻译官’), HumanMessage(content=‘请帮我翻译这句话:请帮我写一篇关于AI的文章’)]
Process finished with exit code 0

2.2.3 通过SystemMessage、HumanMessagePromptTemplate创建聊天消息模板

from langchain_core.messages import SystemMessage
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate

# 通过SystemMessage、HumanMessagePromptTemplate创建聊天消息模板
chat_template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(
            content="你是一个翻译官"
        ),
        HumanMessagePromptTemplate.from_template("请帮我翻译这句话:{input}")
    ]
)
messages = chat_template.format_messages(input="请帮我写一篇关于AI的文章")
print(messages)

[SystemMessage(content=‘你是一个翻译官’), HumanMessage(content=‘请帮我翻译这句话:请帮我写一篇关于AI的文章’)]
Process finished with exit code 0

2.3 MessagePlaceholder

此提示模板负责在特定位置添加消息列表。通过MessagePlaceholder在指定位置传入一组消息。

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt_template = ChatPromptTemplate.from_messages([
    SystemMessage(content="You are a helpful assistant."),        #system
    MessagesPlaceholder("msgs")         # palceholder
])
result = prompt_template.invoke({"msgs": [
    HumanMessage(content="hi!"),
    {"role": "user", "content": "你是谁?"}
]})
print(result)

这将生成一个包含三条消息的列表,第一条是系统消息,第二条和第三条是我们传入的 HumanMessage。这对于将消息列表放入特定位置非常有用。

messages=[SystemMessage(content=‘You are a helpful assistant.’), HumanMessage(content=‘你是谁?’), HumanMessage(content=‘hi!’)]
Process finished with exit code 0

在不显式使用 MessagesPlaceholder 类的情况下完成相同操作的另一种方法是:

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt_template = ChatPromptTemplate(
    [
        ("system", "You are a helpful assistant"),
        ("placeholder", "{msgs}")
    ]
)
result = prompt_template.invoke({"msgs": [
    HumanMessage(content="hi!"),
    {"role": "user", "content": "你是谁?"}
]})
print(result)

2.4 Few-shot prompting

添加示例输入和预期输出的技术模型提示被称为“少样本提示”。

2.4.1 生成示例

少样本提示的第一步也是最重要的一步是提供一个好的示例数据集。
好的示例应该在运行时相关、清晰、信息丰富,并提供模型尚不知道的信息。
单匝与多轮示例:最简单类型的示例仅具有用户输入和预期模型输出。这些是单匝示例。一种更复杂的类型是示例是整个对话,通常模型最初响应不正确,然后用户告诉模型如何纠正其答案。这称为多轮示例。

2.4.2 例子数量

关键的权衡是,更多的示例通常会提高性能,但更大的提示会增加成本和延迟。超过某个阈值,过多的示例可能会开始使模型变得混乱。找到正确数量的示例在很大程度上取决于模型、任务、示例的质量以及成本和延迟限制。有趣的是,模型越好,表现良好所需的示例就越少,并且添加更多示例时,您的回报率就会越快急剧递减。但是,可靠地回答这个问题的最佳/唯一方法是使用不同数量的示例进行一些实验。

2.4.3 选取示例

需要有一种方法根据给定的输入从数据集中选择示例。示例选择器是负责选择示例并将其格式化为提示的类(https://python.langchain.com/docs/concepts/example_selectors/)。
可以随机、通过输入的(语义或基于关键字)相似性、基于一些其他约束,例如令牌大小进行选取。

2.4.4 格式化示例

不同的模型对不同的语法有更好的响应,例如ChatML 、XML、TypeScript 等。

参数名功能使用场景
examples提供一组少样本学习的输入输出示例,帮助模型理解任务模式。在需要引导模型学习任务要求或特定输出格式时。
example_selector在传递给模型的示例中进行选择,以确保示例的数量和内容长度不会超过模型的处理能力动态选择示例,用于大数据量或动态示例场景
example_prompt定义示例的格式确保示例具有一致的结构化形式
prefix提示前缀,添加上下文或任务说明为 Few-Shot 示例提供背景或任务描述
suffix提示后缀,引导输入和目标输出明确模型任务和用户输入
input_variables定义模板中的动态占位符,这些变量需要在运行时提供实际值。当模板需要根据用户输入生成个性化提示时
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate

# 定义示例
examples = [
    {"text": "I love this movie!", "label": "positive"},
    {"text": "This book is boring.", "label": "negative"},
    {"text": "The weather is nice today.", "label": "neutral"}
]

# 创建示例模板
example_template = """
Text: {text}
Label: {label}
"""

# 创建PromptTemplate
example_prompt = PromptTemplate(
    input_variables=["text", "label"],
    template=example_template
)

# 创建FewShotPromptTemplate
few_shot_prompt = FewShotPromptTemplate(
    examples=examples, #一个列表,包含多个示例,每个示例是一个字典,其中包含输入文本和对应的标签。这些示例将用于指导模型进行预测。
    example_prompt=example_prompt, #  一个 PromptTemplate 对象,用于定义示例的格式。它指定了如何将示例中的输入变量(如 text 和 label)填充到模板中
    prefix="Please classify the following texts as positive, negative, or neutral:",  # 一个字符串,用于在所有示例之前添加的前缀。这个前缀通常提供一些上下文或指导信息,帮助模型理解任务。
    suffix="Text: {input}\nLabel:",   #一个字符串,用于在所有示例之后添加的后缀。这个后缀通常包含一个占位符,用于提示模型输入新的文本进行分类。
    input_variables=["input"]
)

# 使用FewShotPromptTemplate进行预测
new_text = "I enjoyed the concert last night."
print(few_shot_prompt.format(input=new_text))

E:\Anaconda3\envs\openAI\python.exe E:\PythonProjects\openAI\few_short_prompt_template.py
Please classify the following texts as positive, negative, or neutral:
Text: I love this movie!
Label: positive
Text: This book is boring.
Label: negative
Text: The weather is nice today.
Label: neutral
Text: I enjoyed the concert last night.
Label:
Process finished with exit code 0

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

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

相关文章

数据结构二叉树-C语言

数据结构二叉树-C语言 1.树1.1树的概念与结构1.2树的相关术语1.3树的表示1.4树形结构实际运用场景 2.二叉树2.1概念与结构2.2特殊的二叉树2.2.1满二叉树2.2.2完全二叉树 2.3二叉树存储结构2.3.1顺序结构2.3.2链式结构 3.实现顺序结构的二叉树4.实现链式结构二叉树4.1前中后序遍…

Qt/C++进程间通信:QSharedMemory 使用详解(附演示Demo)

在开发跨进程应用程序时,进程间通信(IPC)是一个关键问题。Qt 框架提供了多种 IPC 技术,其中 QSharedMemory 是一种高效的共享内存方式,可以实现多个进程之间快速交换数据。本文将详细讲解 QSharedMemory 的概念、用法及…

【vue3项目使用 animate动画效果】

vue3项目使用 animate动画效果 前言一、下载或安装npm 安装 二、引入组件三、复制使用四、完整使用演示总结 前言 提示:干货篇,不废话,点赞收藏,用到会后好找藕~ 点击这里,直接看官网哦 👉 官网地址&#…

Android 15应用适配指南:所有应用的行为变更

Android系统版本适配,一直是影响App上架Google Play非常重要的因素。 当前Google Play政策规定 新应用和应用更新 必须以 Android 14(API 级别 34)为目标平台,才能提交到Google Play。现有应用 必须以 Android 13(AP…

qml TargetDirection详解

1、概述 TargetDirection是QML(Qt Modeling Language)中一个用于指定粒子系统中粒子移动方向的类型。它允许粒子朝向一个目标点移动,这个目标点可以是QML界面上的一个具体位置,也可以是另一个QML元素的中心。TargetDirection通常…

Linux C 使用ZBar库解析二维码和条形码

1. 编译zbar库 下载 zbar 库源码,这里需要注意下,如果识别的二维码中有中文的话,会出现乱码,一般二维码里中文为UTF-8编码,zbar会默认给你把UTF-8转换为ISO8859-1。有两种解决办法,一是自己再转换一下编码…

金融项目实战 06|Python实现接口自动化——日志、实名认证和开户接口

目录 一、日志封装及应用(理解) 二、认证开户接口脚本编写 1、代码编写 1️⃣api目录 2️⃣script目录 2、BeautifulSoup库 1️⃣简介及例子 2️⃣提取html数据工具封装 3、认证开户参数化 一、日志封装及应用(理解) &…

基于springboot+vue+微信小程序的宠物领养系统

基于springbootvue微信小程序的宠物领养系统 一、介绍 本项目利用SpringBoot、Vue和微信小程序技术,构建了一个宠物领养系统。 本系统的设计分为两个层面,分别为管理层面与用户层面,也就是管理者与用户,管理权限与用户权限是不…

【微服务】面试题 5、分布式系统理论:CAP 与 BASE 详解

分布式系统理论:CAP 与 BASE 详解 一、CAP 定理 背景与定义:1998 年由加州大学科学家埃里克布鲁尔提出,分布式系统存在一致性(Consistency)、可用性(Availability)、分区容错性(Part…

【Vue】Vue组件--上

目录 一、组件基础 二、组件的嵌套关系 1. 基础架构 2. 嵌套 三、组件注册方式 1. 局部注册: 2. 全局注册: 四、组件传递数据 1. 基础架构 2. 传递多值 3. 动态传递数据 五、组件传递多种数据类型 1. Number 2. Array 3. Object 六、组…

鸿蒙UI开发——键盘弹出避让模式设置

1、概 述 我们在鸿蒙开发时,不免会遇到用户输入场景,当用户准备输入时,会涉及到输入法的弹出,我们的界面针对输入法的弹出有两种避让模式:上抬模式、压缩模式。 下面针对输入法的两种避让模式的设置做简单介绍。 2、…

python Streamlit和AKShare 实现的股票数据查询系统

1. 系统概述 这是一个基于Streamlit和AKShare的股票数据查询系统,提供了便捷的股票数据查询和可视化功能。系统支持按板块筛选股票、多股票代码查询、数据导出等功能。 1.1 主要功能 股票代码直接输入查询按板块筛选和选择股票历史数据和实时行情查询财务报表数据…

蓝桥杯备赛:顺序表和单链表相关算法题详解(上)

目录 一.询问学号(顺序表) 1.题目来源: 2.解析与代码实现: (1)解析: (2)代码实现: 二.寄包柜(顺序表) 1.题目来源: …

数据结构-ArrayLIst-一起探索顺序表的底层实现

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连,小编尽全力做到更好 欢迎您分享给更多人哦 大家好,我们今天来学习java数据结构的第一章ArrayList(顺序表) 1.ArrayList的概念 那小伙伴就要问了线性表到…

RabbitMQ(四)

SpringBoot整合RabbitMQ SpringBoot整合1、生产者工程①创建module②配置POM③YAML④主启动类⑤测试程序 2、消费者工程①创建module②配置POM③YAML文件内配置: ④主启动类⑤监听器 3、RabbitListener注解属性对比①bindings属性②queues属性 SpringBoot整合 1、生…

初始Java4

目录 一.继承 1.定义: 2.继承的语法: 3.子类访问父类 4.子类构造方法 5.super与this 6.继承方法 7.final关键字 (1).变量不变 (2).方法不变 (3).类不可继承 8.继承与组合…

极限竞速 地平线5“d3dx12_43.dll”文件丢失或错误导致游戏运行异常如何解决?windows系统DLL文件修复方法

d3dx12_43.dll是存放在windows系统中的一个重要dll文件,缺少它可能会造成部分软件不能正常运行。当你的电脑弹出提示“无法找到d3dx12_43.dll”或“计算机缺少d3dx12_43.dll”等错误问题,请不用担心,我们将深入解析DLL文件错误的成因&#xf…

Leecode刷题C语言之超过阈值的最小操作数②

执行结果:通过 执行用时和内存消耗如下: // 最小堆的节点结构体 typedef struct {long long* heap;int size;int capacity; } MinHeap;// 初始化最小堆 MinHeap* createMinHeap(int capacity) {MinHeap* minHeap (MinHeap*)malloc(sizeof(MinHeap));minHeap->s…

[Qt]常用控件介绍-按钮类控件-QPushButton、QRedioButton、QCheckBox、QToolButton控件

目录 1.QPushButton按钮 介绍 属性 Demo:键盘方向键控制人物移动 2.Redio Button按钮 属性 clicked、pressed、released、toggled区别 单选按钮的分组 Demo:点餐小程序 3.CheckBox按钮 属性 Demo:获取今天的形成计划 4.ToolBu…

寒假第一次牛客周赛 Round 76回顾

AC数&#xff1a;2&#xff08;A、C&#xff09; B 思路&#xff1a; 等价于求&#xff1a; 数量最多的字符 #include<stdio.h> int main() {int n,num;int a[26]{0};//用于存储字母 a 到 z 的出现次数。scanf("%d",&n);char s[n];scanf("%s",s)…