🎯 课程主题
讲解 LangChain 中 invoke 方法的三种输入参数类型:字符串文本、字典列表、消息对象列表,并演示多轮对话中记忆(上下文)的传递方式。
📝 核心知识点
1. 模型调用的三组方法
- 同步版本:
invoke(阻塞式,一次性返回完整结果)、stream(流式输出,逐 token 返回)、batch(批量并发处理)。 - 异步版本:以上三者各自加前缀
a→ainvoke、astream、abatch。 invoke的核心参数:input(必填):发送给模型的内容。config(可选):高级配置,涉及回调函数、元数据和标签(后续章节讲解)。
2. invoke 支持的输入类型
PromptValue:提示词模板的返回值(后续讲解)。- 字符串:最简单的文本输入。
- 序列:列表(list)、元组(tuple)、字典(dict)等形式。
3. 三种常用输入方式
方式一:字符串输入
- 概念说明:直接将字符串传入
invoke,模型将其作为用户问题处理。 - 适用场景:简单的单轮问答。
方式二:字典列表输入
- 概念说明:传入一个列表,列表中每个元素为
{"role": "xxx", "content": "xxx"}的字典。 - 三种角色(role):
system:系统角色,用于设定 AI 的行为、角色和规则(如"你是一个专业的数学老师")。user:用户角色,代表用户的提问。assistant:AI 助手角色,代表模型的回复。
- 说明:
user和human有时可互换,但建议遵循 OpenAI 惯例使用user。 - 这是官方推荐的写法,最灵活。
方式三:消息对象列表输入
- 概念说明:传入由消息对象构成的列表,与方式二一一对应:
角色 字典方式 消息对象 系统 {"role": "system"}SystemMessage用户 {"role": "user"}HumanMessageAI {"role": "assistant"}AIMessage - 均从
langchain_core.messages中导入。
4. 大模型的记忆机制
- 核心问题:大模型天然不具备记忆功能——每次调用
invoke是独立的,不会自动记住上一轮对话内容。 - 解决方案:通过手动拼接历史对话来传递上下文(记忆)。
- 初始化一个消息列表。
- 调用
model.invoke(messages)得到回复。 - 将 AI 的回复(
AIMessage或{"role": "assistant", "content": ...})追加到消息列表中。 - 将用户的新问题追加到消息列表中。
- 再次调用
model.invoke(messages),此时模型能"记住"之前的对话。
🏗️ 架构与工作流
单轮调用(无记忆):
input → model.invoke() → response
多轮调用(带记忆):
messages = [SystemMessage, UserMessage1]
→ model.invoke(messages) → response1 (AIMessage)
messages.append(response1)
messages.append(UserMessage2)
→ model.invoke(messages) → response2 (AIMessage) ← 能"记住"第一轮内容
💻 代码实战
from langchain.chat_models import init_chat_model
model = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
base_url="https://api.closeai-asia.com/v1"
)
# ===== 方式一:字符串输入 =====
response = model.invoke("翻译:你好世界")
print(response.content)
# ===== 方式二:字典列表输入 =====
messages = [
{"role": "system", "content": "你是一个专业的数学老师。"},
{"role": "user", "content": "帮我解释一下什么是斐波那契数列。"}
]
response = model.invoke(messages)
print(response.content)
# ===== 方式三:消息对象列表输入 =====
from langchain_core.messages import SystemMessage, HumanMessage
messages = [
SystemMessage(content="你是一个专业的数学老师。"),
HumanMessage(content="帮我解释一下什么是斐波那契数列。")
]
response = model.invoke(messages)
print(response.content)
多轮对话 + 记忆传递示例(消息对象方式)
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
conversation = [HumanMessage(content="我的名字叫小明。")]
response1 = model.invoke(conversation)
print(f"AI回复1: {response1.content}")
# 添加记忆:AI 的回复 + 用户的新问题
conversation.append(response1) # 即 AIMessage
conversation.append(HumanMessage(content="我叫什么名字?"))
response2 = model.invoke(conversation)
print(f"AI回复2: {response2.content}") # 能回答出"小明"
⚠️ 常见问题与避坑指南
- 默认情况下模型会"失忆":每次
invoke调用是独立的,如果不手动拼接历史消息,模型无法知道之前的对话内容。 - 消息列表中 role(角色)的顺序:一般建议
system→user→assistant→user→ ... 的交替顺序。 uservshuman:两者功能等价,但建议统一使用user以遵循 OpenAI 惯例。
💡 个人总结与延伸
三种输入方式中,字符串最简单,适合快速原型和单轮问答;字典列表是官方推荐的灵活写法;消息对象列表与 LangChain 的消息体系无缝集成,适合构建复杂对话系统。多轮对话中的"记忆"本质上是将历史对话逐步拼接到消息列表中再传给模型——这也是后续 LangChain 中 Memory 组件(如 ConversationBufferMemory)的底层实现原理。