当前位置:   article > 正文

大模型从入门到应用——LangChain:提示(Prompts)-[提示模板:基础知识]_prompt jinja2

prompt jinja2

分类目录:《大模型从入门到应用》总目录

LangChain系列文章:


语言模型以文本作为输入,这段文本通常被称为提示(Prompt)。通常情况下,这不仅仅是一个硬编码的字符串,而是模板、示例和用户输入的组合。LangChain提供了多个类和函数,以便轻松构建和处理提示。

提示模板的概念

提示模板是指一种可复制的生成提示的方式。它包含一个文本字符串(模板),可以从最终用户处接收一组参数并生成提示。提示模板可能包含以下内容:

  • 对语言模型的指令
  • 少量示例,以帮助语言模型生成更好的回复
  • 对语言模型的问题

以下代码片段是包含了一个提示模板的示例:

from langchain import PromptTemplate

template = """
我希望你能充当新公司的命名顾问。
一个生产{product}的公司的好名字是什么?
"""

prompt = PromptTemplate(
    input_variables=["product"],
    template=template,
)
prompt.format(product="彩色袜子")
# -> 我希望你能充当新公司的命名顾问。
# -> 一个生产彩色袜子的公司的好名字是什么?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

创建提示模板

我们可以使用PromptTemplate类创建简单的硬编码提示。提示模板可以接受任意数量的输入变量,并且可以进行格式化以生成提示。

from langchain import PromptTemplate
  • 1
# 没有输入变量的提示示例
no_input_prompt = PromptTemplate(input_variables=[], template="给我讲个笑话。")
no_input_prompt.format()
# -> "给我讲个笑话。"

# 一个输入变量的提示示例
one_input_prompt = PromptTemplate(input_variables=["adjective"], template="给我讲个{adjective}的笑话。")
one_input_prompt.format(adjective="有趣的")
# -> "给我讲个有趣的笑话。"

# 多个输入变量的示例提示
multiple_input_prompt = PromptTemplate(
    input_variables=["adjective", "content"], 
    template="给我讲一个{adjective}的关于{content}的笑话。"
)
multiple_input_prompt.format(adjective="有趣的", content="小鸡")
# -> "给我讲一个有趣的关于小鸡的笑话。"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

如果我们不想手动指定input_variables,还可以使用from_template类方法创建PromptTemplate。LangChain将根据传递的template自动推断input_variables

template = "给我讲一个{adjective}的关于{content}的笑话。"
prompt_template = PromptTemplate.from_template(template)
prompt_template.input_variables
# -> ['adjective', 'content']
prompt_template.format(adjective="有趣的", content="小鸡")
# -> 给我讲一个有趣的关于小鸡的笑话。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们可以创建自定义的提示模板,以任何您想要的方式格式化提示。

模板格式

默认情况下,PromptTemplate将提供的模板视为Python f-string。我们可以通过template_format参数指定其他模板格式:

# 在运行此代码之前,请确保已安装jinja2

jinja2_template = "告诉我一个{{ adjective }}的笑话,关于{{ content }}"
prompt_template = PromptTemplate.from_template(template=jinja2_template, template_format="jinja2")

prompt_template.format(adjective="有趣的", content="鸡")
# -> 告诉我一个有趣的笑话,关于鸡
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

目前,PromptTemplate仅支持jinja2f-string模板格式。如果您希望使用其他模板格式,我们可以在GitHub页面上提交需求。

验证模板

默认情况下,PromptTemplate将通过检查input_variables是否与模板中定义的变量匹配来验证template字符串。您可以通过将validate_template设置为False来禁用此行为。

template = "我正在学习LangChain,因为{reason}。"

prompt_template = PromptTemplate(template=template, input_variables=["reason", "foo"])  # 由于存在额外的变量而引发ValueError
prompt_template = PromptTemplate(template=template, input_variables=["reason", "foo"], validate_template=False)  # 不会引发错误
  • 1
  • 2
  • 3
  • 4

序列化模板

我们可以将PromptTemplate保存到本地文件系统中的文件中。LangChain将通过文件扩展名自动推断文件格式。目前,LangChain支持将模板保存为YAML和JSON文件。

prompt_template.save("awesome_prompt.json")  # 保存为JSON文件
from langchain.prompts import load_prompt
loaded_prompt = load_prompt("awesome_prompt.json")

assert prompt_template == loaded_prompt
  • 1
  • 2
  • 3
  • 4
  • 5

LangChain还支持从LangChainHub加载提示模板,其中包含一系列我们可以在项目中使用的有用提示。

from langchain.prompts import load_prompt

prompt = load_prompt("lc://prompts/conversation/prompt.json")
prompt.format(history="", input="1 + 1等于多少?")
  • 1
  • 2
  • 3
  • 4

向模板添加Few Shot示例

Few Shot示例是一组可以帮助语言模型生成更好响应的示例。要使用Few Shot示例生成提示,可以使用FewShotPromptTemplate。此类接受PromptTemplate和Few Shot示例列表。然后,它使用Few Shot示例格式化提示模板。

在下面示例中,我们将创建一个生成单词反义词的提示。

from langchain import PromptTemplate, FewShotPromptTemplate

