前面三篇讲了 Runnable 协议和 LCEL 管道。从这篇开始,我们把底层 core 的几块具体积木逐个拆开。第一块,是和 LLM 打交道时最常写的——prompt。
这一篇讲 PromptTemplate。但它要解决的核心问题,不是「怎么写好一段 prompt 文案」(那是另一门学问),而是怎么把散落在代码里的 prompt 文案,变成可复用、可管理的组件。
先看问题:prompt 散落是技术债
很多人写 LLM 应用,prompt 是直接拼字符串的:
# 散落在业务代码里的 prompt
result = model.invoke(f"你是一个客服,用户问:{question},请回答:{context}")
这种写法在 demo 阶段没问题,一旦认真做应用,立刻暴露三个问题:
- 难复用:同一段 prompt 在多处用,复制粘贴,改一处忘改另一处
- 难维护:prompt 一改就要动业务代码,不能独立迭代
- 难测试:想测 prompt 在不同输入下的效果,得把整个调用链跑起来
PromptTemplate 要解决的,就是把 prompt 从「散落的字符串」变成「独立的、可复用的组件」。
PromptTemplate:固定文案 + 变量
PromptTemplate 的思路很朴素:把 prompt 拆成「固定文案」和「变量」两部分。固定文案写死在模板里,变量在运行时填入。
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template(
"你是一个客服,用户问:{question},请结合以下资料回答:{context}"
)
# 运行时填变量
prompt.invoke({"question": "怎么退款", "context": "退款政策..."})
这样带来三个直接收益:
- 可复用:模板定义一次,到处用
- 可独立迭代:改 prompt 不动业务代码
- 可测试:传不同变量,看模板渲染成什么,不用跑整条链
关键:PromptTemplate 也是 Runnable
这是容易被忽略但很重要的一点——PromptTemplate 本身就是一个 Runnable。
这意味着它有上一篇讲的所有能力:invoke 填变量、batch 批量填、stream 流式渲染、能被管道符 | 串进链。所以前面那个 prompt | model | parser 里的 prompt,就是 PromptTemplate。
# prompt 是 Runnable,能进管道
chain = prompt | model | parser
chain.invoke({"question": "怎么退款", "context": "..."})
这就把 prompt 从「写死在代码里的字符串」提升成了「链里的一等公民」——它和 model、parser 平起平坐,都是可组合的积木。
ChatPromptTemplate 与消息角色
和模型对话时,prompt 不是一段平铺文本,而是带角色的消息序列:系统消息(system,定基调)、用户消息(human,提需求)、AI 消息(ai,之前的回答)。
ChatPromptTemplate 就是处理这种「带角色的消息序列」的模板:
| 角色 | 含义 | 典型用途 |
|---|---|---|
| System | 系统设定,定角色和规则 | 「你是客服,回答要简洁」 |
| Human | 用户输入 | 「怎么退款」 |
| AI | 模型之前的回答 | 「退款流程是……」 |
为什么要区分角色?因为模型对不同角色的内容,权重不一样:system 消息被视为「指令」,模型会强烈遵循;human 是「请求」;ai 是「上下文」(尤其在多轮对话里,ai 消息构成历史)。把 prompt 拆成角色消息,能更精确地控制模型行为。
prompt = ChatPromptTemplate.from_messages([
("system", "你是客服,回答简洁,只基于提供的资料"),
("human", "用户问题:{question}"),
])
模板的核心价值:prompt 与代码解耦
讲到这里,PromptTemplate 的真正价值就清楚了:它实现了 prompt 和业务代码的解耦。
- 业务代码只负责「拿到变量,调链」
- prompt 文案集中在模板里,由写 prompt 的人(可能不是写代码的人)独立维护
- 改 prompt 效果,可以不动一行业务代码,直接改模板
这点在团队协作时尤其重要:产品/运营想调 prompt 措辞,不用拉上开发改代码上线;开发改业务逻辑,也不用担心碰到 prompt。两者的迭代节奏解开了。
收束:prompt 是一等公民
这一篇讲了 PromptTemplate:
- 它把 prompt 从散落的字符串,变成「固定文案 + 变量」的模板
- 它是 Runnable,能进管道、能批量、能流式
- ChatPromptTemplate 处理带角色的消息(system/human/ai)
- 核心价值是 prompt 与业务代码解耦
下一篇讲和 prompt 配对的另一块积木——输出解析器。prompt 负责把输入喂给模型,解析器负责把模型的自由文本回答,变成程序能消费的结构化数据。这两块一起,才构成完整的 Model I/O。
关于十三Tech
我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。我相信 AI 是程序员的最佳搭档。
如果你想跟完这套「图解 LangChain」,欢迎关注公众号 「十三Tech」。全系列 42 篇,会按认识基础、LangGraph 状态机、Agent 与 middleware、RAG 检索、Tools/MCP/记忆、生产化收束这条线更新。

