Jean's Blog

一个专注软件测试开发技术的个人博客

0%

LangChain核心组件Message(消息)

LangChain 的 Message 模块核心是它作为 LangChain 中处理对话交互的基础组件,用结构化方式标准化了与大模型的交流形式。

介绍

模块核心定位

Message 模块是 LangChain 处理对话上下文交互的基础组件,核心作用是提供结构化的表示方式,来定义与大语言模型之间的所有交流内容。同时明确了核心属性:消息是模型交互的基本单位,每个消息都包含「内容」和「元数据」,用于表征对话的实时状态。

核心价值

该模块的设计核心是解决复杂对话应用开发中的兼容性、可维护性和扩展性问题,具体体现在四点:

  1. 结构化表示:提供统一的消息格式,能清晰区分对话中的不同角色(如系统、用户、AI 助手、工具),避免消息类型混乱。
  2. 上下文管理:为多轮对话历史的维护、存储和调用提供标准化支撑,让复杂的多轮交互逻辑更易管理。
  3. 跨模型兼容:通过统一的消息接口,屏蔽不同模型提供商(如 OpenAI、Anthropic、Google)的消息格式差异,实现 “一次开发,多模型适配”。
  4. 多媒体支持:突破纯文本交互限制,原生支持文本、图像、音频等多种内容形式,适配多模态大模型的交互需求。

总结

Message 模块是 LangChain 对话应用的 “通信标准”—— 它以结构化消息为载体,串联起模型调用、上下文记忆、多模态交互等核心能力,既降低了多模型适配的开发成本,也为复杂对话场景的管理提供了基础支撑。

基本组成

1. 角色 (Role)

  • 作用:标识消息的来源和类型,决定了这条消息在对话中的功能和权重。
  • 常见角色
    • 系统 (System):定义 AI 助手的行为、角色和规则(如 “你是一个专业的 Python 编程助手”)。
    • 用户 (User):代表用户的提问或输入。
    • 助手 (Assistant):代表 AI 模型的回复。
    • 工具 (Tool):代表工具调用的结果或中间信息。

2. 内容 (Content)

  • 作用:承载消息的实际信息,是与模型交互的核心载体。
  • 特点
    • 支持纯文本,也支持图像、音频等多模态内容。
    • 可以是单一内容,也可以是混合内容(如 “文本 + 图片”)。

3. 元数据 (Metadata)

  • 作用:提供额外的上下文信息和追踪能力,不直接参与模型生成,但用于系统管理。
  • 常见元数据
    • 消息 ID、会话 ID
    • 用户标识、设备信息
    • 令牌使用情况、时间戳
    • 自定义业务标签(如优先级、来源渠道)

简单来说,角色定义了 “谁说的”,内容是 “说了什么”,元数据是 “这条消息的背景信息”,三者共同构成了 LangChain 中完整的消息对象,支撑起复杂的对话交互和上下文管理。

使用Message模块

导入消息类型

首先从 langchain.messages 导入常用的消息类,这是构建对话的基础:

1
from langchain.messages import HumanMessage, AIMessage, SystemMessage
  • HumanMessage:用户输入
  • AIMessage:AI 助手回复
  • SystemMessage:系统提示,定义 AI 角色和行为

创建消息对象

根据角色创建对应的消息实例,构建对话的基本单元:

1
2
3
4
5
6
7
8
# 系统消息:定义 AI 的角色和行为
system_msg = SystemMessage("You are a helpful assistant")

# 用户消息:用户的输入内容
human_msg = HumanMessage("Hello, how are you?")

# 助手消息:AI 的回复(可用于手动构建对话历史)
ai_msg = AIMessage("I'm doing well, thank you! How can I help you today?")

每个消息对象都明确了角色和内容,为后续的上下文管理提供了结构化基础。

与模型一起使用

将消息列表传入模型,完成一次完整的对话交互:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, AIMessage, SystemMessage

# 初始化模型
model = init_chat_model("gpt-4o", model_provider="openai")

# 构建消息列表(系统提示 + 用户输入)
messages = [
SystemMessage("你是一个诗歌专家"),
HumanMessage("写一首关于春天的绝句")
]

# 调用模型,返回 AIMessage 对象
response = model.invoke(messages)

# 打印生成的内容
print(response.content)
  • 消息列表按顺序传递,模型会根据上下文生成回复。
  • 返回的 response 是一个 AIMessage 对象,包含了 AI 的回复内容。

类型详解

