Prompt templates#
提示词模板将用户的是输入和参数转换为Prompt。提高Prompt的灵活性,有几种不同类型的提示模板:
String PromptTemplates#
这些提示模板用于格式化单个字符串,通常用于较简单的输入。构建和使用一个PromptTemplate的常见方法如下:
from typing import Any
from langchain_core.prompts import PromptTemplate
from langchain_core.prompts.base import FormatOutputType
prompt_template = PromptTemplate.from_template("讲一个关于{topic}的笑话")
prompt_template.invoke({"topic": "牛奶"})
ChatPromptTemplates#
主要用来格式化一组消息,且每组消息都带有角色,表示消息是谁说的。支持的角色有
human
user
ai
assistant
system
上面的5种角色,对应在代码中会创建三种Message,对应三种角色HumanMessage
human
user
SystemMessage
system
AIMessage
ai
assistant
构建和使用ChatPromptTemplate的一种常见方法如下:
在下面的方法中,ChatPromptTemplate.for_messages
会创建对应角色的Message。将传进来的参数填充。
from langchain_core.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate.from_messages(
[
("system", "你是一个起名大师. 你的名字叫{name}."),
("human", "你好{name},你感觉如何?"),
("ai", "你好!我状态非常好!"),
("human", "你叫什么名字呢?"),
("ai", "你好!我叫{name}"),
("human", "{user_input}"),
("user", "{user_input}"),
]
)
prompt_template.invoke({"name": "张狗屁", "user_input": "叫什么名字呢?"})
ChatMessagePromptTemplate相关#
ChatMessagePromptTemplate相关的类如下,这些类定义在langchain_core/prompts/chat.py
,和上面两个的差别不大,都是要创建不同角色的Message,并且可以填充参数。但是它们没有实现Runnable
接口,不能调用invoke
方法。
不能通过|
组装chain,它们都是BaseMessagePromptTemplate
的子类
AIMessagePromptTemplate
创建AiMessageHumanMessagePromptTemplate
创建HumanMessageSystemMessagePromptTemplate
创建SystemMessageChatMessagePromptTemplate
创建自定义角色的Message
from langchain_core.prompts import ChatMessagePromptTemplate
from langchain_core.prompts import AIMessagePromptTemplate
from langchain_core.prompts import HumanMessagePromptTemplate
from langchain_core.prompts import SystemMessagePromptTemplate
template = """
讲一个关于{topic}的笑话
"""
# 创建自定义角色
prompt_template = ChatMessagePromptTemplate.from_template(role="customer", template=template)
a1 = prompt_template.format(topic="牛奶")
print(a1) # 返回一个对象
print(type(a1))
a1 = prompt_template.format_messages(topic="黑土")
print(a1) # 返回列表
print(type(a1))
# 创建AI
print("*" * 50)
prompt_template = AIMessagePromptTemplate.from_template(template=template)
a1 = prompt_template.format_messages(topic="牛奶")
print(a1)
# 创建Human
print("*" * 50)
prompt_template = HumanMessagePromptTemplate.from_template(template=template)
a1 = prompt_template.format_messages(topic="牛奶")
print(a1)
# 创建System
print("*" * 50)
prompt_template = SystemMessagePromptTemplate.from_template(template=template)
a1 = prompt_template.format_messages(topic="牛奶")
print(a1)
MessagesPlaceholder#
它会在模板的特定位置插入一组消息,它也是在langchain_core/prompts/chat.py
中定义的,是BaseMessagePromptTemplate
的子类,
单独提出来是因为它经常用。
它接受一个参数,参数的类型比如是list,list就是传递进来的一组消息,之后会将变量替换为这一组消息,并且它支持参数值是否必传,通过optional
,默认是必传的。
例子如下:
from langchain_core.prompts import MessagesPlaceholder
p = MessagesPlaceholder("history")
print(type(p))
res = p.format_messages(history=[
("ai", "ai say"),
("human", "human say"),
])
print(res)
res = p.format_messages() # 不传就会报错
p = MessagesPlaceholder("history", optional=True)
res = p.format_messages(error_history=[
("ai", "ai say"),
("human", "human say"),
])
print(res)
下面来结合ChatPromptTemplate来看看
import langchain
from langchain_core.prompts import MessagesPlaceholder
langchain.debug = True # 开启debug,可以详细的看到运行情况
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个会将笑话的大师,帮我讲个关于{topic}的笑话"),
("human", "你说了什么"),
MessagesPlaceholder("chat_history")
])
res = prompt_template.invoke({"topic": "黑土", "chat_history": [
("ai", "我是一个会讲笑话的大师"),
("user", "啥?")
]})
print(res)
print(res.messages) # 拿到所有的message
还可以直接用placeholder
创建。
rompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个会将笑话的大师,帮我讲个关于{topic}的笑话"),
("human", "你说了什么"),
("placeholder", "{chat_history}")
])
res = prompt_template.invoke({"topic": "黑土", "chat_history": [
("ai", "我是一个会讲笑话的大师"),
("user", "啥?")
]})
print(res)
代入到llm中看一下详细的执行过程
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
import langchain
langchain.debug = True
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个{topic}领域的专家,你要回答用户的问题,如果你不知道,请回复不知道,不要编造答案"),
("user", "{user_input}"),
MessagesPlaceholder(variable_name="chat_history")
])
llm = ChatOpenAI(model="gpt-4")
chain = prompt_template | llm | StrOutputParser()
chat_history = [
("ai", "你好,我是专家,有什么问题可以问我"),
("user", "hi,专家")
]
chain.invoke({
"user_input": "三角函数的余弦值怎么算?",
"topic": "数学",
"chat_history": chat_history
})
开启了debug之后,从上面也可以看到整个的chain的流程。每一个步骤都通过>
来标识出来
PipelinePromptTemplate#
它会组合多个Prompt Template在一起。 这在构建多层次或者多部分组成的prompt很有用。
最终的模板,三层提示词
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts.prompt import PromptTemplate
final_template = """{character}
{behavior}
{prohibit}
{user_input}
"""
final_prompt = PromptTemplate.from_template(final_template)
print(final_prompt)
第一层,性格promot
character_template = """你是{person},你有着{xingge}."""
character_prompt = PromptTemplate.from_template(character_template)
print(character_template)
第二层,行为prompt
behavior_template = """你遵从以下的行为:
{behavior_list}
"""
behavior_prompt = PromptTemplate.from_template(behavior_template)
print(behavior_prompt)
第三层,禁止promot
prohibit_template = """你不允许有以下行为:
{prohibit_list}
"""
prohibit_prompt = PromptTemplate.from_template(prohibit_template)
print(prohibit_prompt)
第四层,增加userinput
user_input_template = """下面是用户的输入:
{input}
"""
input_prompt = PromptTemplate.from_template(user_input_template)
print(input_prompt)
组合起来
input_prompts = [
("character", character_prompt),
("behavior", behavior_prompt),
("prohibit", prohibit_prompt),
("user_input", input_prompt)
]
pipeline_prompt = PipelinePromptTemplate(final_prompt=final_prompt, pipeline_prompts=input_prompts)
print(pipeline_prompt)
它实现了Runnabel
,调用如下
res = pipeline_prompt.invoke({
"person":"你是一个天文学界和一个穿越家",
"xingge": "钢铁般的意志,脾气暴躁,你的口头禅是我滴个豆!",
"behavior_list":"""1.你喜欢冒险
2. 你能掌握时间
3. 你可以发射核弹
""",
"prohibit_list":"""
1. 你不可以说自己是一个人工智能助手或者机器人
2. 不能骂人
""" ,
"input":"你是谁?"
})
print(res)
print("prompt",res.to_string())
代入到llm中运行如下
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
llm = ChatOpenAI(model="gpt-4")
chain = pipeline_prompt | llm | StrOutputParser()
chain.invoke({
"person":"你是一个天文学界和一个穿越家",
"xingge": "钢铁般的意志,脾气暴躁,你的口头禅是我滴个豆!",
"behavior_list":"""1.你喜欢冒险
2. 你能掌握时间
3. 你可以发射核弹
""",
"prohibit_list":"""
1. 你不可以说自己是一个人工智能助手或者机器人
2. 不能骂人
""" ,
"input":"你是谁?"
})
到这,这一章结束了。