大模型学习笔记:LangChain核心组件-消息(Messages)

在调用模型时,发送给LLM的消息、LLM返回的消息都包含以下几部分内容:

  • role:消息所属角色,可以是system、user、assistant
  • content:消息的内容
  • metadata(可选):消息的元数据,例如:消息的ID、消耗的token等

之前我们都是自己用dict模拟消息:

python 复制代码
response = agent.invoke({
    "messages": [{"role": "user", "content": "月亮的首都是哪里?"}]
})

这太麻烦了。在LangChain中发送给LLM的消息、LLM返回的消息都统一被封装为BaseMessage,它是中基本的上下文单元。

3.1 消息类型

在LangChain中,我们并不需要自己创建BaseMessage对象,LangChain已经把常见消息根据角色(Role)创建了对应的BaseMessage的子类:

  • SystemMessage:role是system,代表系统消息,用于设定模型角色和交互背景
  • HumanMessage:role是user,代表用户输入的消息
  • AIMessage:role是assistant,代表LLM生成的响应,包含:文本、工具调用、元数据
  • ToolMessage:role是tool,代表工具调用时产生的结果

所以,我们可以这样传递消息列表:

python 复制代码
from langchain.messages import HumanMessage, AIMessage
from langchain.agents import create_agent

# 创建Agent
agent = create_agent(model="deepseek-chat")

# 调用Agent,发送消息
response = agent.invoke({
    "messages": [
        HumanMessage(content="你好,我是张三"),
        AIMessage(content="你好,张三,很高兴认识你。"),
        HumanMessage(content="我的名字是什么?")
    ]
})

print(response)

注意看,Agent的返回结果中包含完整的消息列表(Messages):

