LangChain 不用原生字典、而是用 SystemMessage/HumanMessage/AIMessage 这类类对象,核心不是 “炫技”,而是为了强类型安全、跨模型统一、可扩展能力、可观测与可序列化,并支撑它整个链式 / Agent 架构。下面从动机、好处、底层实现三方面讲清楚。


一、原生字典有什么问题?

OpenAI 原生是这样的:

python

运行

[
    {"role": "system", "content": "你是助手"},
    {"role": "user", "content": "你好"}
]

缺点很明显:

  1. 无类型校验,易写错
    • 手敲 {"role":"uesr"}、漏 content、值类型错(list/str 混用),运行时才炸,难排查。
  2. 多模型格式不统一
    • OpenAI:role/system/user/assistant
    • Anthropic:role/human/assistant,无 system
    • 本地 / Ollama / 国产模型:字段、嵌套结构各不相同→ 直接用字典,换一个模型就要重写一套消息组装逻辑
  3. 难以承载复杂信息
    • 多模态(图文混排)、工具调用(tool_calls)、token 用量、消息 ID、会话元数据…… 字典会变成松散、难维护的大杂烩LangChain。
  4. 代码可读性与可维护差
    • isinstance(msg, dict) 判断角色不直观;
    • 多轮历史拼接、记忆存取、链式传递,全靠手动 key 取值,极易出错
  5. 不支持结构化扩展与序列化
    • 字典不好做校验、默认值、方法扩展
    • 要持久化到 Redis / 数据库、跨进程传输,需要自己写序列化 / 反序列化。

二、LangChain 用类对象的核心好处

1. 强类型安全(Pydantic 加持)

所有消息继承自 BaseMessage(Pydantic 模型):

python

运行

class SystemMessage(BaseMessage):
    role: str = "system"  # 固定,不可改
  • 自动校验:role 只能是固定值、content 类型合法;
  • 提前报错:写错参数定义时 / 初始化时就抛错,不是运行时;
  • IDE 友好:自动补全、类型提示。

2. 跨模型 “一次编写,到处运行”

LangChain 核心目标是屏蔽底层差异

  • 上层永远用 SystemMessage/HumanMessage/AIMessage
  • 底层适配器(ChatOpenAI/ChatAnthropic/ChatOllama)自动把对象转成对应厂商字典

你可以无缝切换:

python

运行

# OpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 换成 Ollama,消息代码完全不用改
llm = ChatOpenAI(base_url="http://localhost:11434/v1", model="qwen:7b")

3. 天然支持复杂能力(工具调用 / 多模态 / 流式)

AIMessage 直接带扩展字段:

python

运行

class AIMessage(BaseMessage):
    role: str = "assistant"
    tool_calls: Optional[List[ToolCall]] = None  # 函数调用
    usage_metadata: Optional[dict] = None          # token 统计
    response_metadata: Optional[dict] = None       # 厂商返回元数据
  • 工具调用不用自己设计字典结构,直接读写 tool_calls
  • 多模态:LangChain 1.0+ 的 content_blocks 统一表示图文 / 音频;
  • 流式分片AIMessageChunk 继承自 BaseMessage,天然支持 chunk 合并LangChain。

4. 支撑记忆、链式、Agent 架构

LangChain 的 Memory、Chain、Agent 全部基于 BaseMessage 流转:

  • 记忆组件InMemoryChatMessageHistory 直接存 / 取消息对象,不用解析字典;
  • Runnable 链RunnableWithMessageHistory 自动拼接历史,依赖统一消息结构;
  • Agent 工具循环:靠 isinstance(msg, AIMessage) 判断是否要调用工具,类型判断清晰

5. 可观测、可序列化、可持久化

  • 序列化对象 ↔ 字典双向无损转换,适配 Redis / 数据库 / 网络传输;
  • 回调 / 日志统一的 message.idusage_metadata,便于追踪、计费、调试LangChain;
  • 版本兼容:新增字段不破坏旧代码,平滑演进。

三、底层实现:LangChain 怎么把对象变成 OpenAI 字典?

流程很清晰:

  1. 上层:你写消息对象列表

    python

    运行

    [SystemMessage("你是助手"), HumanMessage("你好")]
    
  2. 模型适配器内部(如 ChatOpenAI._convert_messages):

    python

    运行

    def _convert_messages(messages):
        return [
            {"role": msg.role, "content": msg.content}
            for msg in messages
        ]
    
  3. 发请求:把转换后的原生字典发给 OpenAI;
  4. 返回结果:把 OpenAI 返回的 assistant 字典,自动转回 AIMessage

简单说:上层面向对象,底层自动翻译为原生字典,两边好处都占。


四、一句话总结

原生字典是 **“面向 OpenAI 的临时方案”,而 LangChain 的消息类是“面向多模型、复杂对话系统的工程化标准”—— 用类对象换来了类型安全、统一抽象、能力扩展、架构支撑 **,这是做企业级、可维护、可扩展 LLM 应用的必然选择。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