LangChain 提示语模板
目录
LangChain 库提供了一组类帮应用开发者方便地组合形成提示语,让我们来逐步地了解它的使用。
1. LangChain 提示语模板基础
1.1 提示语模板 PromptTemplate
LangChain 的提示语模板由一组类组成,其中最常用的是 PromptTemplate
与BaseChatPromptTemplate
。提示语模板的相关类如下图所示。
图:提示语模板的主要 Class
来源:https://api.python.langchain.com/en/latest/langchain_api_reference.html#module-langchain.prompts
1.2 PromptTemplate 的使用
设计 LangChain 提示语模板时,我们设定在调用的要提供参数。如下是一个提示语,用invoke()
调用时,我们用 Dictionary 类型输入两个参数:adjective
与 content
。
python
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
chatmodel = ChatOpenAI()
prompt_template = PromptTemplate.from_template(
"Tell me a {adjective} joke about {content}."
)
chain = prompt_template | chatmodel
chain.invoke({
"adjective":"funny",
"content":"chickens",
})
其中,我们用于构建提示语模板的函数是 from_template()
(langchain docs)。
注意这里使用的是聊天模型,LangChain 帮我们完成相关的提示语模板转换。我们实际提供给模型的提示语是:
Tell me a funny joke about chickens.
模型输出是:
AIMessage(content='Why did the chicken become a comedian?\n\nBecause it had all the best "yolks"!')
1.3 ChatPromptTemplate 的使用
如前所述,聊天模型接受的是一组消息,我们也可以用它来更好地组织提供给聊天模型的提示语模板。
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
chatmodel = ChatOpenAI()
chat_template = ChatPromptTemplate.from_messages(
[
("system", "You are a helpful AI bot. Your name is {name}."),
("human", "Hello, how are you doing?"),
("ai", "I'm doing well, thanks!"),
("human", "{user_input}"),
]
)
chain = chat_template | chatmodel
chain.invoke({
"name":"Bob",
"user_input":"What is your name?",
})
其中,我们用于构建提示语模板的函数是 from_messages()
(langchain docs)
我们实际调用模型的提示语是:
python
[
SystemMessage(content='You are a helpful AI bot. Your name is Bob.'),
HumanMessage(content='Hello, how are you doing?'),
AIMessage(content="I'm doing well, thanks!"),
HumanMessage(content='What is your name?')]
模型输出是: AIMessage(content='My name is Bob. How may I assist you today?')
2. ChatPromptTemplate 进阶使用
2.1 三种 Message 类型
LangChain 定义了一组 Message 模板类:
- HumanMessagePromptTemplate
- AIMessagePromptTemplate
- SystemMessagePromptTemplate
- ChatMessagePromptTemplate
我们可以用它们来定义对话提示语模板:
python
from langchain_core.prompts import ChatPromptTemplate
from langchain.prompts import HumanMessagePromptTemplate, AIMessagePromptTemplate, SystemMessagePromptTemplate
from langchain_openai import ChatOpenAI
chatmodel = ChatOpenAI()
chat_template = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template("You are a helpful AI bot. Your name is {name}."),
HumanMessagePromptTemplate.from_template("Hello, how are you doing?"),
AIMessagePromptTemplate.from_template("I'm doing well, thanks!"),
HumanMessagePromptTemplate.from_template("{user_input}"),
]
)
chain = chat_template | chatmodel
chain.invoke({
"name":"Bob",
"user_input":"What is your name?",
})
LangChain-core 定义了一系列 Message 类型,可在如下文档链接查看。其中主要有:
- ChatMessage
- SystemMessage
- HumanMessage
- AIMessage
- FunctionMessage
- ToolMessage
2.2 采用「+」组合 Message 模板
LangChain 提供了一个简单的方式来便于开发者更方便地组织对话提示语模板——用+
将对话提示语模板连接 起来。示例如下:
python
from langchain_core.prompts import ChatPromptTemplate
from langchain.prompts import HumanMessagePromptTemplate, AIMessagePromptTemplate, SystemMessagePromptTemplate
from langchain.schema import AIMessage, HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
chatmodel = ChatOpenAI()
system_message = SystemMessagePromptTemplate.from_template("You are a helpful AI bot. Your name is {name}.")
human_example= HumanMessage(content="Hello, how are you doing?")
ai_example = AIMessage(content="I'm doing well, thanks!")
human_input = HumanMessagePromptTemplate.from_template("{user_input}")
chat_template = (
system_message +
human_example + ai_example +
human_input
)
chain = chat_template | chatmodel
chain.invoke({
"name":"Bob",
"user_input":"What is your name?",
})
由上课件,我们创建多个消息模板,然后,用加号「+」将它们连起来,LangChain 将它们组合成一个消息列表。
2.3 少样本模板的构建
大语言模型是“少样本学习者”(Few shot learner),它能够直接从我们在提示语中提供的样例中学习。在前述代码中,我们手工写入了样例。如果要更方便地创建少样本,我们可以使用 FewShotChatMessagePromptTemplate
来协助。
- 创建 few shot prompt
python
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from langchain_openai import ChatOpenAI
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
]
# This is a prompt template used to format each individual example.
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}"),
("ai", "{output}"),
]
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
print(few_shot_prompt.format())
结果是:
Human: 2+2 AI: 4 Human: 2+3 AI: 5
- 组合形成最终提示语
python
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
print(final_prompt.format(input="What's the square of a triangle?"))
结果是:
System: You are a wondrous wizard of math. Human: 2+2 AI: 4 Human: 2+3 AI: 5 Human: What's the square of a triangle?
- 调用模型
python
chatmodel = ChatOpenAI()
chain = final_prompt | chatmodel
chain.invoke({
"input":"What's the square of a triangle?",
})
模型的回应:
AIMessage(content='A triangle does not have a square because a square is a type of quadrilateral with four equal sides and four right angles. However, a triangle can have an area, which is the amount of space inside the triangle. The area of a triangle can be calculated using the formula: \nArea = (base * height) / 2.')
说明:这里暂时不涉及根据用户提问动态地选择示例样本,具体可参见:example selectors langchain docs
2.4 partial 的使用
使用 LangChain 的提示语模板时,我们可以用partial()
逐步地填充提示语的输入参数。
我们略微改造之前用过的让模型生成 JSON 输出的示例如下:
python
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
# 1. 用 Pydantic 定义输出的 JSON 格式
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
# 2. 创建模型
chatmodel = ChatOpenAI()
# 3. 设定输出解析器
parser = JsonOutputParser(pydantic_object=Joke)
# 4. 创建模板
prompt_template = ChatPromptTemplate.from_messages(
[
("system", "Answer the user query.\n{format_instructions}"),
("user", "{query}")
])
# 5. 在模板中部分填充输出要求
prompt_partial_filled = prompt_template.partial(
format_instructions=parser.get_format_instructions()
)
# 6. 生成调用链
chain = prompt_partial_filled | chatmodel | parser
# 7. 调用模型
joke_query = "Tell me a joke."
chain.invoke({"query": joke_query})
3. 附录:提示语模板类图示
来源:https://api.python.langchain.com/en/latest/langchain_api_reference.html#module-langchain.prompts
4. 小结
总的来说,LangChain 的提示语模板让我们可以更灵活地在代码中创建复杂的提示语模板。