python 复制代码
{'messages': [HumanMessage(content='你好,我是张三', additional_kwargs={}, response_metadata={}, id='f5703ee9-f567-48d6-8e07-e6ddaf24547e'), AIMessage(content='你好,张三,很高兴认识你。', additional_kwargs={}, response_metadata={}, id='5c654447-828c-43b7-9505-a341e0d21b8a', tool_calls=[], invalid_tool_calls=[]), HumanMessage(content='我的名字是什么?', additional_kwargs={}, response_metadata={}, id='a3390334-85b8-4f5f-8528-782a18671ac9'), AIMessage(content='你刚才提到你的名字是"张三"。如果这是你希望我称呼你的方式,我会记住的。如果有其他偏好,随时告诉我哦! 😊', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 33, 'prompt_tokens': 26, 'total_tokens': 59, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 26}, 'model_provider': 'deepseek', 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_eaab8d114b_prod0820_fp8_kvcache', 'id': '9ea39267-c54a-4523-82e0-1377435ffde4', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019cad79-8b7a-7861-855b-5a87ba11d38c-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 26, 'output_tokens': 33, 'total_tokens': 59, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}})]}

我们可以通过遍历Messages数组,更友好的打印结果:

python 复制代码
for message in response['messages']:
    message.pretty_print()

结果:

python 复制代码
================================ Human Message =================================

你好,我是张三
================================== Ai Message ==================================

你好,张三,很高兴认识你。
================================ Human Message =================================

我的名字是什么?
================================== Ai Message ==================================

你刚才提到你的名字是"张三"。如果这是你希望我称呼你的方式,我会记住的。如果有其他偏好,随时告诉我哦! 😊

提示:

通过刚才的实现可以发现,拼接message列表可以让AI记住会话历史,产生记忆。

3.2 多模态消息

之前我们都是向模型发送文本消息,但是 LangChain 也支持向模型发送多模态消息,比如图片、音频、视频、文本等。但前提是必须是多模态模型才支持。

一些支持多模态的模型有:

  • qwen3.5-plus
  • gpt-5-nano
  • ...
    我们以qwen3.5-plus为例,演示向模型发送图片消息

3.2.1 在线图片

首先,我们演示如何发送一个在线图片给模型,也就是指定模型的url地址。

图片如下:

消息格式如下:

python 复制代码
{
    "role": "user",
    "content": [
        {"type": "image", "url": "https://xxx.com/a.jpeg"},
        {"type": "text", "text": "这些图描绘了什么内容?"}
    ]
}

示例代码:

python 复制代码
from langchain.chat_models import init_chat_model
import os

# 1.初始化模型
model = init_chat_model(
    model="qwen3.5-plus",  # 这里选择qwen3.5-plus,这是一个多模态模型,支持图片、文本、音频、视频
    model_provider="openai",
    base_url=os.getenv("DASHSCOPE_BASE_URL"),
    api_key=os.getenv("DASHSCOPE_API_KEY")
)

# 2.创建智能体
agent = create_agent(model=model)

# 3.组织多模态消息
multimodal_message = HumanMessage(
    content=[
        {"type": "image",
         "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},
        {"type": "text", "text": "这些图描绘了什么内容?"}
    ])

# 4.调用Agent,发送多模态消息
for token, metadata in agent.stream({
    "messages": [multimodal_message]
}, stream_mode="messages"):
    if token.content:
        print(token.content, end="", flush=True)

结果:

python 复制代码
这张图片描绘了一个非常温馨、和谐的场景,主要包含以下内容:

1.  **人物与动物**:
    *   一位年轻女性坐在沙滩上,她留着长发,身穿黑白格纹衬衫和深色长裤(裤脚卷起),看起来非常休闲。
    *   在她对面坐着一只体型较大的浅色犬(看起来像金毛寻回犬或拉布拉多),狗狗身上戴着带有彩色花纹的胸背带。

2.  **互动动作**:
    *   这是画面的核心:狗狗乖巧地抬起一只前爪,放在女子的手掌中,就像是在玩"握手"的游戏。
    *   女子面带灿烂的笑容,温柔地注视着狗狗,一只手握着狗爪,另一只手似乎拿着小零食或者正准备抚摸它。这展现了人与宠物之间亲密无间的信任与爱。

3.  **环境与背景**:
    *   场景设定在海滩上,地面是细腻的沙子,上面布满了脚印和纹理。
    *   背景是大海,可以看到海浪正在向岸边涌来。

4.  **光影与氛围**:
    *   光线非常温暖柔和,从画面右侧照射过来(看起来像是日落时分的"黄金时刻"),给女子的头发和沙滩镀上了一层金色的光晕。
    *   整体氛围宁静、美好且充满幸福感。

此外,还可以看到一条红色的牵引绳散落在狗狗身后的沙地上,说明它们正在享受一段放松的散步时光。

3.2.2 本地图片

所谓本地图片,就是用户上传的图片数据或者本地存在的图片,而不是图片的url地址。我们需要将图片数据转换成base64字符串,然后发送给模型。

本地图片的消息格式:

python 复制代码
{
    "role": "user",
    "content": [
        {"type": "text", "text": "Describe the content of this image."},
        {
            "type": "image",
            "base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
            "mime_type": "image/jpeg",
        },
    ]
}

示例:

python 复制代码
import base64

# 例如,有一个用户上传的文件,是字节格式img_bytes,我们先将其进行base64编码
img_b64 = base64.b64encode(img_bytes).decode("utf-8")

# 组织多模态消息
multimodal_question = HumanMessage(content=[
    {
        "type": "image",
        "base64": img_b64,
        "mime_type": "image/jpeg",
    },
    {"type": "text", "text": "给我讲讲图片中的城市"}
])

# 调用Agent,发送消息
response = agent.invoke(
    {"messages": [multimodal_question]}
)

print(response['messages'][-1].content)
相关推荐
完成大叔3 小时前
Agent入门:用本地模型从零搭建
开发语言·python·langchain
Mr.朱鹏6 小时前
9-检索增强生成RAG详解
python·gpt·langchain·大模型·llm·rag
怪祝浙7 小时前
AI学习-LangChain实战-多模态识别agent
人工智能·学习·langchain
情绪总是阴雨天~7 小时前
深入理解A2A协议:从零搭建多Agent协作系统实战
python·langchain·langgraph·a2a
C137的本贾尼7 小时前
融会贯通:打造完整的 RAG 问答链
python·langchain
暗不需求9 小时前
深入浅出 LangChain Memory:从无状态到有记忆的智能对话
面试·langchain·ai编程
怪祝浙9 小时前
AI实战之LangChain开发(prompt;tools;memory)
langchain
古怪今人9 小时前
大语言模型运行工具及格式 Ollama操作大模型 LangChain应用开发框架【2026】
人工智能·语言模型·langchain
禁默11 小时前
解密 LangChain:LLM 应用开发的核心框架与“超级武器”
android·adb·langchain·vibe coding