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, 必需): 给提示模板中的参数赋值。 |
使用构造方法创建提示模版
# 使用构造函数创建
from langchain import PromptTemplate
template = """\
秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。
"""
prompt = PromptTemplate(input_variables=["product1","product2"], template=template)
print(prompt.format(product1="LangChain", product2="AI"))
print(prompt.format_prompt(product1="LangChain", product2="AI").to_messages())
'''
代码执行后输出内容如下:
秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
[HumanMessage(content='秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。\n')]
'''
这种方式使用类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方法创建提示模版
# 使用from_template方法创建
from langchain import PromptTemplate
template = """\
秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。
"""
prompt_multiple = PromptTemplate.from_template(template)
print(prompt_multiple.format(product1="LangChain", product2="AI"))
'''
代码执行后输出内容如下:
秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
'''
from_template方法是类PromptTemplate方法,用于创建PromptTemplate的实例。这种方法直接接受一个模板字符串作为参数,其中模板字符串包含用大括号{}包裹的变量,这些变量在后续可以通过format方法被替换。
这种方式直观且易于使用,尤其是当你的模板字符串是静态的或者在编写代码时已知的。它允许你在一个步骤中定义模板,并在另一个步骤中填充具体的变量值。
使用from_file方法创建提示模版
# 假设有一个名为"model_io_prompt.txt"的文件,与当前代码文件在相同目录下,其中包含模板字符串
# 文件内容: "秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。"
from langchain import PromptTemplate
template_path = "model_io_prompt.txt"
prompt_from_file = PromptTemplate.from_file(template_path)
print(prompt_from_file.format(product1="LangChain", product2="AI"))
'''
代码执行后输出内容如下:
秋水札记,定位于 LangChain AI 编程推广,分享 AI 商业与技术。
'''
from_file方法是类PromptTemplate的方法,用于从文件中创建PromptTemplate的实例。这个方法接受一个文件路径作为参数,该文件包含模板字符串,其中的变量用大括号{}包裹,这些变量后续可以通过format方法被替换。
这种方法非常适合于模板内容比较大或者需要频繁更改的场景,因为它允许将模板内容与代码逻辑分离,使得维护更加方便。此外,从文件中加载模板也使得在不同的项目或环境中重用模板变得简单。
partial 方法用于提示模版分多次赋值
partial是BasePromptTemplate的一个方法,继承BasePromptTemplate类的所有子类,都有这个方法,该方法执行完后返回的是BasePromptTemplate对象。
partial方法的主要用途是解决复杂 prompt 提示中含有多个变量,部分变量先赋值,剩余部分在后续逐步赋值,赋值的次数可以为多次,但是最后一步必须执行format方法。
字符串多次赋值
# 初始化模板,其中包含了两个变量:product1和product2
from langchain import PromptTemplate
template_str = "秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。"
prompt = PromptTemplate.from_template(template_str)
# 对模板进行partial处理,先填充product1变量
partial_prompt = prompt.partial(product1="langchain")
print(partial_prompt)
# 使用partial处理后的模板,赋值剩余的product2变量
# 最后一步赋值操作需要用format方法
final_statement = partial_prompt.format(product2="AI")
print(final_statement)
'''
代码执行后输出内容如下:
input_variables=['product2'] partial_variables={'product1': 'langchain'} template='秋水札记,定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。'
秋水札记,定位于 langchain AI 编程推广,分享 AI 商业与技术。
'''
带字符串的partial使用是最常见的,尤其是当某些变量提前获得而其他变量稍后获得时。在上方代码示例中,提示模板需要两个变量 product1 和 product2 。如果你提前获得了 product1 值,但是 product2 值稍后才获得,此时不需要等到两个变量同时赋值给提示模板。相反,你可以使用 product1 值对提示模板进行 partial 处理,然后继续后续的赋值操作,直到提示模版中的变量全部赋值结束。
partial 方法执行后返回的 BasePromptTemplate 对象,如果需要输出 prompt 提示 ,最后还是需要执行 format 或 format_prompt 方法。
函数调用赋值
from langchain.prompts import PromptTemplate
def get_product_name():
# 这里的逻辑可以根据实际情况动态决定product2的值
# 为了示例,我们直接返回"AI"
return "AI"
# 更新模板字符串以包含三个参数,并预先为product3赋值
prompt = PromptTemplate(
template="{product3},定位于 {product1} AI 编程推广,分享 {product2} 商业与技术。",
input_variables=["product1", "product2"],
partial_variables={"product3": "秋水札记"} # 在构造方法中预先为product3赋值
)
# 使用函数Partial处理,这里我们假设product1始终为"LangChain"
partial_prompt = prompt.partial(product1="LangChain", product2=get_product_name)
# 格式化时,我们不需要再传递任何变量,因为它们已通过Partial处理被填充
final_statement = partial_prompt.format()
print(final_statement)
'''
代码执行后输出内容如下:
秋水札记,定位于 langchain AI 编程推广,分享 AI 商业与技术。
'''
在上方示例中,我们通过 partial_variables 参数在构造 PromptTemplate 对象时预先为 product3 变量赋值为”秋水札记”。product2 根据当前的某些条件动态决定,所以动态决定的过程就放在函数里执行,函数名可以直接在执行partial方法时的作为参数值。在 format 方法中,不能直接使用函数名作为参数。应先调用函数并将返回结果赋值给一个变量,然后再将这个变量传递给 format 方法。
可以直接在 partial 方法或者构造函数 partial_variables 对应的参数赋值处填写函数名,进行直接调用。但是 format 方法是不可以直接调用,需要先将函数返回结果赋值给一个变量,在将变量赋值给 format 方法对应的参数。