type
Post
status
Published
date
Sep 10, 2025
slug
summary
tags
prompt
人工智能
category
技术分享
icon
password
ChatPromptTemplate 中,MessagesPlaceholder 的作用可以概括为:为一组“不确定数量”的消息对象在 Prompt 中预留一个“动态占位符”。
如果说 {question} 是为一个字符串(String)预留的座位,那么 MessagesPlaceholder 就是为一排消息对象列表(List of Messages)预留的一个“VIP 专区”。
以下是它的核心作用拆解:

1. 处理“列表”而非“字符串”

普通的变量占位符(如 {question})通常只能接收一个简单的字符串。 如果你尝试把一段对话历史(包含多个 HumanMessageAIMessage 的列表)塞进 {history} 字符串占位符,结果会变成一段很难看的 Python 代码文本:
[HumanMessage(content='你好'), AIMessage(content='你好!')]
MessagesPlaceholder 会告诉 LangChain:“这里会进来一串完整的消息对象,请把它们原封不动地展开并插入到这个位置。”

2. 保持消息的角色(Role)属性

使用 MessagesPlaceholder 后,历史记录中的每一条消息都能保留其原始身份:
  • 用户说的话依然是 HumanMessage
  • AI 说的话依然是 AIMessage
这样发送给模型(如 DeepSeek 或 GPT)时,模型能清晰地识别出:“这是之前用户说的,那是之前我回答的”,从而大大提高上下文理解的准确度。

3. 实现“动态插入”

在你的代码结构中:
  1. System Message: 始终在最开头(定义角色)。
  1. MessagesPlaceholder (history): 动态地把过去 5 轮或 10 轮的对话塞在这里。
  1. Human Message (question): 始终在最后(当前用户的新问题)。
这种结构非常符合大模型的对话规范:[系统指令] -> [历史对话] -> [最新提问]

形象的比喻

想象你在排队入场:
  • ("system", "..."):是一个固定的领队。
  • ("human", "{question}"):是一个固定的末尾观众。
  • MessagesPlaceholder(variable_name='history'):是中间的一块预留区域
当程序运行起来后,Memory 组件会带着一队人(历史消息)走过来。MessagesPlaceholder 就会退场,让这一队人原样站进这个预留位置。

代码中的逻辑连接点

这个 variable_name='history' 必须与两处保持一致:
  1. Memory 定义处ConversationBufferMemory(memory_key="history", return_messages=True)
  1. 数据注入处RunnablePassthrough.assign(history=...)
总结一句话: 没有它,你的对话历史只是一段死板的文字;有了它,你的对话历史才是活生生的、有角色区分的消息流。
ollama服务连接失败问题FewShotPromptTemplate
Loading...