提示词模板之ChatPromptTemplate的使用

实例化的方式(两种方式:使用构造方法,from_message())

方式1:使用构造方法

from pydoc import resolve

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate(
    messages=[
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ],
    input_variables={"name","question"}
)

response = chat_prompt_template.invoke(input={"name":"小智","question":"1 + 2 * 3 = ?"})
print(response)
print(type(response))
print(len(response.messages)) # 包含的消息数

方式2: 调用from_messages)()

from pydoc import resolve

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.invoke(input={"name":"小智","question":"1 + 2 * 3 = ?"})
print(response)
print(type(response))
print(len(response.messages)) # 包含的消息数

调用提示词模板的几种方法

invoke()\format()\format_message()\format_prompt()

invoke(): 传入字典 返回ChatPromptValue类型

format(): 传入变量的值,返回str

format_message(): 传入变量的值,返回消息构成的list

format_prompt(): 传入变量的值,返回ChatPromptValue

方法1:invoke()

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.invoke(input={"name":"小智","question":"1 + 2 * 3 = ?"})
print(response)
print(type(response))
print(len(response.messages)) # 包含的消息数

方法2:format()

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.format(name="小智", question="1 + 2 * 3 = ?")
print(response)
print(type(response))

方法3:format_message()

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.format_messages(name="小智", question="1 + 2 * 3 = ?")
print(response)
print(type(response))

方法4:format_prompt()

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.format_prompt(name="小智", question="1 + 2 * 3 = ?")
print(response)
print(type(response)) #<class 'langchain_core.prompt_values.ChatPromptValue'>

ChatPromptValue与list[messages]、字符串之间的转换

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.format_prompt(name="小智", question="1 + 2 * 3 = ?")
# 将ChatPromptValue类型转换为消息构成的list
response_message = response.to_messages()

# 将ChatPromptValue类型转换为字符串类型
response_string = response.to_string()


print(response_message)
print(type(response_message))

更丰富的实例化类型

本质:不管使用构造方法、还是使用from_message()来创建ChatPromptTemplate的实例,本质上来讲,传入的都是消息构成的列表。

从调用上来讲,我们看到不管使用构造方法,还是使用from_message(),messages参数的类型都是列表,但是列表的元素的类型是多样的,元素可以是:字符串类型、字典类型、消息类型、元组构成的列表(最常用、最简单、最基础)、Chat提示词模板类型、消息提示词模板类型。

举例1:元组构成的列表(最常用、最简单、最基础)

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

response = chat_prompt_template.format_messages(name="小智", question="1 + 2 * 3 = ?")
print(response)
print(type(response))

举例2:字符串

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        "我的问题是{question}"
    ]
)

response = chat_prompt_template.format_messages(question="1 + 2 * 3 = ?")
print(response)
print(type(response))

举例3:字典类型

from langchain_core.prompts import ChatPromptTemplate

# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
    {"role":"system","content":"我是一个人工智能,我的名字叫{name}"},
    {"role":"human","content":"我的问题是{question}"}
])

response = chat_prompt_template.invoke({"name":"小智","question":"1 + 2 * 3 = ?"})
print(response)
print(type(response))

举例4:消息类型

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
    SystemMessage(content="我是一个人工智能,我的名字叫{name}"),
    HumanMessage(content="我的问题是{question}")
])

response = chat_prompt_template.invoke({"name":"小智","question":"1 + 2 * 3 = ?"})
print(response)
print(type(response))

举例5:Chat提示词模板类型

from langchain_core.prompts import ChatPromptTemplate

# 使用 BaseChatPromptTemplate(嵌套的 ChatPromptTemplate)
nested_prompt_template1 = ChatPromptTemplate.from_messages([("system", "我是一个人工智能助手")])
nested_prompt_template2 = ChatPromptTemplate.from_messages([("human", "很高兴认识你")])
prompt_template = ChatPromptTemplate.from_messages([
    nested_prompt_template1,
    nested_prompt_template2
])

prompt_template.format_messages(name="小智", question="1 + 2 * 3 = ?")

举例6:消息提示词模板类型

# 导入聊天消息类模板
from langchain_core.prompts import ChatPromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate
# 创建消息模板
system_template = "你是一个专家{role}"
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)

human_template = "给我解释{concept},用浅显易懂的语言"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

# 组合成聊天提示模板
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt,
human_message_prompt])

# 格式化提示
formatted_messages = chat_prompt.format_messages(
role="物理学家",
concept="相对论"
)
print(formatted_messages)

结合LLM

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
import os
import dotenv

# 1.提供大模型
dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL")

chat_model = ChatOpenAI(model="gpt-4o-mini")

# 2.通过Chat提示词模板创建提示词
# 创建实例
chat_prompt_template = ChatPromptTemplate.from_messages([
        ("system","你是一个AI助手,你的名字叫{name}"),
        ("human","我的问题是{question}")
    ]
)

prompt_response = chat_prompt_template.format_messages(name="小智", question="1 + 2 * 3 = ?")

