内容纲要
- 提示词模板核心概念
PromptTemplate:面向纯文本 LLM 的字符串模板ChatPromptTemplate:面向对话模型的结构化模板MessagesPlaceholder:在消息列表中动态插入内容的占位符- 使用
SystemMessage、HumanMessage、AIMessage灵活组合模板 - 自定义模板:继承
StringPromptTemplate实现特殊逻辑
- 关键流程:定义模板 → 声明变量 → 格式化(
format/format_messages)→ 提交给 LLM - 涉及组件:
langchain_core.prompts、langchain_core.messages - 代码演示:完整可运行的 Python 脚本,涵盖所有模板类型
引言
在构建 AI Agent 或大语言模型应用时,提示词(Prompt)是连接业务逻辑与模型能力的桥梁。LangChain 提供了一套丰富的提示词模板系统,使开发者可以像写配置一样管理复杂的提示词结构,而无需手动拼接字符串。本文将系统讲解五种最常用的提示词模板:字符串模板、对话模板、消息占位符、Message 组合模板以及自定义模板,并提供可直接运行的代码示例。
一、字符串模板:PromptTemplate
字符串模板是最基础的提示词模板,适用于传统的文本补全模型(LLM),它接收一个包含占位符的字符串,通过format方法将参数注入,最终生成一段完整的文本提示。
核心特点:输入输出均为纯文本,不支持结构化消息。
fromlangchain_core.promptsimportPromptTemplate# 定义模板,花括号内为变量template="你是一个{role},帮我起一个具有{country}特色的{gender}名字。"prompt=PromptTemplate.from_template(template)# 传入参数格式化formatted=prompt.format(role="算命大师",country="法国",gender="女孩")print(formatted)输出:你是一个算命大师,帮我起一个具有法国特色的女孩名字。
使用时需注意:模板中声明的变量数量必须与format传入的参数完全一致,否则会抛出异常。
二、对话模板:ChatPromptTemplate
对话模板是当前应用最广泛的形式,专为对话类模型(Chat Model)设计。它返回的是一个结构化的消息列表,每条消息都带有明确的角色(system、human、ai),便于下游处理。
fromlangchain_core.promptsimportChatPromptTemplate# 使用 from_messages 构建消息列表template=ChatPromptTemplate.from_messages([("system","你是一个起名大师,你的名字叫{name}。"),("human","你好,感觉如何?"),("ai","你好,我状态非常好。"),("human","你叫什么名字?"),("ai","你好,我叫{name}。"),("human","{user_input}"),])# 注意:对话模板使用 format_messages 而非 formatmessages=template.format_messages(name="陈大师",user_input="你的爸爸是谁呢?")print(messages)输出将是一个包含SystemMessage、HumanMessage、AIMessage的列表,每条消息都带有content字段,并保留了元数据,非常适合在应用中进行结构化解析和后续调用。
三、消息占位符:MessagesPlaceholder
当需要在消息列表的特定位置动态插入一组消息(例如历史聊天记录),但又不确定其具体数量或类型时,可以使用MessagesPlaceholder。它相当于一个“插槽”,在最终调用模型前可以被替换为实际的消息列表。
fromlangchain_core.promptsimportChatPromptTemplate,MessagesPlaceholderfromlangchain_core.messagesimportHumanMessage# 构造带占位符的模板prompt=ChatPromptTemplate.from_messages([("system","你是一个厉害的人工智能助手。"),MessagesPlaceholder(variable_name="history"),("human","{question}")])# 在调用阶段动态传入消息列表result=prompt.invoke({"history":[HumanMessage(content="你好,请多关照!")],"question":"今天天气如何?"})print(result.messages)此外,也可以直接用("placeholder", "{history}")这种简写方式,效果等价。占位符的灵活性在于,它允许在invoke阶段(而不一定在format阶段)再确定插入的内容,这对构建复杂 Agent 的多轮对话记忆非常实用。
四、使用 Message 直接组合模板
除了通过ChatPromptTemplate.from_messages声明式构建,还可以直接用SystemMessage、HumanMessage、AIMessage等消息对象手动拼装,形成消息列表。这种方式更灵活,适合将公共的系统消息或用户消息进行复用组合。
fromlangchain_core.messagesimportSystemMessage,HumanMessage,AIMessagefromlangchain_core.promptsimportChatPromptTemplate# 手动构建消息system_msg=SystemMessage(content="你是一个起名大师",additional_kwargs={"大师名字":"陈瞎子"})human_msg=HumanMessage(content="请问大师叫什么?")ai_msg=AIMessage(content="我叫陈瞎子。")# 直接拼成列表,即是一个合法的消息模板chat_list=[system_msg,human_msg,ai_msg]prompt=ChatPromptTemplate.from_messages(chat_list)print(prompt.format_messages())这种方式下,你可以将某个SystemMessage作为公共提示词,在多个场景中复用,并自由组合后续对话流程,大幅提升代码的模块化程度。
五、自定义提示词模板
当内置的PromptTemplate和ChatPromptTemplate无法满足需求时,可以通过继承StringPromptTemplate来实现自己的模板逻辑。例如,创建一个“函数大师”模板:输入函数名,自动获取函数源代码,并生成一段要求解释代码的提示词。
步骤:
- 继承
StringPromptTemplate - 重写
format方法,在其中实现自定义逻辑(如获取源代码、拼接提示) - 调用时和普通模板一致
importinspectfromlangchain_core.promptsimportStringPromptTemplate# 定义一个示例函数defhello_world(a,b,c):"""测试函数"""print("hello world")returna,b,c# 自定义模板类classCustomCodeExplainerTemplate(StringPromptTemplate):defformat(self,**kwargs)->str:func_name=kwargs["function_name"]# 获取函数源代码source_code=inspect.getsource(globals()[func_name])# 内嵌提示词prompt_template=("你是一个非常有经验和天赋的程序员。现在给你如下函数名称,""你会按照如下格式输出这段代码的名称、源代码和中文解释。\n""函数名称: {function_name}\n""源代码: {source_code}\n""代码解释: ")returnprompt_template.format(function_name=func_name,source_code=source_code)# 使用自定义模板custom_prompt=CustomCodeExplainerTemplate(input_variables=["function_name"])final_prompt=custom_prompt.format(function_name="hello_world")print(final_prompt)输出已包含函数名称和源代码。后续你可以将该提示词直接交给 LLM,得到代码解释。这种模式允许你在模板内部封装任何复杂的预处理逻辑,从而将提示词构建过程完全自动化。
五种模板对比
| 模板类型 | 输入变量占位 | 输出格式 | 适用模型 | 灵活性 |
|---|---|---|---|---|
PromptTemplate | 字符串花括号 | 纯文本 | LLM(补全) | 低 |
ChatPromptTemplate | 消息列表变量 | 结构化消息列表 | Chat Model | 中 |
MessagesPlaceholder | 动态消息插槽 | 含占位符的消息列表 | Chat Model | 高 |
| Message 对象组合 | 无 | 消息列表 | Chat Model | 高 |
自定义StringPromptTemplate | 自定义 | 任意 | 均可 | 极高 |
模板工作流程
以下 Mermaid 时序图展示了从定义模板到 LLM 调用的一般流程。
完整可运行代码
以下代码整合了上述五种模板的示例,可直接复制执行。执行前请安装依赖:
pipinstalllangchain langchain-coreimportinspectfromlangchain_core.promptsimport(PromptTemplate,ChatPromptTemplate,MessagesPlaceholder,StringPromptTemplate)fromlangchain_core.messagesimportHumanMessage,SystemMessage,AIMessage# ========== 1. 字符串模板 ==========str_template=PromptTemplate.from_template("你是一个{role},帮我起一个具有{country}特色的{gender}名字。")str_result=str_template.format(role="算命大师",country="法国",gender="女孩")print("字符串模板结果:\n",str_result,"\n")# ========== 2. 对话模板 ==========chat_template=ChatPromptTemplate.from_messages([("system","你是一个起名大师,你的名字叫{name}。"),("human","你好,感觉如何?"),("ai","你好,我状态非常好。"),("human","你叫什么名字?"),("ai","你好,我叫{name}。"),("human","{user_input}"),])chat_result=chat_template.format_messages(name="陈大师",user_input="你的爸爸是谁呢?")print("对话模板结果:\n",chat_result,"\n")# ========== 3. 消息占位符 ==========placeholder_template=ChatPromptTemplate.from_messages([("system","你是一个厉害的人工智能助手。"),MessagesPlaceholder(variable_name="history"),("human","{question}")])ph_result=placeholder_template.invoke({"history":[HumanMessage(content="你好,请多关照!")],"question":"今天天气如何?"})print("消息占位符结果:\n",ph_result.messages,"\n")# ========== 4. Message 组合模板 ==========sys_msg=SystemMessage(content="你是一个起名大师",additional_kwargs={"大师名字":"陈瞎子"})human_msg=HumanMessage(content="请问大师叫什么?")ai_msg=AIMessage(content="我叫陈瞎子。")composed_list=[sys_msg,human_msg,ai_msg]composed_template=ChatPromptTemplate.from_messages(composed_list)comp_result=composed_template.format_messages()print("Message 组合模板结果:\n",comp_result,"\n")# ========== 5. 自定义模板 ==========defhello_world(a,b,c):"""测试函数"""print("hello world")returna,b,cclassCustomCodeExplainerTemplate(StringPromptTemplate):defformat(self,**kwargs)->str:func_name=kwargs["function_name"]source_code=inspect.getsource(globals()[func_name])prompt_template=("你是一个非常有经验和天赋的程序员。现在给你如下函数名称,""你会按照如下格式输出这段代码的名称、源代码和中文解释。\n""函数名称: {function_name}\n""源代码: {source_code}\n""代码解释: ")returnprompt_template.format(function_name=func_name,source_code=source_code)custom_prompt=CustomCodeExplainerTemplate(input_variables=["function_name"])custom_result=custom_prompt.format(function_name="hello_world")print("自定义模板结果:\n",custom_result,"\n")总结
本文详细介绍了 LangChain 中五种提示词模板的用法及适用场景,从最简单的字符串模板到高度灵活的自定义模板,覆盖了绝大多数 LLM 应用的提示词构建需求。
通过对比和完整代码示例,开发者可以快速选择适合自己项目的模板类型,并基于此构建稳健、可维护的 AI Agent 系统。