# 首先,创建Few Shot示例列表
examples = [
    {"word": "happy", "antonym": "sad"},
    {"word": "tall", "antonym": "short"},
]

# 接下来,我们指定用于格式化示例的模板。
# 我们使用`PromptTemplate`类来实现这个目的。
example_formatter_template = """Word: {word}
Antonym: {antonym}
"""

example_prompt = PromptTemplate(
    input_variables=["word", "antonym"],
    template=example_formatter_template,
)

# 最后,创建`FewShotPromptTemplate`对象。
few_shot_prompt = FewShotPromptTemplate(
    # 这些是我们要插入到提示中的示例。
    examples=examples,
    # 这是我们在将示例插入到提示中时要使用的格式。
    example_prompt=example_prompt,
    # 前缀是出现在提示中示例之前的一些文本。
    # 通常,这包括一些说明。
    prefix="Give the antonym of every input\n",
    # 后缀是出现在提示中示例之后的一些文本。
    # 通常,这是用户输入的地方。
    suffix="Word: {input}\nAntonym: ",
    # 输入变量是整个提示期望的变量。
    input_variables=["input"],
    # 示例分隔符是我们将前缀、示例和后缀连接在一起的字符串。
    example_separator="\n",
)

# 现在,我们可以使用`format`方法生成一个提示。
print(few_shot_prompt.format(input="big"))
# -> Give the antonym of every input
# -> 
# -> Word: happy
# -> Antonym: sad
# ->
# -> Word: tall
# -> Antonym: short
# ->
# -> Word: big
# -> Antonym:
  • 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
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

选择用于提示模板的示例

如果您有大量示例,可以使用ExampleSelector选择一部分对语言模型来说最具信息量的示例。这将帮助您生成更有可能获得良好回应的提示。下面,我们将使用LengthBasedExampleSelector,它根据输入的长度选择示例。当我们担心构建的提示会超过上下文窗口的长度时,这将非常有用。对于较长的输入,它会选择较少的示例进行包含,而对于较短的输入,它会选择更多的示例。我们将继续使用前面部分的示例,但这次我们将使用LengthBasedExampleSelector来选择示例。

from langchain.prompts.example_selector import LengthBasedExampleSelector

# 这里是一些虚构任务的大量示例,该任务是创建反义词。
examples = [
    {"word": "happy", "antonym": "sad"},
    {"word": "tall", "antonym": "short"},
    {"word": "energetic", "antonym": "lethargic"},
    {"word": "sunny", "antonym": "gloomy"},
    {"word": "windy", "antonym": "calm"},
]

# 我们将使用`LengthBasedExampleSelector`来选择示例。
example_selector = LengthBasedExampleSelector(
    # 这些是可供选择的示例。
    examples=examples, 
    # 这是用于格式化示例的PromptTemplate。
    example_prompt=example_prompt, 
    # 这是格式化示例的最大长度。
    max_length=25
    # 这是用于获取字符串长度的函数,用于确定包含哪些示例。在这里被注释掉,因为如果没有指定,默认提供了该函数。
    # get_text_length: Callable[[str], int] = lambda x: len(re.split("\n| ", x))
)

# 现在,我们可以使用`example_selector`创建`FewShotPromptTemplate`。
dynamic_prompt = FewShotPromptTemplate(
    # 我们提供一个ExampleSelector而不是示例。
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个输入的反义词",
    suffix="单词:{input}\n反义词:",
    input_variables=["input"],
    example_separator="\n\n",
)

# 现在,我们可以使用`format`方法生成提示。
print(dynamic_prompt.format(input="big"))
# -> 给出每个输入的反义词
# ->
# -> 单词:happy
# -> 反义词:sad
# ->
# -> 单词:tall
# -> 反义词:short
# ->
# -> 单词:energetic
# -> 反义词:lethargic
# ->
# -> 单词:sunny
# -> 反义词:gloomy
# ->
# -> 单词:windy
# -> 反义词:平静
```python
print(dynamic_prompt.format(input="big"))
# -> 给出每个输入的反义词
# ->
# -> 单词:happy
# -> 反义词:sad
# ->
# -> 单词:tall
# -> 反义词:short
# ->
# -> 单词:energetic
# -> 反义词:lethargic
# ->
# -> 单词:sunny
# -> 反义词:gloomy
# ->
# -> 单词:windy
# -> 反义词:calm
# ->
# -> 单词:big
# -> 反义词:平静
相反,如果我们提供一个非常长的输入,LengthBasedExampleSelector会选择较少的示例包含在提示中。

long_string = "big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else"
print(dynamic_prompt.format(input=long_string))
# -> 给出每个输入的反义词
# ->
# -> 单词:happy
# -> 反义词:sad
# ->
# -> 单词:big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else
# -> 反义词:平静
  • 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
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

LangChain附带了一些示例选择器供我们使用,有关如何使用示例选择器,可以参考《自然语言处理从入门到应用——LangChain:提示(Prompts)》系列的后续文章。除此之外,我们还可以创建自定义示例选择器,根据我们想要的任何条件选择示例。

参考文献:
[1] LangChain

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/1000807
推荐阅读
相关标签