一个大语言模型的提示是用户提供的一组指令或输入,用来引导模型的响应,帮助它理解上下文和生成相关且连贯的基于语言的输出,例如回答问题、完成句子或参与对话。
提示模板是一种预设的格式,用于为语言模型生成引导指令。
一个模板可能包含指令、少样本示例以及为特定任务准备的具体上下文和问题。
通常情况下,语言模型预期接收的提示是一个字符串,或者是一个聊天信息的列表。
PromptTemplate
PromptTemplate
可以用来为字符串提示创建一个模板。默认情况下,PromptTemplate
利用 Python 中的 str.format 方法来创建字符串模板。
1
2
3
4
5
6
|
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template(
"Tell me a {adjective} joke about {content}."
)
prompt_template
|
1
|
PromptTemplate(input_variables=['adjective', 'content'], template='Tell me a {adjective} joke about {content}.')
|
1
|
prompt_template.format(adjective="funny", content="chickens")
|
'Tell me a funny joke about chickens.'
这个模板可以包含任意多个变量,也可以不包含任何变量:
1
2
3
4
|
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("Tell me a joke")
prompt_template
|
1
|
PromptTemplate(input_variables=[], template='Tell me a joke')
|
1
|
prompt_template.format()
|
'Tell me a joke'
在操作字符串提示时,各个模板将被连续地组合起来,不过列表中的首个元素需要是一个提示。
1
2
3
4
5
6
7
8
|
from langchain_core.prompts import PromptTemplate
prompt = (
PromptTemplate.from_template("Tell me a joke about {topic}")
+ ", make it funny"
+ "\n\nand in {language}"
)
prompt
|
1
|
PromptTemplate(input_variables=['language', 'topic'], template='Tell me a joke about {topic}, make it funny\n\nand in {language}')
|
1
|
prompt.format(topic="sports", language="spanish")
|
'Tell me a joke about sports, make it funny\n\nand in spanish'
ChatPromptTemplate
ChatModels 的提示是一个包含多条聊天消息的列表。
每条聊天消息都关联一段内容,并有一个称作 role
的附加参数。
像这样创建一个 ChatPromptTemplate
:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from langchain_core.prompts import ChatPromptTemplate
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}"),
]
)
messages = chat_template.format_messages(name="Bob", user_input="What is your name?")
messages
|
1
2
3
4
|
[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?')]
|
ChatPromptTemplate.from_messages
静态方法能够接收多种形式的消息,并为将这些消息准确无误地传递到聊天模型提供了一个便捷的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from langchain_core.messages import SystemMessage
from langchain_core.prompts import HumanMessagePromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
SystemMessage(
content=(
"You are a helpful assistant that re-writes the user's text to "
"sound more upbeat."
)
),
HumanMessagePromptTemplate.from_template("{text}"),
]
)
messages = chat_template.format_messages(text="I don't like eating tasty things")
messages
|
1
|
[SystemMessage(content="You are a helpful assistant that re-writes the user's text to sound more upbeat."), HumanMessage(content="I don't like eating tasty things")]
|
1
2
3
4
5
6
7
8
|
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
prompt = SystemMessage(content="You are a nice pirate")
new_prompt = (
prompt + HumanMessage(content="hi") + AIMessage(content="what?") + "{input}"
)
messages = new_prompt.format_messages(input="i said hi")
messages
|
1
2
3
4
|
[SystemMessage(content='You are a nice pirate'),
HumanMessage(content='hi'),
AIMessage(content='what?'),
HumanMessage(content='i said hi')]
|
Message Prompts
LangChain 提供了不同种类的 MessagePromptTemplate
。
其中,最常用的模板包括 AIMessagePromptTemplate
、SystemMessagePromptTemplate
和 HumanMessagePromptTemplate
,它们分别用于生成 AI 消息、系统消息和面向人类的消息。
来比较一下 PromptTemplate
和 Message
之间的区别:
1
2
3
4
5
6
|
from langchain_core.prompts import SystemMessagePromptTemplate
from langchain_core.messages import SystemMessage
smpt = SystemMessagePromptTemplate.from_template("You are a helpful assistant, {etc}")
sm = SystemMessage(content="You are a nice pirate")
smpt, sm
|
1
2
|
(SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['etc'], template='You are a helpful assistant, {etc}')),
SystemMessage(content='You are a nice pirate'))
|
区别在于 PromptTemplate
可以用来创建字符串模板并插入变量。
当聊天模型能够处理带有任意指定角色的消息时,你可以选用 ChatMessagePromptTemplate
。这种模板使得用户能够自由定义角色名称。
1
2
3
4
5
6
7
8
|
from langchain_core.prompts import ChatMessagePromptTemplate
prompt = "May the {subject} be with you"
chat_message_prompt = ChatMessagePromptTemplate.from_template(
role="Jedi", template=prompt
)
chat_message_prompt.format(subject="force")
|
1
|
ChatMessage(content='May the force be with you', role='Jedi')
|
MessagesPlaceholder
LangChain 还提供 MessagesPlaceholder
,它让你能够精确控制在格式化文本时要展示的信息内容。这在你不确定该为信息模板选择哪种角色,或者想要在文本格式化时加入一串特定信息列表时,尤为有用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
from langchain_core.prompts import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
MessagesPlaceholder,
)
human_prompt = "Summarize our conversation so far in {word_count} words."
human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)
chat_prompt = ChatPromptTemplate.from_messages(
[MessagesPlaceholder(variable_name="conversation"), human_message_template]
)
from langchain_core.messages import AIMessage, HumanMessage
human_message = HumanMessage(content="What is the best way to learn programming?")
ai_message = AIMessage(
content="""\
1. Choose a programming language: Decide on a programming language that you want to learn.
2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures.
3. Practice, practice, practice: The best way to learn programming is through hands-on experience\
"""
)
chat_prompt.format_prompt(
conversation=[human_message, ai_message], word_count="10"
).to_messages()
|
1
2
3
|
[HumanMessage(content='What is the best way to learn programming?'),
AIMessage(content='1. Choose a programming language: Decide on a programming language that you want to learn.\n\n2. Start with the basics: Familiarize yourself with the basic programming concepts such as variables, data types and control structures.\n\n3. Practice, practice, practice: The best way to learn programming is through hands-on experience'),
HumanMessage(content='Summarize our conversation so far in 10 words.')]
|
PipelinePrompt www.cqzlsb.com
当你希望重复使用部分提示时,PipelinePromptTemplate
非常有用。一个 PipelinePrompt 主要包含两个部分:
- 最终提示:返回的最终提示
- 管道提示:一个由元组组成的列表,每个元组包含一个字符串名称和一个提示模板。每个提示模板都将被格式化,然后作为具有相同名称的变量传递给未来的提示模板。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
from langchain_core.prompts.pipeline import PipelinePromptTemplate
from langchain_core.prompts.prompt import PromptTemplate
full_template = """{introduction}
{example}
{start}"""
full_prompt = PromptTemplate.from_template(full_template)
introduction_template = """You are impersonating {person}."""
introduction_prompt = PromptTemplate.from_template(introduction_template)
example_template = """Here's an example of an interaction:
Q: {example_q}
A: {example_a}"""
example_prompt = PromptTemplate.from_template(example_template)
start_template = """Now, do this for real!
Q: {input}
A:"""
start_prompt = PromptTemplate.from_template(start_template)
input_prompts = [
("introduction", introduction_prompt),
("example", example_prompt),
("start", start_prompt),
]
pipeline_prompt = PipelinePromptTemplate(
final_prompt=full_prompt, pipeline_prompts=input_prompts
)
|
1
|
pipeline_prompt.input_variables
|
1
|
['person', 'example_a', 'example_q', 'input']
|
1
2
3
4
5
6
7
8
|
print(
pipeline_prompt.format(
person="Elon Musk",
example_q="What's your favorite car?",
example_a="Tesla",
input="What's your favorite social media site?",
)
)
|
1
2
3
4
5
6
7
8
9
10
11
|
You are impersonating Elon Musk.
Here's an example of an interaction:
Q: What's your favorite car?
A: Tesla
Now, do this for real!
Q: What's your favorite social media site?
A:
|
Partial prompt templates
就像其他方法一样,对一个提示模版进行 “部分填充” 也是有意义的。
LangChain 用两种方式支持这个功能:
- 使用字符串值进行部分格式化。
- 使用返回字符串值的函数进行部分格式化。
这两种不同的方式支持不同的使用场景。在下面的范例中,我们将分别阐述这两种使用场景的目的,以及如何在 LangChain 中应用。
Partial with strings
当你需要分批获得不同的变量时,部分填充提示模板就显得非常实用。举个例子,假如你有一个提示模板,里面需要填入两个变量,分别是 foo
和 baz
。如果在处理流程的前期就得到了 foo
的值,但是要到后期才能得到 baz
的值,整个流程会因为需要同时拥有这两个变量才能继续而变得不那么顺畅。你可以选择先将 foo
值填入模板,然后再将这个已填充了 foo
值的提示模板传递下去,这样在接下来的步骤中只需要关注 baz
值即可。以下是如何做到这一点的示例:
1
2
3
4
5
|
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template("{foo}{bar}")
partial_prompt = prompt.partial(foo="foo")
partial_prompt
|
1
|
PromptTemplate(input_variables=['bar'], partial_variables={'foo': 'foo'}, template='{foo}{bar}')
|
1
|
print(partial_prompt.format(bar="baz"))
|
foobaz
也可以这么写:
1
2
3
4
|
prompt = PromptTemplate(
template="{foo}{bar}", input_variables=["bar"], partial_variables={"foo": "foo"}
)
print(prompt.format(bar="baz"))
|
foobaz
Partial with functions
另一个方便的应用是利用函数进行部分填充。这个方法特别有助于处理那些你希望以固定模式获取的变量。举个例子,你可能会有一个提示模板,希望它总能自动包含当前的日期或时间。显然,你不可能将一个固定日期写死在模板里,每次还要和其他变量一起手动传入日期也显得比较麻烦。在这种场景下,如果你能够部分填充一个始终能返回当前日期的函数到提示模板中,那将大大简化整个流程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from datetime import datetime
def _get_datetime():
now = datetime.now()
return now.strftime("%m/%d/%Y, %H:%M:%S")
prompt = PromptTemplate(
template="Tell me a {adjective} joke about the day {date}",
input_variables=["adjective", "date"],
)
partial_prompt = prompt.partial(date=_get_datetime)
partial_prompt
|
1
|
PromptTemplate(input_variables=['adjective'], partial_variables={'date': <function _get_datetime at 0x7ac5c5b988b0>}, template='Tell me a {adjective} joke about the day {date}')
|
1
|
print(partial_prompt.format(adjective="funny"))
|
Tell me a funny joke about the day 05/07/2024, 07:24:11
也可以这么写:
1
2
3
4
5
6
|
prompt = PromptTemplate(
template="Tell me a {adjective} joke about the day {date}",
input_variables=["adjective"],
partial_variables={"date": _get_datetime},
)
print(prompt.format(adjective="funny"))
|