# 3.通过大模型调用提示词,得到响应模型
response = chat_model.invoke(prompt_response)
print(response)

插入消息列表:MessagePlaceholder

使用场景:当ChatPromptTemplate模板中的消息类型和个数不确定的时候,我们就可以使用MessagesPlaceholder。

举例1:

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.prompts.chat import MessagesPlaceholder

chat_prompt_template = ChatPromptTemplate.from_messages([
    ("system","你是一个AI助手,你的名字叫{name}"),
    MessagesPlaceholder(variable_name="messages")
])

chat_prompt_template.invoke({
    "name":"小智",
"messages":[HumanMessage(content="1 + 2 * 3 = ?")],
})

举例3:存储对话历史记录

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import AIMessage

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    MessagesPlaceholder("history"),
    ("human", "{question}")
])

prompt_value = prompt.format_messages(
    history=[HumanMessage(content="1+2*3 = ?"),AIMessage(content="1+2*3=7")],
    question="我刚才问题是什么?"
)

print(prompt_value)

少量示例的提示词模板的使用

FewshotPromptTemplate的使用

举例1:未提供示例的情况

import os
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")

chat_model = ChatOpenAI(model="gpt-4o-mini",
            temperature=0.4)
res = chat_model.invoke("2 🦜 9是多少?")
print(res.content)

运行结果:

由于未提供示例,所以无法识别2 🦜 9是什么意思。

举例2:使用FewshotPromptTemplate

此时给出示例集合examples,就可以根据集合中的示例模板,模仿回答问题。

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate

import os
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")

chat_model = ChatOpenAI(model="gpt-4o-mini")

#1、创建示例集合
examples = [
    {"input": "北京天气怎么样", "output": "北京市"},
    {"input": "南京下雨吗", "output": "南京市"},
    {"input": "武汉热吗", "output": "武汉市"}
]

#2、创建PromptTemplate实例
example_prompt = PromptTemplate.from_template(
template="Input: {input}\nOutput: {output}"
)

#3、创建FewShotPromptTemplate实例
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Input: {input}\nOutput:", # 要放在示例后面的提示模板字符串。
input_variables=["input"] # 传入的变量
)

#4、调用大模型
prompt = prompt.invoke({"input":"长沙多少度"})
response = chat_model.invoke(prompt)
print(response.content)

运行结果:长沙市

FewShotChatMessagePromptTemplate的使用

     除了FewShotPromptTemplate之外,FewShotChatMessagePromptTemplate是专门为 聊天对话场 设计的少样本(few-shot)提示模板,它继承自 FewShotPromptTemplate ,但针对聊天消息的格 式进行了优化。
