langchain核心组件 Model I/O(2)-Prompt Template

9 阅读6分钟

2.4 Prompt Template

2.4.1 提示词模板介绍

在应用开发中,固定的提示词限制了模型的灵活性和适用范围。所以,Prompt Template 是一个模板化的字符串,我们可以将变量插入到模板中,从而创建出不同的提示。Prompt Template 接收用户输入,返回一个传递给 LLM 的信息(即提示词 prompt)。 提示模板以字典作为输入,其中每个键代表要填充的提示模板中的变量。并输出一个 PromptValue。这个 PromptValue 可以传递给聊天模型,也可以转换为字符串或消息列表。 PromptValue 存在的目的是为了方便在字符串和消息之间切换。 有多种类型的提示模板,常用的有 PromptTemplate(字符串提示模板)和 ChatPromptTemplate(聊天提示模板)。

2.4.2 复习:str.format()

Python的str.format()方法是一种字符串格式化的手段,允许在字符串中插入变量。使用这种方法,可以创建包含占位符的字符串模板,占位符由花括号{}标识。 调用format()方法时,可以传入一个或多个参数,这些参数将被顺序替换进占位符中。 str.format()提供了灵活的方式来构造字符串,支持多种格式化选项。 在LangChain的默认设置下,PromptTemplate使用Python的str.format()方法进行模板化。这样在模型接收输入前,可以根据需要对数据进行预处理和结构化。

基本用法

# 简单示例,直接替换
greeting = "Hello, {}!".format("Alice")
print(greeting)
# 输出: Hello, Alice!

带有位置参数的用法

# 简单示例,直接替换
greeting = "Hello, {}!".format("Alice")
print(greeting)
# 输出: Hello, Alice!

输出:Name:Jerry,Age:25

带有关键字参数的用法

info = "Name: {0}, Age: {1}".format("Jerry", 25)
print(info)
# 输出:Name: Jerry, Age: 25

使用字典解包的方式

使用字典解包  
person = {"name": "David", "age": 40}  
info = "Name: {name}, Age: {age}" .format(**person)  
print(info)  
#输出:Name: David, Age: 40

2.4.3 PromptTemplate

PromptTemplate 用于快速构建包含变量的提示词模板,并通过传入不同的参数值生成自定义的提示词。

参数
template提示模板,包括变量占位符
input_variables需要将其值作为提示输入的变量名称列表
partial_variables提示模板携带的部分变量的字典。使用部分变量预先填充模板,无需后续在每次调用时再传递这些变量
方法
format()使用输入格式化提示

2.4.3.1 实例化

方式1:使用构造方法实例化提示词模板