系统消息 (SystemMessage)

  • 作用:为模型提供初始指令,设定其行为、角色和响应指南,是对话的 “规则书”。

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 基本指令
    system_msg = SystemMessage("你是一个有帮助的编程助手")

    # 详细角色设定
    detailed_system_msg = SystemMessage("""
    你是一位资深Python开发者,精通Web框架。
    总是提供代码示例并解释你的推理过程。
    解释要简洁但全面。
    """)

用户消息 (HumanMessage)

  • 作用:代表用户的输入和交互,可包含文本、图像、音频等多模态内容。

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 基本文本内容
    human_msg = HumanMessage("如何创建REST API?")

    # 带元数据的消息
    human_msg_with_metadata = HumanMessage(
    content="Hello!",
    name="alice", # 可选:标识不同用户
    id="msg_123" # 可选:唯一标识符用于追踪
    )

助手消息 (AIMessage)

  • 作用:代表模型的输出,包含生成的内容和相关元数据,也可手动创建用于构建对话历史。

  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 模型生成的响应
    response = model.invoke("解释什么是AI")
    print(type(response)) # <class 'langchain_core.messages.ai.AIMessage'>

    # 手动创建AI消息(用于对话历史)
    manual_ai_msg = AIMessage("我很乐意帮你解决这个问题!")

    # 在对话历史中插入AI消息
    messages = [
    SystemMessage("你是一个有帮助的助手"),
    HumanMessage("你能帮我吗?"),
    manual_ai_msg, # 插入人工创建的AI消息
    HumanMessage("太好了!2+2等于多少?")
    ]

工具消息 (ToolMessage)

  • 作用:代表工具调用的输出,用于模型和外部工具之间的交互,是实现工具调用能力的关键。

  • 示例

    1
    2
    3
    4
    5
    6
    from langchain.messages import ToolMessage

    tool_response = ToolMessage(
    content='{"temperature": 25, "condition": "sunny"}', # 工具返回的内容
    tool_call_id="tool_call_123" # 关联的工具调用ID
    )

总结

这四种消息类型构成了 LangChain 对话交互的核心:

  • SystemMessage:定规则
  • HumanMessage:提问题
  • AIMessage:做回答
  • ToolMessage:连工具

使用模式

文本提示 (Text Prompts)

这是最简单直接的方式,直接传递字符串给模型,无需构建复杂的消息结构。

  • 使用示例

    1
    response = model.invoke("写一首关于春天的俳句")
  • 适用场景

    • 单个、独立的请求
    • 不需要维护对话历史
    • 希望代码复杂度最小,快速验证想法

消息提示 (Message Prompts)

使用消息对象列表(SystemMessageHumanMessageAIMessage 等),可以管理复杂的多轮对话和上下文。

  • 使用示例

    1
    2
    3
    4
    5
    6
    7
    8
    from langchain.messages import SystemMessage, HumanMessage, AIMessage

    messages = [
    SystemMessage("你是一位诗歌专家"),
    HumanMessage("写一首关于春天的俳句"),
    AIMessage("樱花盛开...") # 上一轮AI回复,用于构建对话历史
    ]
    response = model.invoke(messages)
  • 适用场景

    • 需要管理多轮对话历史
    • 处理多模态内容(图像、音频、文件)
    • 需要包含系统指令来定义 AI 角色

字典格式 (Dictionary Format)

直接使用 OpenAI 兼容的聊天完成格式,以字典列表的形式传递消息,适合从其他 OpenAI 兼容框架迁移代码。

  • 使用示例

    1
    2
    3
    4
    5
    6
    messages = [
    {"role": "system", "content": "你是一位诗歌专家"},
    {"role": "user", "content": "写一首关于春天的俳句"},
    {"role": "assistant", "content": "樱花盛开..."}
    ]
    response = model.invoke(messages)
  • 特点

    • 与 OpenAI API 格式完全兼容
    • 便于从其他框架(如 openai 库)迁移代码
    • LangChain 会自动将这些字典转换为内部的消息对象

总结

提示方式 特点 适用场景
文本提示 简单直接,代码最少 独立请求、快速验证
消息提示 结构化,支持多轮对话和多模态 复杂对话、需要系统指令
字典格式 OpenAI 兼容,便于迁移 从 OpenAI 生态迁移代码

标准内容块(Standard Content Blocks)

什么是 Content Blocks?

