【LangChain】langchain_core.messages.BaseMessage 类:定义对话消息的基本结构和行为的抽象基类

在 LangChain 中,langchain_core.messages.BaseMessagelangchain_core.messages 模块中的核心抽象基类,用于表示对话中的消息。它为所有具体消息类型(如 HumanMessageAIMessageSystemMessage 等)提供了统一的接口和基础功能。BaseMessage 的设计目标是标准化消息的结构和行为,确保消息能够在聊天模型、代理、记忆模块和其他 LangChain 组件中无缝传递和处理。

以下是对 langchain_core.messages.BaseMessage 的详细介绍,涵盖其定义、功能、核心属性与方法、实现方式、应用场景、代码示例、优化建议、注意事项以及与 LangChain 生态的结合。


1. 什么是 BaseMessage

BaseMessage 是一个抽象基类,定义了对话消息的基本结构和行为。消息是 LangChain 对话系统的核心组件,表示用户、模型、工具或其他实体之间的交互内容。BaseMessage 提供了以下功能:

  • 统一消息格式:标准化消息的属性(如内容、角色、元数据)。
  • 支持多模态:允许消息内容包含文本、图像或其他数据类型。
  • 序列化:支持消息的 JSON 序列化和反序列化,便于存储或传输。
  • 扩展性:允许开发者继承并创建自定义消息类型。

核心目标

  • 提供一致的消息表示,简化对话管理和上下文传递。
  • 支持复杂交互,如工具调用、多轮对话和多模态输入。
  • 与 LangChain 的聊天模型、代理、记忆等模块无缝集成。

子类

  • HumanMessage:用户发送的消息。
  • AIMessage:模型生成的消息,可能包含工具调用。
  • SystemMessage:系统指令或提示。
  • ToolMessage:工具调用结果。
  • ChatMessage:任意角色的自定义消息。
  • FunctionMessage:旧版函数调用结果(已废弃,推荐 ToolMessage)。

2. 功能与特点

BaseMessage 提供了以下核心功能:

  1. 消息结构
    • 定义消息的核心属性:content(内容)、role(角色)、additional_kwargs(元数据)。
    • 支持多模态内容(如文本+图像的列表)。
  2. 序列化与反序列化
    • 支持将消息转换为 JSON 格式,或从 JSON 还原。
    • 便于存储对话历史或跨系统传输。
  3. 类型安全
    • 使用 Pydantic 模型,确保字段验证和类型一致性。
  4. 扩展性
    • 允许子类添加特定字段(如 tool_callsAIMessage 中)。
    • 支持自定义消息类型。
  5. 对话上下文
    • 作为消息列表的一部分,传递给聊天模型或代理,构建对话历史。
  6. 工具调用支持
    • 通过子类(如 AIMessageToolMessage)支持工具调用请求和结果。

特点

  • 抽象化:提供通用接口,屏蔽具体消息类型的实现细节。
  • 模块化:与 LangChain 的提示模板、代理、记忆等模块无缝协作。
  • 跨模型兼容:支持 OpenAI、Anthropic、HuggingFace 等模型的消息格式。
  • 轻量高效:结构简单,易于序列化和处理。

3. 核心属性与方法

核心属性

