PromptTemplate 字符串提示模版

PromptTemplate的应用场景主要用于与LLM大模型生成单次请求的提示。这种模板适用于需要生成特定任务或查询的场景,例如转换文本风格、生成特定信息的文本、或者执行特定的文本分析任务。它更多地用于静态的、一次性的文本生成或文本处理任务。
它允许用户定义一个模板,其中可以包含占位符和指定的变量。当需要生成提示时,这些变量会被实际的数据替换,以形成完整的提示文本。
字符串提示模版最终形成的提示是以字符串形式存在的,在字符串模版中可以有多个占位符,每个占位符就是一个变量,后续可以将变量的位置替换成对应的字符串。
字符串提示模版,可以使用 f-strings(默认)或 jinja2 语法。
f-string,在Python中,f-strings是一种字符串格式化方法,可以方便地将变量插入到字符串中。F-string以字母”f”或”F”开头,后面跟着一对大括号,用于包含要插入的变量或表达式。大括号内可以使用变量、表达式或方法调用等Python代码。
jinja2,是Python下一个被广泛应用的模版引擎,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能。
推荐使用f-strings,f-strings提供了一种快速简洁的格式化方式,而jinja2则提供了更强大的逻辑控制能力。然而,出于安全考虑,如果模板来自不可信的源,推荐使用f-strings,因为jinja2模板可能会执行任意的Python代码。为了减少安全风险,从LangChain 0.0.329版本开始,jinja2模板将默认在一个沙盒环境中渲染,虽然这提供了一定程度的安全保护,但仍然建议慎用来自不信任来源的jinja2模板。

主要方法概览

方法名 介绍 返回类型 参数说明
init 构造方法 PromptTemplate
- input_variables (List[str], 必需):这是一个字符串列表,指定了模板中期望的变量名。这些变量是在模板字符串中被格式化时需要提供值的占位符。
- input_types (Dict[str, Any], 可选): 一个字典,映射模板中每个变量的名称到其期望的类型。这有助于在处理模板之前验证输入数据的类型。
- template (str, 必需):模板字符串本身。这是一个包含占位符的字符串,占位符将在调用format方法时被实际的值替换。
- template_format (Literal[‘f-string’, ‘jinja2’], 可选, 默认为’f-string’):指定模板使用的格式化语法。可以是Python的f-string格式或jinja2模板引擎语法。出于安全考虑,推荐使用f-string。
- partial_variables (Mapping[str, Union[str, Callable[[], str]]], 可选):一个映射,为模板中的一些变量提供部分或默认值。这些值可以是字符串或返回字符串的函数。在此处赋值的变量就不需要在input_variables中体现了
- output_parser (Optional[BaseOutputParser], 可选, 默认为None):一个输出解析器对象,用于解析调用语言模型后返回的输出。这允许对模型输出进行自定义处理。
- validate_template (bool, 可选, 默认为False):指定是否在实例化时验证模板字符串。启用验证可以确保模板字符串符合预期的格式,但可能会增加额外的性能开销。
from_template 类方法,从一个字符串模板加载提示模板。这是创建提示模板的推荐方式。 PromptTemplate
- template (str, 必需):要加载的模板字符串。
- template_format (str, 可选, 默认为’f-string’):模板的格式。可以是’f-string’或’jinja2’。
- partial_variables (Dict[str, Any], 可选):用于部分填充模板的变量字典。
- **kwargs (Any, 可选):其他任何关键字参数。
from_file 类方法,从文件加载提示模板。 PromptTemplate
- template_file (Union[str, Path], 必需): 包含提示模板的文件路径。
- input_variables (Optional[List[str]], 可选):最终提示模板期望的变量名称列表。此参数已弃用,因为from_file现在委托给from_template。
- **kwargs (Any, 可选):其他任何关键字参数。
format 对象方法,使用输入参数格式化提示模板,所有加载的模版都需要调用这个方法,对传入模版中每个变量的值。 str
- **kwargs (Any, 必需): 给提示模板中的参数赋值。
format_prompt 对象方法,与format效果一样,只是返回的类型不一样。
该方法返回的PromptValue对象可以输出str和message两种类型的格式
PromptValue
- **kwargs (Any, 必需): 给提示模板中的参数赋值。
partial 对象方法,可以对一个有多个变量的提示模版,进行多次赋值,format方法调用一次需要对所有的变量进行赋值。 BasePromptTemplate
- **kwargs (Any, 必需): 给提示模板中的参数赋值。

使用构造方法创建提示模版

  1. # 使用构造函数创建
  2. from langchain import PromptTemplate
  3. template = """\
  4. 秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。
  5. """
  6. prompt = PromptTemplate(input_variables=["product1","product2"], template=template)
  7. print(prompt.format(product1="LangChain", product2="AI"))
  8. print(prompt.format_prompt(product1="LangChain", product2="AI").to_messages())
  9. '''
  10. 代码执行后输出内容如下:
  11. 秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
  12. [HumanMessage(content='秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。\n')]
  13. '''

这种方式使用类PromptTemplate的构造函数直接创建一个实例。构造函数接受一个变量列表input_variables,这个列表明确指出了模板中将要使用的变量名称,以及一个template字符串,其中包含相应的变量占位符。
这种方式在input_variables提供了额外的变量明确性,因为它要求你在创建模板时就明确指定哪些变量将会被用于格式化,这可能有助于代码的可读性和后续的维护。
1、PromptTemplate构造方法中input_variables的参数为提示模版中的变量列表,可以写也可以不写,例如input_variables=[],都不影响format方法执行时对提示模版中的变量进行赋值。
2、format_prompt方法执行后输出的PromptValue对象,用于聊天模型交互,format方法执行输出的是字符串,用于LLM大模型交互。
3、format、format_prompt两个方法在格式化提示模版的时候,必须对所有的变量进行赋值,如果需要分步赋值,可以用partial方法赋值。