Content Blocks 是 LangChain v1 引入的标准化数据结构,用于在单条消息中组合文本、图像、音频等多种内容类型,为大模型提供更丰富的输入信息。

  • 它不是 content 属性的替代品,而是作为新属性补充,提供标准化的消息内容访问方式
  • 核心价值:
    • 提供统一的多模态内容表示标准
    • 支持复杂的多模态交互场景开发
    • 实现模型与外部工具的无缝集成
    • 显著提升 AI 应用的表达能力与交互体验

如何使用 content_blocks 属性

  1. 基础使用

    1
    2
    3
    4
    5
    6
    from langchain.messages import HumanMessage

    # 创建使用 content_blocks 属性的消息
    message = HumanMessage(
    content_blocks=[{"type": "text", "text": "今天天气如何?"}]
    )
  1. 在 Agent 中使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from langchain.messages import HumanMessage

    # 运行 Agent
    result = agent.invoke({
    "messages": [
    HumanMessage(
    content_blocks=[{"type": "text", "text": "今天天气如何?"}]
    )
    ]
    })

主要内容块类型

LangChain 支持多种内容块类型,适配不同场景:

类型 示例 用途
文本内容块 {"type": "text", "text": "这是一段文本内容"} 承载纯文本信息
图像内容块 {"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}} 传递图像链接或数据
音频内容块 {"type": "audio_url", "audio_url": {"url": "https://example.com/audio.mp3"}} 传递音频链接或数据
工具使用内容块 {"type": "tool_use", "id": "tool_call_123", "name": "get_weather", "params": {"city": "北京"}} 表示模型发起的工具调用
工具结果内容块 {"type": "tool_result", "tool_call_id": "tool_call_123", "content": '{"temperature": 25, "condition": "sunny"}'} 表示工具返回的结果

最佳实践与场景划分

LangChain 官方对 Content Blocks 的使用有明确推荐:

场景 推荐用法 原因
简单文本 HumanMessage("你是谁") 简洁、向后兼容,官方示例中大量使用
多媒体混合 HumanMessage(content_blocks=[...]) 多媒体支持、跨提供商统一、结构化访问
访问响应 response.content_blocks 标准化跨提供商访问

为什么这样划分:

  • content_blocks 不是替代品,只是一个新属性。
  • 简单文本用 content:没有必要为简单文本包装成 content_blocks
  • 多媒体用 content_blocks:需要混合文本、图片、音频时,明确指定每个块的类型和格式。

实际代码对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from langchain_core.messages import HumanMessage

# ✅ 简单文本:保持简洁
msg1 = HumanMessage("你是谁")

# ✅ 多媒体:用 content_blocks
msg2 = HumanMessage(
content_blocks=[
{"type": "text", "text": "分析这张图"},
{"type": "image", "url": "https://example.com/image.png", "mime_type": "image/png"}
]
)

# ✅ 读取响应时标准化访问
response = model.invoke([msg1])
for block in response.content_blocks:
if block["type"] == "text":
print(block["text"])

总结

Content Blocks 是 LangChain 为多模态交互设计的核心机制:

  • 简单场景:继续使用传统的 content 属性,保持代码简洁。
  • 多模态 / 工具交互场景:使用 content_blocks,获得标准化、跨模型兼容的能力。
  • 响应处理:通过 response.content_blocks 实现统一的结构化访问。

最佳实践

  • 角色与规则定义(基础定位)

    • 使用系统消息设置上下文:必须通过系统消息明确界定模型的角色、行为准则和回复要求,为对话奠定统一的执行基准。
  • 对话流程与结构管理(核心逻辑)

    • 遵循标准消息顺序:严格按照「系统消息→用户消息→助手消息」的固定顺序组织,确保模型能正确识别对话角色与上下文逻辑。
    • 妥善维护消息历史:多轮对话场景中,需实时、准确地更新对话历史(追加新消息),保障上下文的连续性。
    • 匹配任务选对格式:简单独立请求用文本提示(极简高效),复杂多轮对话用消息对象(结构化管理)。
  • 性能与资源管控(优化关键)

    • 监控上下文长度:时刻关注模型的上下文窗口限制,对超长对话及时进行截断、摘要或优化,避免超出限制导致的调用失败或上下文丢失。
  • 工程化落地保障(稳定性支撑)

    • 利用消息元数据:借助元数据记录会话 ID、用户标识、时间戳等信息,实现应用的追踪、审计与调试。
    • 完善错误处理:在消息构建、模型调用、响应解析等全流程,实现合理的错误捕获、重试机制,提升应用的健壮性。