赞
踩
本文整理改编自:
https://www.langchain.com.cn/modules/prompts/prompt_templates
https://python.langchain.com.cn/docs/modules/model_io/prompts/
代码基于 langchain 0.1.14 测试
编写模型的新方式是通过提示。
一个 提示(prompt) 指的是 输入模型 的内容。
这个输入通常由多个组件构成。
LangChain 提供了多个类和函数,使构建和处理提示变得简单。
它包含一个文本字符串(称为:模板,template),该字符串可以从最终用户那里 接收一组参数 并生成提示。
提示模板是生成语言模型提示的 预定义配方。
提示模板可能包含:
LangChain提供了创建和使用提示模板的工具。
LangChain致力于创建 与模型无关 的模板,以便在不同的语言模型之间 轻松重用现有模板。
您可以使用 PromptTemplate 类创建简单的 硬编码提示。
提示模板可以接受任意数量的输入变量,并可以 格式化 生成提示。
示例1
from langchain import PromptTemplate
template = '''I want you to act as a naming consultant for new companies.
What is a good name for a company that makes {product}?
'''
prompt = PromptTemplate(
template = template,
input_variables=['product'],
)
prompt 为:
PromptTemplate(input_variables=['product'],
output_parser=None,
partial_variables={},
template='I want you to act as a naming consultant for new companies.\nWhat is a good name for a company that makes {product}?\n',
template_format='f-string', validate_template=True)
prompt.format(product="colorful socks")
'I want you to act as a naming consultant for new companies.\nWhat is a good name for a company that makes colorful socks?\n'
手动指定 input_variables
no_input_prompt = PromptTemplate(input_variables=[],
template="Tell me a joke.")
no_input_prompt.format()
# 'Tell me a joke.'
one_input_prompt = PromptTemplate(input_variables=["adjective"],
template="Tell me a {adjective} joke.")
one_input_prompt.format(adjective="funny")
# 'Tell me a funny joke.'
multiple_input_prompt = PromptTemplate(
input_variables=["adjective", "content"],
template="Tell me a {adjective} joke about {content}."
)
multiple_input_prompt.format(adjective="funny", content="chickens")
# -> 'Tell me a funny joke about chickens.'
根据传递的 template 自动推断 input_variables
。
template = "Tell me a {adjective} joke about {content}."
prompt_template = PromptTemplate.from_template(template)
prompt_template.input_variables
# -> ['adjective', 'content']
prompt_template.format(adjective="funny", content="chickens")
# -> Tell me a funny joke about chickens.
聊天模型 以聊天消息列表作为输入 - 这个列表通常称为 prompt。
这些聊天消息与原始字符串不同(您会将其传递给 LLM 模型),因为每个消息都与一个 role 相关联。
要创建与角色相关联的消息模板,您可以使用 MessagePromptTemplate。
LangChain 提供了不同类型的 MessagePromptTemplate
,其中最常用的是
AIMessagePromptTemplate
, 创建 AI 消息SystemMessagePromptTemplate
, 系统消息HumanMessagePromptTemplate
,人类消息ChatMessagePromptTemplate
,允许用户指定角色名称from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
system_message_prompt
SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input_language', 'output_language'], output_parser=None, partial_variables={}, template='You are a helpful assistant that translates {input_language} to {output_language}.', template_format='f-string', validate_template=True), additional_kwargs={})
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
human_message_prompt
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['text'], output_parser=None, partial_variables={}, template='{text}', template_format='f-string', validate_template=True), additional_kwargs={})
更直接地构建MessagePromptTemplate:可以在外部创建一个 PromptTemplate,然后将其传递进去
prompt=PromptTemplate(
template="You are a helpful assistant that translates {input_language} to {output_language}.",
input_variables=["input_language", "output_language"],
)
system_message_prompt_2 = SystemMessagePromptTemplate(prompt=prompt)
system_message_prompt_2
SystemMessagePromptTemplate(prompt=PromptTemplate(
input_variables=['input_language', 'output_language'],
output_parser=None,
partial_variables={},
template='You are a helpful assistant that translates {input_language} to {output_language}.',
template_format='f-string',
validate_template=True),
additional_kwargs={})
assert system_message_prompt == system_message_prompt_2
可以使用ChatPromptTemplate
的format_prompt
方法 - 这将返回一个PromptValue
,
您可以将其转换为字符串或Message对象,具体取决于您是否想将格式化值用作llm或chat模型的输入。
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt,
human_message_prompt])
# get a chat completion from the formatted messages
chat_prompt.format_prompt(input_language="English",
output_language="French",
text="I love programming.").to_messages()
[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}),
HumanMessage(content='I love programming.', additional_kwargs={}, example=False)]
ChatMessagePromptTemplate
,指定角色名称from langchain.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")
ChatMessage(content='May the force be with you', additional_kwargs={}, role='Jedi')
当您不确定应该使用哪个消息提示模板的角色,或者希望在格式化期间插入消息列表时,这可能非常有用。
from langchain.prompts import 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] )
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()
[HumanMessage(content='What is the best way to learn programming?', additional_kwargs={}),
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', additional_kwargs={}),
HumanMessage(content='Summarize our conversation so far in 10 words.', additional_kwargs={})]
默认情况下,PromptTemplate
会将提供的模板作为 Python f-string 处理。您可以通过 template_format
参数指定其他模板格式:
目前,PromptTemplate
仅支持 jinja2
和 f-string
模板格式。
运行这些之前,需要保证 jinja2 已安装
Make sure jinja2 is installed before running this
jinja2_template = "Tell me a {{ adjective }} joke about {{ content }}"
jinja2_template
# -> 'Tell me a {{ adjective }} joke about {{ content }}'
prompt_template = PromptTemplate.from_template(template=jinja2_template,
template_format="jinja2")
prompt_template
PromptTemplate(
input_variables=['adjective', 'content'],
output_parser=None,
partial_variables={},
template='Tell me a {{ adjective }} joke about {{ content }}',
template_format='jinja2',
validate_template=True
)
prompt_template.format(adjective="funny", content="chickens")
# -> Tell me a funny joke about chickens.
template = "I am learning langchain because {reason}."
# -> 'I am learning langchain because {reason}.'
提示模板是具有.format
方法的类,该方法接受键-值映射并返回字符串(提示),以传递给语言模型。
先获取某些变量
如:有一个需要两个变量foo和baz的提示模板。
如果在链条的早期就获取了foo值,但稍后才能获取了baz值,
那么等到在一个地方同时拥有两个变量 才将它们传递给提示模板可能会很麻烦。
相反,您可以使用foo值部分化提示模板,然后将部分化的提示模板传递下去,只需使用它即可。
代码如下:
prompt = PromptTemplate(template="{foo}{bar}",
input_variables=["foo", "bar"])
partial_prompt = prompt.partial(foo="foo");
partial_prompt
PromptTemplate(input_variables=['bar'], output_parser=None, partial_variables={'foo': 'foo'}, template='{foo}{bar}', template_format='f-string', validate_template=True)
partial_prompt.partial(foo="foo2") # 可移执行,修改无效;只能使用 partial,不能使用 format
PromptTemplate(input_variables=['bar'], output_parser=None, partial_variables={'foo': 'foo2'}, template='{foo}{bar}', template_format='f-string', validate_template=True)
partial_prompt.format(bar="baz")
'foobaz'
partial_prompt.partial(foo="foo2") # 可移执行,修改无效;只能使用 partial,不能使用 format
PromptTemplate(input_variables=['bar'], output_parser=None, partial_variables={'foo': 'foo2'}, template='{foo}{bar}', template_format='f-string', validate_template=True)
partial_prompt.format(bar="bar2") # 可以执行
'foobar2'
# 只使用部分变量初始化Prompt
prompt = PromptTemplate(template="{foo}{bar}",
input_variables=["bar"],
partial_variables={"foo": "foo"})
prompt.format(bar="baz")
foobaz
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.format(adjective="funny")
Tell me a funny joke about the day 04/07/2024, 14:08:22
# 使用部分变量初始化 Prompt
prompt = PromptTemplate(
template="Tell me a {adjective} joke about the day {date}",
input_variables=["adjective"],
partial_variables={"date": _get_datetime} #
);
prompt.format(adjective="funny")
'Tell me a funny joke about the day 04/07/2024, 14:09:11'
默认情况下,PromptTemplate
会通过检查 template
字符串中定义的变量是否与 input_variables
中的变量匹配来验证模板。
您可以通过将 validate_template
设置为 False
来禁用此行为。
prompt_template = PromptTemplate(template=template,
input_variables=["reason", "foo"]) # ValueError due to extra variables
会报错: ValidationError: 1 validation error for PromptTemplate
因为设置需要校验
prompt_template = PromptTemplate(template=template,
input_variables=["reason", "foo"],
validate_template=False) # 设置不校验,不会报错
PromptTemplate(input_variables=['reason', 'foo'], output_parser=None, partial_variables={}, template='I am learning langchain because {reason}.', template_format='f-string', validate_template=False)
基本上有两种不同的提示模板可用-字符串提示模板和聊天提示模板。
字符串提示模板提供一个简单的字符串格式提示,而聊天提示模板生成一个更结构化的提示,可用于与聊天API一起使用。
在本指南中,我们将使用字符串提示模板创建自定义提示。
要创建一个自定义的字符串提示模板,需要满足两个要求:
下例创建一个自定义的提示模板,它以函数名作为输入,并格式化提示以提供函数的源代码。
为了实现这一点,让我们首先创建一个根据函数名 返回 函数源代码的函数。
import inspect
def get_source_code(function_name):
# Get the source code of the function
return inspect.getsource(function_name)
接下来,我们将创建一个自定义提示模板,该模板将函数名称作为输入,并格式化提示模板 以提供函数的源代码。
from langchain.prompts import StringPromptTemplate
from pydantic import BaseModel, validator
class FunctionExplainerPromptTemplate(StringPromptTemplate, BaseModel):
"""A custom prompt template that takes in the function name as input, and formats the prompt template to provide the source code of the function."""
@validator("input_variables")
def validate_input_variables(cls, v):
"""Validate that the input variables are correct."""
if len(v) != 1 or "function_name" not in v:
raise ValueError("function_name must be the only input_variable.")
return v
def format(self, **kwargs) -> str:
# Get the source code of the function
source_code = get_source_code(kwargs["function_name"])
# Generate the prompt to be sent to the language model
prompt = f"""
Given the function name and source code, generate an English language explanation of the function.
Function Name: {kwargs["function_name"].__name__}
Source Code:
{source_code}
Explanation:
"""
return prompt
def _prompt_type(self):
return "function-explainer"
使用它来为我们的任务生成提示
fn_explainer = FunctionExplainerPromptTemplate(input_variables=["function_name"])
# 为函数"get_source_code"生成一个提示
prompt = fn_explainer.format(function_name=get_source_code)
print(prompt)
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
examples = [
{
"question": "Who lived longer, Muhammad Ali or Alan Turing?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
"""
},
{
"question": "When was the founder of craigslist born?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
"""
},
{
"question": "Who was the maternal grandfather of George Washington?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
"""
},
{
"question": "Are both the directors of Jaws and Casino Royale from the same country?",
"answer":
"""
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
"""
}
]
配置一个将少量示例 格式化为字符串的格式化程序。
该格式化程序应该是一个 PromptTemplate 对象。
example_prompt = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
print(example_prompt.format(**examples[0]))
Question: Who lived longer, Muhammad Ali or Alan Turing?
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
将示例和格式化程序提供给 FewShotPromptTemplate
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"]
)
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
PipelinePrompt 由两个主要部分组成:
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.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)
pipeline_prompt.input_variables
# -> ['example_a', 'person', 'example_q', 'input']
print(pipeline_prompt.format(
person="Elon Musk",
example_q="What's your favorite car?",
example_a="Telsa",
input="What's your favorite social media site?"
))
You are impersonating Elon Musk.
Here's an example of an interaction:
Q: What's your favorite car?
A: Telsa
Now, do this for real!
Q: What's your favorite social media site?
A:
我们不会直接将示例提供给 FewShotPromptTemplate 对象,而是将它们提供给一个 ExampleSelector 对象。
在本例中,我们将使用 SemanticSimilarityExampleSelector 类。该类根据输入与少量示例的相似性选择少量示例。
它使用嵌入模型计算输入与少量示例之间的相似性,以及向量存储执行最近邻搜索。
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples(
# This is the list of examples available to select from.
examples,
# This is the embedding class used to produce embeddings which are used to measure semantic similarity.
OpenAIEmbeddings(),
# This is the VectorStore class that is used to store the embeddings and do a similarity search over.
Chroma,
# This is the number of examples to produce.
k=1
)
# Select the most similar example to the input.
question = "Who was the father of Mary Ball Washington?"
selected_examples = example_selector.select_examples({"question": question})
print(f"Examples most similar to the input: {question}")
for example in selected_examples:
print("\n")
for k, v in example.items():
print(f"{k}: {v}")
示例选择器提供给 FewShotPromptTemplate
最后,创建一个 FewShotPromptTemplate 对象。该对象接受示例选择器和少量示例的格式化程序。
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"]
)
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
from langchain.chat_models import ChatOpenAI
from langchain import PromptTemplate, LLMChain
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import AIMessage, HumanMessage, SystemMessage
chat = ChatOpenAI(temperature=0)
template = "You are a helpful assistant that translates english to pirate."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
example_human = HumanMessagePromptTemplate.from_template("Hi")
example_ai = AIMessagePromptTemplate.from_template("Argh me mateys")
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages(
[system_message_prompt, example_human, example_ai, human_message_prompt]
)
chain = LLMChain(llm=chat, prompt=chat_prompt)
# get a chat completion from the formatted messages
chain.run("I love programming.")
# -> "I be lovin' programmin', me hearty!"
template = "You are a helpful assistant that translates english to pirate."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
example_human = SystemMessagePromptTemplate.from_template(
"Hi", additional_kwargs={"name": "example_user"}
)
example_ai = SystemMessagePromptTemplate.from_template(
"Argh me mateys", additional_kwargs={"name": "example_assistant"}
)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages(
[system_message_prompt, example_human, example_ai, human_message_prompt]
)
chain = LLMChain(llm=chat, prompt=chat_prompt)
# get a chat completion from the formatted messages
chain.run("I love programming.")
# -> "I be lovin' programmin', me hearty."
format_prompt
方法的输出可以作为字符串、消息列表和ChatPromptValue
使用。
output = chat_prompt.format(input_language="English",
output_language="French",
text="I love programming.")
output
# -> 'System: You are a helpful assistant that translates English to French.\nHuman: I love programming.'
下面代码和上面等效
output_2 = chat_prompt.format_prompt(input_language="English",
output_language="French",
text="I love programming.").to_string()
assert output == output_2
ChatPromptValue
chat_prompt.format_prompt(input_language="English",
output_language="French",
text="I love programming.")
ChatPromptValue(messages=[SystemMessage(content='You are a helpful assistant that translates English to French.',
additional_kwargs={}),
HumanMessage(content='I love programming.',
additional_kwargs={},
example=False)])
chat_prompt.format_prompt(input_language="English",
output_language="French",
text="I love programming.").to_messages()
[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}), HumanMessage(content='I love programming.', additional_kwargs={})]
https://www.langchain.com.cn/modules/prompts/output_parsers
输出解析器是帮助 结构化语言模型响应 的类。
有两种主要的方法,一个输出解析器必须实现:
get_format_instructions() -> str
:一个方法,返回一个包含有关 如何格式化语言模型输出 的字符串。parse(str) -> Any
:一个方法,接受一个字符串(假定为语言模型的响应) 并将其解析为某个结构。然后是一个可选的:
parse_with_prompt(str) -> Any
:一个方法,它接受一个字符串(假设是语言模型的响应)和一个提示(假设是生成这样的响应的提示),并将其解析为某种结构。提示在此大多数情况下是为了提供信息以便OutputParser重新尝试或以某种方式修复输出。在高层次上,序列化遵循以下设计原则:
还有一个单一入口点可以从磁盘加载提示,这样可以轻松加载任何类型的提示。
更多本地存储示例,可见:https://python.langchain.com.cn/docs/modules/model_io/prompts/prompt_templates/prompt_serialization
prompt_template.save("awesome_prompt.json")
查看文件
!cat awesome_prompt.json
内容如下
{
"input_variables": [
"reason",
"foo"
],
"output_parser": null,
"partial_variables": {},
"template": "I am learning langchain because {reason}.",
"template_format": "f-string",
"validate_template": false,
"_type": "prompt"
}
from langchain.prompts import load_prompt
loaded_prompt = load_prompt("awesome_prompt.json")
loaded_prompt
PromptTemplate(
input_variables=['reason', 'foo'],
output_parser=None,
partial_variables={},
template='I am learning langchain because {reason}.',
template_format='f-string',
validate_template=False
)
2024-04-08(一)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。