PromptTemplate

同一套客服话术里,城市名、用户名、检索片段每次不同,把字符串拼进 f-string 很快无法维护,也难做单元测试。PromptTemplate / ChatPromptTemplate 把「模板 + 变量 dict」变成 Runnable:左侧进变量,右侧出格式化后的 messages 或字符串。

段末注释PromptTemplate = 带占位符的提示词模板;ChatPromptTemplate 专用于 Chat 场景,输出 message 列表。


1. 一句话定位

维度 内容
角色 能力层提示组装:变量 → 结构化 prompt
输入 → 输出 dict(变量名→值)→ PromptValue / list[BaseMessage]
典型调用入口 prompt.invoke({"city": "北京"})prompt | model
与 LangGraph 节点内可先 invoke prompt 再调 model;状态驱动动态 prompt 常用 middleware

2. 实现逻辑

Chat 场景典型 LCEL:

1
2
3
4
5
6
1. 定义 ChatPromptTemplate.from_messages([("system", "..."), ("human", "{question}")])
2. chain = prompt | model | StrOutputParser()
3. chain.invoke({"question": "1+1=?"})
→ prompt 步:{"question"} 填入 → [SystemMessage, HumanMessage]
→ model 步:AIMessage
→ parser 步:str

字段级变形

1
2
3
{"city": "上海", "context": "文档A..."}
→ prompt.invoke
[SystemMessage(content="你是助手"), HumanMessage(content="根据:文档A...\n问:上海天气")]

3. 原理说明

3.1 PromptTemplate vs ChatPromptTemplate

PromptTemplate(数据类)
功能:单字符串模板,适合 completion 型 LLM。
数据结构:template: str(必填);input_variables: list[str](可从 { } 推断);partial_variables: dict = {}template_format="f-string"
最小维度:template 非空;input_variables 可为 [](无占位符)。

1
2
from langchain_core.prompts import PromptTemplate
PromptTemplate.from_template("用{lang}翻译:{text}") # 2 个变量

ChatPromptTemplate(数据类)
功能:多轮角色模板,invoke 产出 Chat Prompt Value(可 .to_messages()),对接 ChatModel。
默认值:无系统消息时只有你提供的角色。
最小维度:from_messages 的 list len ≥ 1

1
ChatPromptTemplate.from_messages([("human", "{q}")])

3.2 from_messages 元组语法

ChatPromptTemplate.from_messages(messages)(类方法)
功能:用 (role, template) 或 Message 对象组模板。role 常用 "system" / "human" / "ai"
最小维度:至少 1 条;占位符名须与 invoke 的 dict 键一致。

MessagesPlaceholder(数据类)
功能:把已有 list[BaseMessage] 插入模板(多轮历史)。

字段 类型 默认值 最小维度
variable_name str 必填 非空,如 "history"
optional bool False False 时缺键报错
n_messages int / None None None=全部;截断时 ≥1
1
2
3
4
5
6
from langchain_core.prompts import MessagesPlaceholder
ChatPromptTemplate.from_messages([
("system", "{role}"),
MessagesPlaceholder("history"),
("human", "{input}"),
])

3.3 Partial 与默认值

partial(**kwargs)(方法)
功能:预填部分变量,返回新模板。剩余变量在 invoke 时传入。
默认值:未 partial 的变量仍必填。
最小维度:至少 1 个关键字;值须能填进对应 {占位符}

1
prompt.partial(lang="中文").invoke({"province": "浙江"})

3.4 Runnable 语义

Prompt 实现 Runnableinvoke(dict) → ChatPromptValue| model 时左输出须与 ChatModel 输入兼容。stream 在 prompt 上通常一次产出完整 messages,流式发生在下游 model。
最小维度:invoke 的 dict 必须覆盖全部未 partial 的 input_variables(少一个 KeyError)。


4. 最小可运行示例

1
pip install -U langchain-openai
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
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
("system", "用{lang}回答,只答事实,一句话。"),
("human", "{province}的省会是哪座城市?"),
]).partial(lang="中文")

model = ChatOpenAI(
model="qwen3.5:9b",
api_key="ollama",
base_url="http://localhost:11434/v1",
temperature=0,
)

# 1) 只跑 prompt:看 messages 怎么拼
msgs = prompt.invoke({"province": "浙江"})
print([m.type for m in msgs.to_messages()], msgs.to_messages()[-1].content)
# 预期:['system', 'human'] 且 human 含「浙江」

# 2) 接模型:prompt | model | parser
chain = prompt | model | StrOutputParser()
print(chain.invoke({"province": "浙江"}))
# 预期形态:含「杭州」

重要配置参数

参数(API 名) 类型 / 默认值 功能说明 作用与影响 参考起点 配置指导
input_variables list[str],可推断 声明模板里必须由 invoke dict 提供的占位符名 缺键 KeyError;多写无害 与模板 { } 一致 与 invoke 键逐字相同
template / messages str 或 list,必填 提示正文或角色消息列表 过长费 token;system 决定角色与格式 短 system + 明确 human system 写角色与输出格式
partial_variables dict,默认 {} 创建时预填部分变量,invoke 不必再传 减少调用方传参;改值须重新 partial 固定语言、日期 动态输入不要 partial
MessagesPlaceholder 对象,可选 把已有 list[BaseMessage] 插入模板指定位置 缺历史且 optional=False 则报错 变量名 history 多轮配合 MessageHistory
validate_template bool,默认 True 构造时检查 { } 与 input_variables 是否对齐 False 则把错误推迟到 invoke True 动态拼模板才关
output_parser(链上) Parser 把 model 输出收成 str/JSON 等 类型选错则下游拿到错误形态 StrOutputParser 结构化用 with_structured_output

5. 易踩坑

  1. 变量名与 {} 不一致{question} 与 invoke 键 query 不匹配会 KeyError。
  2. 把 RAG context 不转义直接拼进模板:若 context 含 { 会被当占位符;用 PromptTemplate 的 escape 或单独 message 字段。
  3. Chat 模型仍用纯 PromptTemplate 单字符串:可行但丢失 system/user 分界;优先 ChatPromptTemplate。

小结

  • ChatPromptTemplate 输出 messages,是 prompt | model 的标准左侧。
  • partial 预填常量;MessagesPlaceholder 接多轮历史。
  • Prompt 本身是 Runnable,可 batch、可进 fallback 链。
  • 注意占位符与 RAG 片段中的花括号 冲突。

参考链接

-------------本文结束感谢您的阅读-------------