🎯 课程主题
详细介绍 LangChain 中 SystemMessage、HumanMessage、AIMessage、ToolMessage 四种消息对象的内部字段及其使用方式,并说明不同模型供应商对字段支持程度的影响。
📝 核心知识点
1. SystemMessage — 系统消息
- 概念说明:用于设定模型角色或行为准则。
- 关键细节:仅有一个
content字段。当content为纯文本时,content=关键字可省略,直接写字符串即可,两种写法完全等价。
2. HumanMessage — 用户消息
- 概念说明:封装用户向模型提出的问题。
- 关键细节:
- 除
content外,支持自定义metadata字段(如name区分用户身份、id区分不同消息)。 name字段的识别取决于模型供应商。例如 Claude AI 平台支持识别,OpenRouter 平台可能返回"unknown"。
- 除
3. AIMessage — AI 回复消息
- 概念说明:模型调用
invoke后的返回值类型。 - 关键细节:
content:模型的回复文本。additional_kwargs:补充信息,如推理思考过程(reasoning_content)。response_metadata:响应的元数据,如 token 消耗情况。usage_metadata:具体的 token 使用统计。tool_calls:工具调用列表。无工具调用时为空列表[];每次工具调用包含name(工具名称)和arguments(参数)等字段。
4. ToolMessage — 工具调用结果消息
- 概念说明:工具调用完成后的返回结果,封装工具执行的内容。
- 关键细节:
content:工具返回的结果内容。name:工具名称。tool_call_id:必须与对应 AIMessage 中tool_calls里的id保持一致,否则模型无法正确关联。
🏗️ 架构与工作流
- 系统消息(SystemMessage)定义角色上下文。
- 用户消息(HumanMessage)携带用户提问,可附加
metadata。 - 模型根据消息列表生成 AIMessage 回复;若需要调用工具,AIMessage 的
tool_calls包含调用信息。 - 工具执行后返回 ToolMessage,
tool_call_id与 AIMessage 中的id匹配,再交回模型整合生成最终回复。
💻 代码实战
# ========== HumanMessage 带 metadata(Claude AI 平台,支持 name 字段)==========
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-4o",
base_url="https://api.claude.ai/v1", # Claude AI 平台
api_key="your-api-key"
)
messages = [
SystemMessage(content="你的任务是严格根据每条消息的 name 提取发言者及其观点,输出JSON格式。"),
HumanMessage(content="我认为Python是最适合AI开发的语言。", name="Bob"),
HumanMessage(content="我更喜欢用JavaScript。", name="Tom"),
HumanMessage(content="你是AI助手,帮我总结一下。", name="audience"),
]
response = model.invoke(messages)
print(response.content)
# ========== HumanMessage 带 metadata(OpenRouter 平台,name 仅显示为 unknown)==========
model = ChatOpenAI(
model="openai/gpt-4o-mini",
base_url="https://openrouter.ai/api/v1",
api_key="your-api-key"
)
response = model.invoke(messages)
print(response.content)
# 输出中 name 字段变为 "unknown",说明该供应商不支持此字段
# ========== AIMessage 基础使用 ==========
response = model.invoke([HumanMessage(content="你好,介绍一下你自己")])
print(response) # 完整 AIMessage 对象
print(response.content) # 仅文本内容
print(response.usage_metadata) # token 使用情况
# ========== ToolMessage 使用(JSON/字典格式)==========
from langchain_core.messages import AIMessage, ToolMessage, HumanMessage
# 模拟 AIMessage 中的工具调用
ai_msg = {
"role": "assistant",
"content": None,
"tool_calls": [{"id": "call_123", "name": "get_weather", "arguments": '{"city": "北京"}'}]
}
# 工具返回结果
tool_msg = {
"role": "tool",
"content": "北京天气晴朗,万里无云",
"name": "get_weather",
"tool_call_id": "call_123" # id 必须与 AIMessage 中的匹配
}
messages = [ai_msg, tool_msg, HumanMessage(content="北京天气如何?")]
response = model.invoke(messages)
print(response.content)
# ========== ToolMessage 使用(消息对象格式)==========
from langchain_core.messages import AIMessage, ToolMessage, HumanMessage
ai_message = AIMessage(
content="",
tool_calls=[{"id": "call_123", "name": "get_weather", "arguments": '{"city": "北京"}'}]
)
tool_message = ToolMessage(
content="北京天气晴朗,万里无云",
name="get_weather",
tool_call_id="call_123"
)
messages = [ai_message, tool_message, HumanMessage(content="北京天气如何?")]
response = model.invoke(messages)
print(response.content)
⚠️ 常见问题与避坑指南
- 模型供应商对字段支持不统一:
name等自定义字段能否生效,最终取决于模型供应商(而非模型本身)。同一个 GPT-4o 模型,在 Claude AI 平台可能支持name字段,在 OpenRouter 平台可能不支持。开发前务必查阅供应商文档。 - ToolMessage 的
tool_call_id必须匹配:这是强制要求,id 不一致会导致模型无法识别对应的工具调用结果,返回异常内容。 - 角色字段大小写敏感:消息角色必须使用官方定义的拼写,如
system、human/user、ai/assistant、tool,大小写错误会报错。
💡 个人总结与延伸
本节系统梳理了 LangChain 四种消息对象的字段结构,这是后续理解消息传递和数据流转的基础。tool_call_id 的匹配机制是工具调用链路中的关键约定;name/metadata 的支持程度因供应商而异,在实际项目中需要注意平台兼容性。LangChain v1.x 中消息对象同时支持 JSON/字典格式和对象格式,两种写法等价,可根据代码风格选用。