属性类型描述示例
contentUnion[str, List[Dict]]消息内容,可以是字符串或多模态内容(如文本+图像)。"Hello"[{"type": "text", "text": "Hi"}, {"type": "image_url", "image_url": {"url": "image.jpg"}}]
rolestr消息的角色,子类定义具体值(如 "human""assistant")。"human"
additional_kwargsDict[str, Any]附加元数据,如时间戳、ID 或模型特定参数。{"timestamp": "2025-05-15"}
typestr消息类型,自动由子类设置。"human"(对于 HumanMessage

注意

  • content 通常是字符串,但在多模态模型(如 GPT-4o)中可以是包含文本、图像等的列表。
  • role 由子类定义,BaseMessage 本身不强制具体值。
  • additional_kwargs 用于存储任意元数据,增强灵活性。

核心方法

方法描述输入输出示例
to_json将消息序列化为 JSON 格式。Dictmessage.to_json()
from_json从 JSON 还原消息对象(类方法)。DictBaseMessageBaseMessage.from_json(json_data)
__str__返回消息的字符串表示。strstr(message)
__eq__比较两个消息是否相等。BaseMessageboolmessage1 == message2

子类特定属性/方法

  • AIMessage:添加 tool_calls(工具调用请求列表)。
  • ToolMessage:添加 tool_call_id(工具调用 ID)。
  • 其他子类可能定义特定行为或字段。

4. 使用方式与代码示例

(1) 创建基本消息

创建 HumanMessageSystemMessage

from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI

# 初始化模型
llm = ChatOpenAI(api_key="your-openai-key")

# 创建消息
messages = [
    SystemMessage(content="你是一个量子计算专家,回答要简洁。"),
    HumanMessage(content="量子计算是什么?")
]

# 调用模型
response = llm.invoke(messages)
print(response.content)

输出

量子计算是一种基于量子力学原理的计算范式,使用量子比特进行计算。

说明

  • SystemMessage 设置对话上下文。
  • HumanMessage 表示用户输入。
  • 消息列表传递给 BaseChatModel 实例。

(2) 工具调用与 ToolMessage

处理工具调用和结果:

from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool

# 定义工具
@tool
def calculator(expression: str) -> str:
    """执行数学计算"""
    return str(eval(expression))

# 初始化模型并绑定工具
llm = ChatOpenAI(api_key="your-openai-key").bind_tools([calculator])

# 创建消息
messages = [HumanMessage(content="计算 5 + 3")]

# 调用模型
response = llm.invoke(messages)

# 处理工具调用
if response.tool_calls:
    tool_call = response.tool_calls[0]
    tool_result = calculator.invoke(tool_call["args"])
    messages.extend([
        AIMessage(content="", tool_calls=[tool_call]),
        ToolMessage(content=tool_result, tool_call_id=tool_call["id"])
    ])

# 继续对话
final_response = llm.invoke(messages)
print(final_response.content)

输出

计算结果为 8。

说明

  • AIMessage 包含 tool_calls,指定工具和参数。
  • ToolMessage 反馈工具结果,通过 tool_call_id 关联。

(3) 多模态消息

处理文本+图像输入(需要支持多模态的模型,如 GPT-4o):

from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI

# 初始化模型
llm = ChatOpenAI(model="gpt-4o", api_key="your-openai-key")

# 创建多模态消息
messages = [
    HumanMessage(content=[
        {"type": "text", "text": "描述这张图片的内容。"},
        {"type": "image_url", "image_url": {"url": "https://example.com/quantum.jpg"}}
    ])
]

# 调用模型
response = llm.invoke(messages)
print(response.content)

输出(假设图片可用):

图片显示一台量子计算机的实验设备,周围有冷却装置和控制面板。

说明

  • content 为列表,包含文本和图像 URL。
  • 仅支持多模态模型。

(4) 序列化与反序列化

将消息序列化为 JSON 并还原:

from langchain_core.messages import HumanMessage

# 创建消息
message = HumanMessage(content="量子计算是什么?", additional_kwargs={"id": "msg_001"})

# 序列化为 JSON
json_data = message.to_json()
print(json_data)

# 从 JSON 还原
restored_message = HumanMessage.from_json(json_data)
print(restored_message.content, restored_message.additional_kwargs)

输出

{'type': 'human', 'content': '量子计算是什么?', 'additional_kwargs': {'id': 'msg_001'}}
量子计算是什么? {'id': 'msg_001'}

说明

  • to_json 返回消息的字典表示。
  • from_json 还原为 BaseMessage 子类实例。

(5) 自定义消息类型

继承 BaseMessage 创建自定义消息:

from langchain_core.messages import BaseMessage
from typing import Any, Dict

# 自定义消息类
class CustomMessage(BaseMessage):
    role: str = "custom"
    custom_field: str

    def __init__(self, content: str, custom_field: str, **kwargs: Any):
        super().__init__(content=content, additional_kwargs=kwargs)
        self.custom_field = custom_field

# 创建自定义消息
message = CustomMessage(content="Hello", custom_field="test")
print(message)
print(message.custom_field)

输出

content='Hello' role='custom' additional_kwargs={}
test

说明

  • 继承 BaseMessage 添加自定义字段和逻辑。
  • 需定义 role 和其他必要属性。

(6) 结合代理

在代理中使用 BaseMessage 子类:

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_core.tools import Tool
from langchain_core.callbacks import StdOutCallbackHandler
from langchain_core.runnables import RunnableConfig

# 定义工具
def search_web(query: str) -> str:
    return f"搜索结果:{query} 的最新信息..."

search_tool = Tool(name="SearchWeb", func=search_web, description="搜索网络信息")

# 初始化模型
llm = ChatOpenAI(model="gpt-4o", api_key="your-openai-key")

# 设置提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个研究助手,擅长搜索信息。"),
    MessagesPlaceholder(variable_name="messages"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 创建代理
agent = create_openai_tools_agent(llm, [search_tool], prompt)
agent_executor = AgentExecutor(agent=agent, tools=[search_tool], verbose=True)

# 配置 RunnableConfig
config = RunnableConfig(callbacks=[StdOutCallbackHandler()], max_iterations=3)

# 执行任务
response = agent_executor.invoke({
    "messages": [HumanMessage(content="量子计算的最新进展是什么?")]
}, config=config)
print(response["output"])

输出

[AgentExecutor] 正在执行...
[Tool: SearchWeb] 输入:量子计算的最新进展
[Tool Output] 搜索结果:量子计算的最新信息...
[Final Answer] 量子计算的最新进展包括超导量子比特的突破...

5. 应用场景

BaseMessage 及其子类适用于以下场景:

  1. 多轮对话
    • 构建聊天机器人,维护对话历史。
    • 示例:连续回答“量子计算是什么?”和“它有什么应用?”。
  2. 工具调用
    • 处理代理或链中的工具交互。
    • 示例:代理调用搜索工具并反馈结果。
  3. 上下文增强
    • 使用 SystemMessage 设置模型行为或提供背景。
    • 示例:指定“以专家身份回答”。
  4. 多模态交互
    • 处理文本+图像或文本+音频的对话。
    • 示例:描述图片内容。
  5. 对话记忆
    • 结合 ConversationBufferMemory 存储消息历史。
    • 示例:实现长期对话的上下文保持。
  6. 自定义交互
    • 创建自定义消息类型,满足特定需求。
    • 示例:添加业务特定的元数据。

6. 优化建议

(1) 提高消息管理效率

  • 精简消息
    • 仅保留必要的对话历史,减少 token 消耗。
    messages = messages[-10:]  # 保留最后 10 条消息
    
  • 压缩历史
    • 使用 ConversationSummaryMemory 压缩长对话。
    from langchain.memory import ConversationSummaryMemory
    memory = ConversationSummaryMemory(llm=llm)
    

(2) 提高工具调用可靠性

  • 验证工具调用
    • 检查 tool_calls 是否有效。
    if not response.tool_calls:
        print("无工具调用")
        return response.content
    
  • 匹配 tool_call_id
    • 确保 ToolMessagetool_call_idAIMessage 一致。
    tool_message = ToolMessage(content=result, tool_call_id=tool_call["id"])
    

(3) 提高性能

  • 序列化优化
    • 批量序列化消息,减少 I/O 开销。
    json_data = [msg.to_json() for msg in messages]
    
  • 异步处理
    • 结合异步模型调用处理消息。
    response = await llm.ainvoke(messages)
    

(4) 监控与调试

  • 回调
    • 使用回调记录消息处理。
    from langchain_core.callbacks import BaseCallbackHandler
    class MessageCallback(BaseCallbackHandler):
        def on_chat_model_start(self, serialized, messages, **kwargs):
            print(f"输入消息:{messages}")
    config = {"callbacks": [MessageCallback()]}
    
  • LangSmith
    • 分析消息流和性能。
    from langsmith import Client
    config = {"callbacks": [Client(api_key="your-langsmith-key")]}
    

(5) 上下文优化

  • 动态系统消息
    • 根据任务调整 SystemMessage
    system_message = SystemMessage(content=f"今天是 {datetime.now().strftime('%Y-%m-%d')},回答要简洁。")
    
  • 元数据管理
    • 使用 additional_kwargs 存储上下文。
    message = HumanMessage(content="Hi", additional_kwargs={"user_id": "user_001"})
    

7. 注意事项

  • 抽象基类
    • BaseMessage 不可直接实例化,需使用子类(如 HumanMessage)。
  • 模型兼容性
    • 多模态消息需要模型支持(如 GPT-4o)。
    • 工具调用需要模型支持 tool_calls(如 GPT-4、Claude)。
  • 消息长度
    • 过多的消息或长内容可能超过模型的 token 限制。
    • 使用截断或总结策略。
  • 工具调用一致性
    • 确保 ToolMessagetool_call_idAIMessagetool_calls 匹配。
  • 序列化
    • 确保 JSON 数据格式正确,避免反序列化错误。
    try:
        msg = HumanMessage.from_json(json_data)
    except ValueError as e:
        print(f"反序列化失败:{e}")
    
  • 安全性
    • 避免在 contentadditional_kwargs 中包含敏感信息。
    • 验证用户输入,防止注入攻击。
  • 废弃警告
    • FunctionMessage 已废弃,推荐使用 ToolMessage

8. 与 LangChain 生态的结合

  • 聊天模型(Chat Models)
    • 消息传递给 BaseChatModel 实例(如 ChatOpenAI)。
    llm.invoke(messages)
    
  • 提示模板(Prompt Templates)
    • 使用 ChatPromptTemplate 管理消息。
    from langchain_core.prompts import ChatPromptTemplate
    prompt = ChatPromptTemplate.from_messages([("human", "{input}")])
    
  • 代理(Agents)
    • 消息用于代理的输入和工具调用。
    agent.invoke({"messages": [HumanMessage(content="Hi")]})
    
  • 工具(Tools)
    • AIMessageToolMessage 支持工具调用。
    messages.append(ToolMessage(content=tool_result, tool_call_id=tool_call["id"]))
    
  • 记忆(Memory)
    • 结合 ConversationBufferMemory 存储消息。
    from langchain.memory import ConversationBufferMemory
    memory = ConversationBufferMemory(return_messages=True)
    
  • 回调(Callbacks)
    • 使用 RunnableConfig 配置回调。
    config = {"callbacks": [StdOutCallbackHandler()]}
    

9. 综合示例:多模态代理

以下是一个结合 BaseMessage、多模态输入和代理的完整示例:

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_core.tools import Tool
from langchain_core.callbacks import StdOutCallbackHandler
from langchain_core.runnables import RunnableConfig
import os
import getpass

# 配置 API 密钥
if not os.environ.get("OPENAI_API_KEY"):
    os.environ["OPENAI_API_KEY"] = getpass.getpass("请输入 OpenAI API 密钥:")

# 定义工具
def search_web(query: str) -> str:
    return f"搜索结果:{query} 的最新信息..."

search_tool = Tool(name="SearchWeb", func=search_web, description="搜索网络信息")

# 初始化模型
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# 设置提示模板
prompt = ChatPromptTemplate.from_messages([
    SystemMessage(content="你是一个研究助手,擅长处理多模态输入和搜索。"),
    MessagesPlaceholder(variable_name="messages"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 创建代理
agent = create_openai_tools_agent(llm, [search_tool], prompt)
agent_executor = AgentExecutor(agent=agent, tools=[search_tool], verbose=True)

# 配置 RunnableConfig
config = RunnableConfig(callbacks=[StdOutCallbackHandler()], max_iterations=3)

# 创建多模态消息
messages = [
    HumanMessage(content=[
        {"type": "text", "text": "搜索量子计算的最新进展,并描述这张图片的内容。"},
        {"type": "image_url", "image_url": {"url": "https://example.com/quantum.jpg"}}
    ])
]

# 执行任务
response = agent_executor.invoke({"messages": messages}, config=config)
print(response["output"])

输出(假设图片可用):

[AgentExecutor] 正在执行...
[Tool: SearchWeb] 输入:量子计算的最新进展
[Tool Output] 搜索结果:量子计算的最新信息...
[Final Answer] 量子计算的最新进展包括超导量子比特的突破。图片显示一台量子计算机的实验设备。

10. 学习资源


11. 总结

  • 定义BaseMessage 是 LangChain 中消息的抽象基类,定义对话消息的结构和行为。
  • 核心属性
    • content:消息内容(字符串或多模态)。
    • role:消息角色。
    • additional_kwargs:元数据。
  • 核心方法
    • to_jsonfrom_json:序列化/反序列化。
    • __str____eq__:字符串表示和比较。
  • 功能:统一消息格式、支持多模态、序列化、工具调用、上下文管理。
  • 应用场景:多轮对话、工具调用、上下文增强、多模态交互、记忆管理、自定义交互。
  • 优化点:消息管理、工具调用可靠性、性能、监控、上下文优化。
  • 注意事项:抽象基类、模型兼容性、消息长度、工具调用一致性、序列化、安全性、废弃警告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值