使用from_template方法创建提示模版

  1. # 使用from_template方法创建
  2. from langchain import PromptTemplate
  3. template = """\
  4. 秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。
  5. """
  6. prompt_multiple = PromptTemplate.from_template(template)
  7. print(prompt_multiple.format(product1="LangChain", product2="AI"))
  8. '''
  9. 代码执行后输出内容如下:
  10. 秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
  11. '''

from_template方法是类PromptTemplate方法,用于创建PromptTemplate的实例。这种方法直接接受一个模板字符串作为参数,其中模板字符串包含用大括号{}包裹的变量,这些变量在后续可以通过format方法被替换。
这种方式直观且易于使用,尤其是当你的模板字符串是静态的或者在编写代码时已知的。它允许你在一个步骤中定义模板,并在另一个步骤中填充具体的变量值。

使用from_file方法创建提示模版

  1. # 假设有一个名为"model_io_prompt.txt"的文件,与当前代码文件在相同目录下,其中包含模板字符串
  2. # 文件内容: "秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。"
  3. from langchain import PromptTemplate
  4. template_path = "model_io_prompt.txt"
  5. prompt_from_file = PromptTemplate.from_file(template_path)
  6. print(prompt_from_file.format(product1="LangChain", product2="AI"))
  7. '''
  8. 代码执行后输出内容如下:
  9. 秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
  10. '''

from_file方法是类PromptTemplate的方法,用于从文件中创建PromptTemplate的实例。这个方法接受一个文件路径作为参数,该文件包含模板字符串,其中的变量用大括号{}包裹,这些变量后续可以通过format方法被替换。
这种方法非常适合于模板内容比较大或者需要频繁更改的场景,因为它允许将模板内容与代码逻辑分离,使得维护更加方便。此外,从文件中加载模板也使得在不同的项目或环境中重用模板变得简单。

partial 方法用于提示模版分多次赋值

partial是BasePromptTemplate的一个方法,继承BasePromptTemplate类的所有子类,都有这个方法,该方法执行完后返回的是BasePromptTemplate对象。
partial方法的主要用途是解决复杂 prompt 提示中含有多个变量,部分变量先赋值,剩余部分在后续逐步赋值,赋值的次数可以为多次,但是最后一步必须执行format方法。

字符串多次赋值
  1. # 初始化模板,其中包含了两个变量:product1和product2
  2. from langchain import PromptTemplate
  3. template_str = "秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。"
  4. prompt = PromptTemplate.from_template(template_str)
  5. # 对模板进行partial处理,先填充product1变量
  6. partial_prompt = prompt.partial(product1="langchain")
  7. print(partial_prompt)
  8. # 使用partial处理后的模板,赋值剩余的product2变量
  9. # 最后一步赋值操作需要用format方法
  10. final_statement = partial_prompt.format(product2="AI")
  11. print(final_statement)
  12. '''
  13. 代码执行后输出内容如下:
  14. input_variables=['product2'] partial_variables={'product1': 'langchain'} template='秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。'
  15. 秋水札记,定位于 langchain AI 编程推广,分享 AI 商业与技术。
  16. '''

带字符串的partial使用是最常见的,尤其是当某些变量提前获得而其他变量稍后获得时。在上方代码示例中,提示模板需要两个变量 product1 和 product2 。如果你提前获得了 product1 值,但是 product2 值稍后才获得,此时不需要等到两个变量同时赋值给提示模板。相反,你可以使用 product1 值对提示模板进行 partial 处理,然后继续后续的赋值操作,直到提示模版中的变量全部赋值结束。
partial 方法执行后返回的 BasePromptTemplate 对象,如果需要输出 prompt 提示 ,最后还是需要执行 format 或 format_prompt 方法。

函数调用赋值
  1. from langchain.prompts import PromptTemplate
  2. def get_product_name():
  3. # 这里的逻辑可以根据实际情况动态决定product2的值
  4. # 为了示例,我们直接返回"AI"
  5. return "AI"
  6. # 更新模板字符串以包含三个参数,并预先为product3赋值
  7. prompt = PromptTemplate(
  8. template="{product3},定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。",
  9. input_variables=["product1", "product2"],
  10. partial_variables={"product3": "秋水札记"} # 在构造方法中预先为product3赋值
  11. )
  12. # 使用函数Partial处理,这里我们假设product1始终为"LangChain"
  13. partial_prompt = prompt.partial(product1="LangChain", product2=get_product_name)
  14. # 格式化时,我们不需要再传递任何变量,因为它们已通过Partial处理被填充
  15. final_statement = partial_prompt.format()
  16. print(final_statement)
  17. '''
  18. 代码执行后输出内容如下:
  19. 秋水札记,定位于 langchain AI 编程推广,分享 AI 商业与技术。
  20. '''

在上方示例中,我们通过 partial_variables 参数在构造 PromptTemplate 对象时预先为 product3 变量赋值为”秋水札记”。product2 根据当前的某些条件动态决定,所以动态决定的过程就放在函数里执行,函数名可以直接在执行partial方法时的作为参数值。在 format 方法中,不能直接使用函数名作为参数。应先调用函数并将返回结果赋值给一个变量,然后再将这个变量传递给 format 方法。
可以直接在 partial 方法或者构造函数 partial_variables 对应的参数赋值处填写函数名,进行直接调用。但是 format 方法是不可以直接调用,需要先将函数返回结果赋值给一个变量,在将变量赋值给 format 方法对应的参数。