特点
     自动将示例格式化为聊天消息( HumanMessage / AIMessage 等)
     输出结构化聊天消息( List[BaseMessage]
     保留对话轮次结构

举例1:基本结构

example_prompt:示例提示词词模版

examples:示例组

from langchain_core.prompts import (
    FewShotChatMessagePromptTemplate,
    ChatPromptTemplate
)
# 1.示例消息格式
examples = [
    {"input": "1+1等于几?", "output": "1+1等于2"},
    {"input": "法国的首都是?", "output": "巴黎"}
]
# 2.定义示例的消息格式提示词模版
msg_example_prompt = ChatPromptTemplate.from_messages([
    ("human", "{input}"),
    ("ai", "{output}"),
])
# 3.定义FewShotChatMessagePromptTemplate对象
few_shot_prompt = FewShotChatMessagePromptTemplate(
    example_prompt=msg_example_prompt,
    examples=examples
)
# 4.输出格式化后的消息
print(few_shot_prompt.format())

举例2:使用方式:将原始输入和被选中的示例组一起加入Chat提示词模版中。

# 1.导入相关包
from langchain_core.prompts import (FewShotChatMessagePromptTemplate,
ChatPromptTemplate)
# 2.定义示例组
examples = [
    {"input": "2🦜2", "output": "4"},
    {"input": "2🦜3", "output": "8"},
]

# 3.定义示例的消息格式提示词模版
example_prompt = ChatPromptTemplate.from_messages([
    ('human', '{input} 是多少?'),
    ('ai', '{output}')
])

# 4.定义FewShotChatMessagePromptTemplate对象
few_shot_prompt = FewShotChatMessagePromptTemplate(
    examples=examples, # 示例组
    example_prompt=example_prompt, # 示例提示词词模版
)

# 5.输出完整提示词的消息模版
final_prompt = ChatPromptTemplate.from_messages([
    ('system', '你是一个数学奇才'), # 系统指令
    few_shot_prompt, # 插入少量样本示例
    ('human', '{input}'), # 用户的实际问题
])

# 6.提供大模型
import os
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
chat_model = ChatOpenAI(model="gpt-4o-mini",
temperature=0.4)
chat_model.invoke(final_prompt.invoke(input="2🦜4")).content

Example selectors(示例选择器)

      前面FewShotPromptTemplate的特点是,无论输入什么问题,都会包含全部示例。在实际开发中,我 们可以根据当前输入,使用示例选择器,从大量候选示例中选取最相关的示例子集。
使用的好处:避免盲目传递所有示例,减少 token 消耗的同时,还可以提升输出效果。
示例选择策略:语义相似选择、长度选择、最大边际相关示例选择等。
语义相似选择 :通过余弦相似度等度量方式评估语义相关性,选择与输入问题最相似的 k 个示
例。
长度选择 :根据输入文本的长度,从候选示例中筛选出长度最匹配的示例。增强模型对文本结构的理解。比语义相似度计算更轻量,适合对响应速度要求高的场景。
最大边际相关示例选择 :优先选择与输入问题语义相似的示例;同时,通过惩罚机制避免返回同质 化的内容。
余弦相似度是通过计算两个向量的夹⻆余弦值来衡量它们的相似性。它的值范围在-1到1之
间:当两个向量⽅向相同时值为1;夹⻆为90°时值为0;⽅向完全相反时为-1。
数学表达式:余弦相似度 = (A·B) / (||A|| * ||B||)。其中A·B是点积,||A||和||B||是向量的模(⻓
度)。

举例1:

examples:这是可供选择的示例列表。

embeddings_model:这是用于生成嵌入的嵌入类,用于衡量语义相似性,用于将文本转换为向量表示。

Chroma:这是一个向量存储库(VectorStore)类,用于存储示例的嵌入向量,并执行相似性搜索。Chroma是一个轻量级的向量数据库,适用于存储和检索向量。

k:这是要生成的示例数量。

# 1.导入相关包
from langchain_community.vectorstores import Chroma
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
import os
import dotenv
from langchain_openai import OpenAIEmbeddings
dotenv.load_dotenv()
# 2.定义嵌入模型
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
embeddings_model = OpenAIEmbeddings( # 用于将文本转换为向量表示
model="text-embedding-ada-002"
)
# 3.定义示例组
examples = [
{
    "question": "谁活得更久,穆罕默德·阿里还是艾伦·图灵?",
    "answer": """
    接下来还需要问什么问题吗?
    追问:穆罕默德·阿里去世时多大年纪?
    中间答案:穆罕默德·阿里去世时享年74岁。
    """,
},
{
    "question": "craigslist的创始人是什么时候出生的?",
    "answer": """
    接下来还需要问什么问题吗?
    追问:谁是craigslist的创始人?
    中级答案:Craigslist是由克雷格·纽马克创立的。
    """,
},
{
    "question": "谁是乔治·华盛顿的外祖父?",
    "answer": """
    接下来还需要问什么问题吗?
    追问:谁是乔治·华盛顿的母亲?
    中间答案:乔治·华盛顿的母亲是玛丽·鲍尔·华盛顿。
    """,
},
{
    "question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?",
    "answer": """
    接下来还需要问什么问题吗?
    追问:《大白鲨》的导演是谁?
    中级答案:《大白鲨》的导演是史蒂文·斯皮尔伯格。
    """,
},
]
# 4.定义示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
# 这是可供选择的示例列表
examples,
# 这是用于生成嵌入的嵌入类,用于衡量语义相似性
embeddings_model,
# 这是一个向量存储库(VectorStore)类,用于存储示例的嵌入向量,并执行相似性搜索。Chroma是一个轻量级的向量数据库,适用于存储和检索向量。
Chroma,
# 这是要生成的示例数量
k=1,
)

# 选择与输入最相似的示例
question = "玛丽·鲍尔·华盛顿的父亲是谁?"
selected_examples = example_selector.select_examples({"question": question})
print(f"与输入最相似的示例:{selected_examples}")

举例2:结合 FewShotPromptTemplate 使用

# 1.导入相关包
from langchain_community.vectorstores import FAISS
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_openai import OpenAIEmbeddings

# 2.定义示例提示词模版
example_prompt = PromptTemplate.from_template(
    template="Input: {input}\nOutput: {output}",
)

# 3.创建一个示例提示词模版
examples = [
    {"input": "高兴", "output": "悲伤"},
    {"input": "高", "output": "矮"},
    {"input": "长", "output": "短"},
    {"input": "精力充沛", "output": "无精打采"},
    {"input": "阳光", "output": "阴暗"},
    {"input": "粗糙", "output": "光滑"},
    {"input": "干燥", "output": "潮湿"},
    {"input": "富裕", "output": "贫穷"},
]

# 4.定义嵌入模型
embeddings = OpenAIEmbeddings(
    model="text-embedding-ada-002"
)

# 5.创建语义相似性示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    embeddings,
    FAISS,
    k=2,
)

# 6.定义小样本提示词模版
similar_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个词组的反义词",
    suffix="Input: {word}\nOutput:",
    input_variables=["word"],
)
response = similar_prompt.invoke({"word":"忧郁"})
print(response.text)

Logo

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

更多推荐