AI Agent白手起家28: LangChain 五种提示词模板实战解析

内容纲要

  • 提示词模板核心概念
    • PromptTemplate:面向纯文本 LLM 的字符串模板
    • ChatPromptTemplate:面向对话模型的结构化模板
    • MessagesPlaceholder:在消息列表中动态插入内容的占位符
    • 使用 SystemMessageHumanMessageAIMessage 灵活组合模板
    • 自定义模板:继承 StringPromptTemplate 实现特殊逻辑
  • 关键流程:定义模板 → 声明变量 → 格式化(format / format_messages)→ 提交给 LLM
  • 涉及组件:langchain_core.promptslangchain_core.messages
  • 代码演示:完整可运行的 Python 脚本,涵盖所有模板类型

引言

在构建 AI Agent 或大语言模型应用时,提示词(Prompt)是连接业务逻辑与模型能力的桥梁。LangChain 提供了一套丰富的提示词模板系统,使开发者可以像写配置一样管理复杂的提示词结构,而无需手动拼接字符串。本文将系统讲解五种最常用的提示词模板:字符串模板、对话模板、消息占位符、Message 组合模板以及自定义模板,并提供可直接运行的代码示例。

一、字符串模板:PromptTemplate

字符串模板是最基础的提示词模板,适用于传统的文本补全模型(LLM),它接收一个包含占位符的字符串,通过 format 方法将参数注入,最终生成一段完整的文本提示。

核心特点:输入输出均为纯文本,不支持结构化消息。

from langchain_core.prompts import PromptTemplate

# 定义模板,花括号内为变量
template = "你是一个{role},帮我起一个具有{country}特色的{gender}名字。"
prompt = PromptTemplate.from_template(template)

# 传入参数格式化
formatted = prompt.format(role="算命大师", country="法国", gender="女孩")
print(formatted)

输出:你是一个算命大师,帮我起一个具有法国特色的女孩名字。

使用时需注意:模板中声明的变量数量必须与 format 传入的参数完全一致,否则会抛出异常。

二、对话模板:ChatPromptTemplate

对话模板是当前应用最广泛的形式,专为对话类模型(Chat Model)设计。它返回的是一个结构化的消息列表,每条消息都带有明确的角色(system、human、ai),便于下游处理。

from langchain_core.prompts import ChatPromptTemplate

# 使用 from_messages 构建消息列表
template = ChatPromptTemplate.from_messages([
    ("system", "你是一个起名大师,你的名字叫{name}。"),
    ("human", "你好,感觉如何?"),
    ("ai", "你好,我状态非常好。"),
    ("human", "你叫什么名字?"),
    ("ai", "你好,我叫{name}。"),
    ("human", "{user_input}"),
])

# 注意:对话模板使用 format_messages 而非 format
messages = template.format_messages(
    name="陈大师",
    user_input="你的爸爸是谁呢?"
)
print(messages)

输出将是一个包含 SystemMessageHumanMessageAIMessage 的列表,每条消息都带有 content 字段,并保留了元数据,非常适合在应用中进行结构化解析和后续调用。

三、消息占位符:MessagesPlaceholder

当需要在消息列表的特定位置动态插入一组消息(例如历史聊天记录),但又不确定其具体数量或类型时,可以使用 MessagesPlaceholder。它相当于一个“插槽”,在最终调用模型前可以被替换为实际的消息列表。

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

# 构造带占位符的模板
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 声明式构建,还可以直接用 SystemMessageHumanMessageAIMessage 等消息对象手动拼装,形成消息列表。这种方式更灵活,适合将公共的系统消息或用户消息进行复用组合。

from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from langchain_core.prompts import ChatPromptTemplate

# 手动构建消息
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 作为公共提示词,在多个场景中复用,并自由组合后续对话流程,大幅提升代码的模块化程度。

五、自定义提示词模板

当内置的 PromptTemplateChatPromptTemplate 无法满足需求时,可以通过继承 StringPromptTemplate 来实现自己的模板逻辑。例如,创建一个“函数大师”模板:输入函数名,自动获取函数源代码,并生成一段要求解释代码的提示词。

步骤

  1. 继承 StringPromptTemplate
  2. 重写 format 方法,在其中实现自定义逻辑(如获取源代码、拼接提示)
  3. 调用时和普通模板一致
import inspect
from langchain_core.prompts import StringPromptTemplate

# 定义一个示例函数
def hello_world(a, b, c):
    """测试函数"""
    print("hello world")
    return a, b, c

# 自定义模板类
class CustomCodeExplainerTemplate(StringPromptTemplate):
    def format(self, **kwargs) -> str:
        func_name = kwargs["function_name"]
        # 获取函数源代码
        source_code = inspect.getsource(globals()[func_name])
        # 内嵌提示词
        prompt_template = (
            "你是一个非常有经验和天赋的程序员。现在给你如下函数名称,"
            "你会按照如下格式输出这段代码的名称、源代码和中文解释。\n"
            "函数名称: {function_name}\n"
            "源代码: {source_code}\n"
            "代码解释: "
        )
        return prompt_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 调用的一般流程。

大语言模型提示词模板开发者大语言模型提示词模板开发者定义模板及变量传入参数 (format / format_messages / invoke)返回格式化后的提示词或消息列表将格式化结果作为输入发送返回模型响应

完整可运行代码

以下代码整合了上述五种模板的示例,可直接复制执行。执行前请安装依赖:

pip install langchain langchain-core
import inspect
from langchain_core.prompts import (
    PromptTemplate,
    ChatPromptTemplate,
    MessagesPlaceholder,
    StringPromptTemplate
)
from langchain_core.messages import HumanMessage, 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. 自定义模板 ==========
def hello_world(a, b, c):
    """测试函数"""
    print("hello world")
    return a, b, c

class CustomCodeExplainerTemplate(StringPromptTemplate):
    def format(self, **kwargs) -> str:
        func_name = kwargs["function_name"]
        source_code = inspect.getsource(globals()[func_name])
        prompt_template = (
            "你是一个非常有经验和天赋的程序员。现在给你如下函数名称,"
            "你会按照如下格式输出这段代码的名称、源代码和中文解释。\n"
            "函数名称: {function_name}\n"
            "源代码: {source_code}\n"
            "代码解释: "
        )
        return prompt_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 系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值