ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【LangChain组件01:Messages】—— LangChain Messages 消息类型:从四种核心消息到多模态与消息裁剪

2026/9/4 5:21:57 拓冰建站 浏览量
【LangChain组件01:Messages】—— LangChain Messages 消息类型:从四种核心消息到多模态与消息裁剪 LangChain Messages 消息类型从四种核心消息到多模态与消息裁剪在 LangChain 中所有的对话都通过消息Message对象传递。理解各种消息类型的用途是编写 Agent 的基础——模型读到的是消息列表你写给模型的也是消息列表。搞不清 HumanMessage、AIMessage、ToolMessage 这些类型和它们之间的关系写 Agent 时就会一头雾水。本文基于 LangChain 官方文档Python与菜鸟教程 LangChain 系列沿材料分类组件01Messages的路径组织覆盖四种核心消息类型、ContentBlock、多模态消息、ToolCall、消息裁剪与删除。一、先厘清消息为什么是 Agent 的基础一句话结论消息Message是模型和程序之间的信使一条消息 一个角色说的话。模型根据整个消息列表理解上下文你也是靠追加/裁剪消息来构造对话历史。四种核心消息类型对应对话中的不同角色类型角色说明典型内容HumanMessage用户用户发送的消息“今天天气怎么样”AIMessageAI 助手模型的回复可能包含 tool_calls“今天杭州晴天25°C”SystemMessage系统系统指令定义 AI 的角色和行为规则“你是一个专业的天气助手”ToolMessage工具工具执行后的返回结果“晴25°C湿度 60%”所有消息类型都继承自BaseMessage共享content、type、id等通用属性。二、HumanMessage——用户消息HumanMessage代表用户发送给 AI 的消息。它是最常见的消息类型也是对话的起点。fromlangchain.messagesimportHumanMessagefromlangchain.chat_modelsimportinit_chat_model msgHumanMessage(content菜鸟教程 RUNOOB 是什么)print(f类型:{msg.type})# humanprint(f内容:{msg.content})print(f角色:{msg.role})# user# 创建消息列表代表多轮对话历史messages[HumanMessage(content你好),HumanMessage(content菜鸟教程有哪些课程),HumanMessage(contentPython 课程适合零基础吗),]modelinit_chat_model(deepseek:deepseek-v4-flash,temperature0)responsemodel.invoke(messages)print(f模型回复:{response.content})2.1 HumanMessage 的快捷创建方式构建消息列表时可以用元组或字典作为快捷方式fromlangchain.messagesimportHumanMessage# 方式 1标准构造msg1HumanMessage(content你好)# 方式 2元组快捷方式 (role, content)msg2(user,你好)msg3(human,你好)# 方式 3字典快捷方式msg4{role:user,content:你好}# 四种方式等价都会在 Agent 内部被转换为 HumanMessage三、AIMessage——AI 回复AIMessage代表模型的回复。与普通文本不同AIMessage可能包含tool_calls工具调用请求。fromlangchain.messagesimportAIMessage# 普通 AI 回复无工具调用ai_msgAIMessage(content菜鸟教程是一个编程学习平台)# 包含工具调用的 AI 回复ai_with_toolsAIMessage(content,# 工具调用时 content 通常为空tool_calls[{name:get_weather,args:{city:杭州},id:call_abc123,type:tool_call,}],)print(fcontent:{ai_with_tools.content})print(ftool_calls:{ai_with_tools.tool_calls})3.1 AIMessage 的附加信息AIMessage包含丰富的元数据消息 ID、模型名、Token 用量fromlangchain.chat_modelsimportinit_chat_model modelinit_chat_model(deepseek:deepseek-v4-flash)responsemodel.invoke(介绍菜鸟教程 RUNOOB)print(f内容:{response.content})print(f消息ID:{response.id})print(f模型名:{response.response_metadata.get(model_name)})print(f完成原因:{response.response_metadata.get(finish_reason)})ifresponse.usage_metadata:print(f输入 tokens:{response.usage_metadata.get(input_tokens)})print(f输出 tokens:{response.usage_metadata.get(output_tokens)})四、SystemMessage——系统指令SystemMessage用于设定 AI 的行为、角色和约束。它放在消息列表的最前面指导模型如何回复。fromlangchain.messagesimportHumanMessage,SystemMessagefromlangchain.chat_modelsimportinit_chat_model modelinit_chat_model(deepseek:deepseek-v4-flash,temperature0.7)# 无系统指令 vs 有系统指令messages_no_system[HumanMessage(content介绍菜鸟教程)]responsemodel.invoke(messages_no_system)print(f无系统指令:{response.content[:80]}...)messages_with_system[SystemMessage(content你是一个小红书风格的博主回复要活泼、使用 emoji、带话题标签),HumanMessage(content介绍菜鸟教程),]responsemodel.invoke(messages_with_system)print(f有系统指令:{response.content})系统指令能显著改变模型风格——同样的输入系统指令直接决定了它是正经介绍还是小红书安利。这正是前面 Agent 篇里system_prompt的作用原理。五、ToolMessage——工具返回结果ToolMessage包含工具执行后的返回结果必须与对应的 tool_call 关联通过tool_call_id。fromlangchain.messagesimportHumanMessage,AIMessage,ToolMessagefromlangchain.chat_modelsimportinit_chat_model# 模拟一轮完整的工具调用对话messages[HumanMessage(content杭州天气怎么样),AIMessage(content,tool_calls[{name:get_weather,args:{city:杭州},id:call_abc,type:tool_call}],),# 工具返回结果tool_call_id 必须与上面的 id 对应ToolMessage(content晴25°C湿度 60%,tool_call_idcall_abc,nameget_weather,),]modelinit_chat_model(deepseek:deepseek-v4-flash)responsemodel.invoke(messages)print(f模型基于工具结果的回复:{response.content})⚠️ 避坑ToolMessage的tool_call_id必须与AIMessage中tool_call的id精确匹配。如果不匹配模型可能会忽略这个工具结果或产生混乱行为。六、AIMessageChunk——流式输出的消息片段使用stream()流式输出时每个到达的片段是AIMessageChunk而非完整的AIMessagefromlangchain.chat_modelsimportinit_chat_model modelinit_chat_model(deepseek:deepseek-v4-flash)print(流式输出过程)forchunkinmodel.stream(用一句话介绍菜鸟教程 RUNOOB):print(chunk.content,end,flushTrue)# 每个 chunk 是一小段文本print()消息类型速查表消息类型type 属性role 属性关键字段何时使用HumanMessagehumanusercontent用户输入AIMessageaiassistantcontent, tool_calls, usage_metadata模型回复AIMessageChunkaiassistantcontent增量流式输出的片段SystemMessagesystemsystemcontent设定 AI 角色ToolMessagetooltoolcontent, tool_call_id, name工具执行结果七、ContentBlock——结构化消息内容到目前为止消息内容都是纯字符串。但实际上每条消息的内容可以是多个ContentBlock内容块组成的列表。最常用的三种内容块类型说明用途PlainTextContentBlock纯文本内容普通文字消息ImageContentBlock图片内容base64 或 URL多模态模型的图片输入ToolCall工具调用请求AI 请求调用工具fromlangchain.messagesimportHumanMessagefromlangchain.messagesimportPlainTextContentBlock,ImageContentBlock# content 可以是纯字符串简单场景simple_msgHumanMessage(content你好)# content 也可以是 ContentBlock 列表复杂场景complex_msgHumanMessage(content[PlainTextContentBlock(text这张图片里是什么),ImageContentBlock(urlhttps://example.com/photo.jpg),# 图片可以是 URL 或 base64])print(f简单消息内容类型:{type(simple_msg.content)})# strprint(f复杂消息内容类型:{type(complex_msg.content)})# listprint(f内容块数量:{len(complex_msg.content)})# 2只发纯文本时直接传字符串即可LangChain 自动处理。只有需要在单条消息里混合文本和图片时才手动构建 ContentBlock 列表。八、多模态消息——让模型看图片如果模型支持多模态输入如 GPT-4o、Claude 3、Gemini可以让它分析图片内容importbase64frompathlibimportPathfromlangchain.messagesimportHumanMessagefromlangchain.chat_modelsimportinit_chat_modeldefencode_image(image_path:str)-str:读取图片文件并转换为 base64 编码withopen(image_path,rb)asf:returnbase64.b64encode(f.read()).decode(utf-8)modelinit_chat_model(deepseek:deepseek-v4-flash)image_dataencode_image(screenshot.png)messages[HumanMessage(content[{type:text,text:请描述这张菜鸟教程 RUNOOB 官网截图的内容},{type:image_url,image_url:{url:fdata:image/png;base64,{image_data},detail:auto,# 可选low, high, auto},},])]responsemodel.invoke(messages)print(f图片分析结果:{response.content})⚠️ 注意并非所有模型都支持多模态。用不支持的模型发送图片会收到错误。OpenAI GPT-4o 系列、Anthropic Claude 3、Google Gemini 系列支持。九、ToolCall——工具调用消息AIMessage中的tool_calls字段是一个 ToolCall 列表每个 ToolCall 代表模型请求调用一个工具fromlangchain.messagesimportAIMessagefromlangchain.messages.toolimportToolCall tool_callToolCall(nameget_weather,args{city:杭州},idcall_abc123,typetool_call,)ai_messageAIMessage(content,tool_calls[tool_call])print(f工具名称:{ai_message.tool_calls[0][name]})print(f调用参数:{ai_message.tool_calls[0][args]})print(f调用 ID:{ai_message.tool_calls[0][id]})检查 AIMessage 是否包含工具调用——两种方式fromlangchain.chat_modelsimportinit_chat_model modelinit_chat_model(deepseek:deepseek-v4-flash,temperature0)model_with_toolsmodel.bind_tools([tools])# 假设 tools 已定义responsemodel_with_tools.invoke(杭州天气怎么样)# 方式 1检查 tool_calls 列表是否非空ifresponse.tool_calls:print(模型请求调用工具)# 方式 2检查 content 是否为空# 大多数模型在有 tool_calls 时 content 为空ifnotresponse.content:print(模型的 content 为空说明它想调用工具而非直接回复)十、trim_messages()——裁剪消息历史当对话越来越长消息列表可能超出模型上下文窗口。trim_messages()智能裁剪消息历史fromlangchain.messagesimport(HumanMessage,AIMessage,SystemMessage,trim_messages)fromlangchain.chat_modelsimportinit_chat_model messages[SystemMessage(content你是菜鸟教程 RUNOOB 的 AI 助手),HumanMessage(contentPython 怎么入门),AIMessage(contentPython 入门可以从基础知识开始...),# ... 更多历史消息 ...HumanMessage(contentpandas 和 NumPy 有什么区别),]modelinit_chat_model(deepseek:deepseek-v4-flash)trimmedtrim_messages(messages,max_tokens1000,# 最多保留 1000 tokensstrategylast,# 保留最后的系统消息 最近的对话token_countermodel,# 使用模型的 token 计数方式include_systemTrue,# 始终保留 SystemMessagestart_onhuman,# 裁剪后以 human 消息开头)策略说明适用场景strategy“last”保留 system 消息 最近的对话长对话中只关心最新上下文strategy“first”保留 system 消息 最早的对话确保关键上下文不被裁剪start_onhuman确保裁剪后的消息列表以用户消息开头而不是 AI 消息避免模型收到一条孤立的 AI 回复开头。十一、RemoveMessage——删除特定消息在某些高级场景中敏感内容清洗、重新生成回复等需要从消息历史中删除特定消息fromlangchain.messagesimportHumanMessage,AIMessage,RemoveMessage messages[HumanMessage(content你好,idmsg_1),AIMessage(content你好有什么可以帮你的,idmsg_2),HumanMessage(content帮我查天气,idmsg_3),]# 使用 RemoveMessage 删除特定消息通过 ID# 配合 add_messages reducer 使用removalRemoveMessage(idmsg_3)print(f要删除的消息 ID:{removal.id})# msg_3print(f类型:{removal.type})# removeRemoveMessage通常配合AgentState的add_messagesreducer 使用。在 middleware 或 after_model 钩子中返回RemoveMessage可以动态清理消息历史。十二、消息属性的通用方法所有消息类型都继承自BaseMessage共享通用方法fromlangchain.messagesimportHumanMessage msgHumanMessage(content你好菜鸟教程)print(fcontent:{msg.content})print(ftype:{msg.type})# humanprint(fid:{msg.id})# 自动生成的唯一 IDprint(ftext:{msg.text})# 文本内容否则返回 print(f美化输出:\n{msg.pretty_repr()})# 格式化打印适合调试十三、总结你真正需要记住的 N 件事消息是 Agent 的基础模型读消息列表你也靠消息列表构造对话历史。四种核心消息Human用户、AI模型回复可含 tool_calls、System系统指令、Tool工具结果靠 tool_call_id 关联。ToolMessage 的 tool_call_id 必须精确匹配否则模型会忽略或混乱。AIMessageChunk 是流式片段stream() 场景用每个 chunk 是一小段增量文本。ContentBlock 支持结构化内容文本 图片混合时才需要手动构建列表。多模态靠 image_url 块只有支持的模型GPT-4o/Claude 3/Gemini能看图。长对话用 trim_messages() 裁剪start_onhuman保证开头是用户消息。删消息用 RemoveMessage配合 add_messages reducer按 ID 精准删除。验证清单我知道四种核心消息类型各自的 role 和 type我给 ToolMessage 填了正确的 tool_call_id与 AIMessage 的 tool_call 对应流式场景我用了 AIMessageChunk并正确拼接内容需要图文混合时我用了 ContentBlock 列表纯文本仍用字符串多模态我只用了支持的模型GPT-4o/Claude 3/Gemini长对话我用 trim_messages() 裁剪并设 start_on“human”需要删消息时我用了 RemoveMessage 配合 add_messages reducer参考资源LangChain 官方文档Messages——https://docs.langchain.com/oss/python/langchain/messagesLangChain Referencemessages——https://reference.langchain.com/python/langchain-core/messages菜鸟教程 LangChain 系列——https://www.runoob.com/langchain/