from langchain_core.prompts import PromptTemplate   
# 使用构造方法实例化提示词模板   
template = PromptTemplate(
    template="请评价{product}的优缺点,包括{aspect1}和{aspect2}。",
    input_variables=["product", "aspect1", "aspect2"],

)
# 使用模板生成提示词 
prompt_1=template.format(product="智能手机", 
aspect1="电池续航", 
aspect2="拍照质量"

prompt_2 = template.format(product=("笔记本电脑", aspect1="处理速度", aspect2="便携性")

print(prompt_1) # 请评价智能手机的优缺点,包括电池续航和拍照质量。  
print(prompt_2) # 请评价笔记本电脑的优缺点,包括处理速度和便携性。

方式2:使用from_template方法实例化提示词模板

from langchain_core.prompts import PromptTemplate
# 使用 from_template 方法实例化提示词模板
template = PromptTemplate.from_template("请给我一个关于{topic}的 {type}解释。")
使用模板生成提示  
prompt = template.format(type="详细", topic="量子力学")  
print(prompt) # 请给我一个关于量子力学的详细解释。

2.4.3.2 部分提示模版

在生成提示之前可以赋予部分变量默认值。

方式1:实例化过程中指定partial_variables参数

from langchain_core.prompts import PromptTemplate   
template   =   PromptTemplate( template   \coloneqq   {"foo} {bar}", input_variables   \coloneqq   ["foo", "bar"], partial_variables   \coloneqq   {"foo": "hello"}, #预先定义部分变量   
prompt   =   template.format(bar="world")   
print(prompt) # hello world

方式2:使用partial方法指定默认值

from langchain_core.prompts import PromptTemplate   
template = PromptTemplate.from_template({foo} {bar})   
partial_template = template.full(foo="hello") #预先定义部分变量   
prompt   =   partial_template.format(bar="world")   
print(prompt) # hello world

2.4.3.3 调用方式

除了format方法,也可以使用invoke方法调用。

invoke 方法返回 PromptValue 对象,可以使用 to_string 方法将其转换为字符串。

举例:invoke 方法调用

from langchain_core.prompts import PromptTemplate
template = PromptTemplate.from_template("{foo} {bar}")
prompt = template.invoke({"foo": "hello", "bar": "world"})
print(prompt, type(prompt))
# text='hello world' <class 'langchain_core.prompt_values.StringPromptValue'>
prompt_str = prompt.to_string()
print(prompt_str, type(prompt_str))
# hello world <class 'str'>

2.4.4 ChatPromptTemplate

ChatPromptTemplate 是创建聊天消息列表的提示模板。相较于普通 PromptTemplate 更适合处理多角色、多轮次的对话场景。支持 System/Human.AI 等不同角色的消息模板。

2.4.4.1 实例化

ChatPromptTemplate 可以通过构造方法或 frommessages 方法来实例化提示词模板。

实例化时需要传入 messages 参数,messages 参数支持如下格式:

tuple构成的列表,格式为[(role, content)]

dict构成的列表,格式为[{"role":..., "content":...}]

Message 类构成的列表

举例:

from langchain_core.prompts import ChatPromptTemplate
template = ChatPromptTemplate(
    [
        ("system", "你是一个AI开发工程师,你的名字是{name}。"),
        ("human", "你能帮我做什么?"),
        ("ai", "我能开发很多{thing}。"),
        ("human", "{user_input}"),
    ]
)
prompt = template.format_messages(name="AI", thing="AI", user_input="行")
print(prompt)
# [
# SystemMessage(content="你是一个AI开发工程师,你的名字是AI。",...),
# HumanMessage(content="你能帮我做什么?", ...),
# AIMessage(content="我能开发很多AI。", ...),
# HumanMessage(content="行", ...),

2.4.4.2 调用方式

推荐使用 from_messages 方法或 invoke 方法调用。

举例:invoke 方法调用

from langchain_core.prompts import ChatPromptTemplate

 

template = ChatPromptTemplate(
    [
        ("system", "你是一个AI开发工程师,你的名字是{name}。"),
        ("human", "你能帮我做什么?"),
        ("ai", "我能开发很多{thing}。"),
        ("human", "{user_input}"),
    ]
)
prompt = template.invoke({"name": "AI", "thing": "AI", "user_input": "行"})
print(prompt)
# messages=[
# SystemMessage(content="你是一个AI开发工程师,你的名字是AI。",...),
# HumanMessage(content="你能帮我做什么?", ...),
# AIMessage(content="我能开发很多AI。", ...),
# HumanMessage(content="行", ...),

# ]

2.4.4.3 消息占位符

当希望在格式化过程中插入消息列表时,比如 Agent 暂存中间步骤,需要使用 MessagesPLACEHolder,负责在特定位置添加消息列表。

举例:

from langchain_core.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages(
    [
        ("system", "你是一个助手。"),
        ("placeholder", "{conversation}"),
        # 等同于 MessagesPlaceholder(variable_name="conversation", optional=True)
    ]
)
prompt = template.format_messages(
    conversation=[
    ("human", "你好!"),
        ("ai", "想让我帮你做些什么?"),
        ("human", "能帮我做一个冰淇凌吗?"),
        ("ai", "不能"),
    ]
)
print(prompt)
# [
#     SystemMessage(content="你是一个助手。", ...),
#     HumanMessage(content="你好!", ...),
#     AIMessage(content="想让我帮你做些什么?", ...),
#     HumanMessage(content="能帮我做一个冰淇凌吗?", ...),
#     AIMessage(content="不能", ...),
# ]

2.4.4.4 多模态提示词

可以使用提示模板来格式化多模态输入,比如将图片链接作为输入。

举例:

import os
from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate 
llm = init_chat_model(
    model="google/gemini-2.0-flash-exp:free",
    model_provider="openai",
    base_url="https://openrouter.ai/api/v1",
    api_key=os.getenv("OPENROUTER_API_KEY"),
)
template = ChatPromptTemplate(
    [
        {"role": "system", "content": "用中文简短描述图片内容"},
        {"role": "user", "content": [{"image_url": "{image_url}"}]},
    ]
) 
prompt = template.format_messages(    image_url="https://img2.baidu.com/it/u=2976763563,2523722948&fm=253&app=138&f=JPEG?w=800&h=1200"
)
resp = llm.invoke(prompt)
print(resp.content)  # 图片中是...

2.4.5 外部加载 Prompt

可以将 prompt 保存为 JSON 或者 YAML 等格式的文件,通过读取指定路径的格式化文件,获取相应的 prompt。这样方便对 prompt 进行管理和维护。

2.4.5.1 json格式提示词

prompts 目录下创建 json 文件:prompt.json

{
    "_type": "prompt",
    "input_variables": ["name", "what"]
    ,
    "template": "请{name}讲一个{what}的故事"
}
from langchain_core.prompts import load_prompt 
template=load_prompt("prompts/prompt.json", encoding="utf-8") print/template.format(name = "张三",what="搞笑的"))

请张三讲一个搞笑的故事

2.4.5.2 yaml 格式提示词

prompts目录下创建yaml文件:prompt.yaml

_type:"prompt" input_variables: ["name", "what"] template:"请{name}讲一个{what}的故事"

代码:

from langchain_core.prompts import load_prompt  
template = load_prompt("prompts/prompt.yaml", encoding="utf-8")  
print template.format(name="年轻人", what="滑稽"))  
# 请年轻人讲一个滑稽的故事