LangGraph框架中的StateGraph和MessageGraph是两种核心的图模型类,它们在状态管理、适用场景和实现原理上存在显著差异。以下从区别、原理和实例三方面进行详细对比:
一、核心区别
- 状态结构的灵活性
- StateGraph:
由用户定义的 状态对象(State) 参数化,支持自定义状态结构。例如,状态可以包含多个字段(如messages
、context
等),每个字段的更新通过reducer函数控制。
- StateGraph:
-
示例:
from typing import TypedDict class State(TypedDict): messages: Annotated[list[AnyMessage], add_messages] context: dict
这里messages
字段通过add_messages
函数追加新消息,而context
字段可自定义更新逻辑。
- MessageGraph:
状态默认为消息列表(List[BaseMessage]
),仅适用于对话场景。其状态更新完全依赖于add_messages
函数,无法扩展其他字段。
- 适用场景
- StateGraph:
适合需要复杂状态管理的场景,例如多步骤任务流程、多智能体协作、需要持久化上下文的系统(如游戏、机器人控制)。
- StateGraph:
-
示例:
from langgraph.graph import StateGraph graph = StateGraph(AgentState) # 自定义状态类
- MessageGraph:
专为对话系统设计,简化消息传递逻辑。例如聊天机器人、客服系统等,通过消息列表维护对话历史。
- MessageGraph:
- 代码复杂度
- StateGraph:
需要显式定义状态结构和reducer函数,灵活性高但配置复杂。 - MessageGraph:
自动管理消息列表,代码简洁但功能受限。
- StateGraph:
二、原理对比
-
StateGraph的原理
-
状态定义:
通过TypedDict
或Pydantic
模型定义状态结构,例如:class AgentState(TypedDict): input: str response: str
-
状态更新:
每个节点接收状态并返回更新后的状态,通过reducer函数控制字段更新。例如:def generate_response(state): return {"response": llm.invoke([HumanMessage(content=state["input"])])}
-
边的逻辑:
边决定节点之间的跳转逻辑,支持条件边(add_conditional_edges
)。
-
-
MessageGraph的原理
-
状态定义:
状态默认为MessagesState
,仅包含messages
字段(List[BaseMessage]
):class MessagesState(TypedDict): messages: Annotated[list[AnyMessage], add_messages]
-
状态更新:
所有节点操作直接作用于messages
列表,使用add_messages
函数追加消息。例如:def chatbot_node(state): return [("assistant", "Hello!")]
-
边的逻辑:
边基于消息内容决定跳转,例如根据用户输入选择下一个节点。
-
三、实例对比
1. 对话系统(MessageGraph)
-
场景:构建一个简单的聊天机器人,用户输入“Hi”,返回“Hello”。
-
代码:
from langgraph.graph.message import MessageGraph from langchain_core.messages import HumanMessage builder = MessageGraph() builder.add_node("chatbot", lambda state: [("assistant", "Hello!")]) builder.set_entry_point("chatbot") builder.compile().invoke([HumanMessage(content="Hi")])
-
特点:
直接操作messages
列表,无需自定义状态结构。
2. 多步骤任务流程(StateGraph)
-
场景:用户请求“查找最新AI论文”,需调用搜索工具和模型生成摘要。
-
代码:
from langgraph.graph import StateGraph from langchain_openai import ChatOpenAI from langchain_tools import DuckDuckGoSearchResults class AgentState(TypedDict): input: str response: str workflow = StateGraph(AgentState) workflow.add_node("agent", lambda state: {"response": llm.invoke([HumanMessage(content=state["input"])])}) workflow.add_node("search", lambda state: {"response": search.invoke([HumanMessage(content=state["input"])])}) workflow.add_edge("agent", "search") workflow.add_edge("search", END) workflow.compile().invoke({"input": "Find latest AI paper"})
-
特点:
使用自定义状态AgentState
,通过llm
和search
节点分步处理任务。
四、总结
- StateGraph更通用,适合复杂状态管理,但配置复杂;MessageGraph更简洁,专为对话系统设计。
- 选择依据:
- 若需多字段状态或复杂逻辑,优先使用StateGraph;
- 若仅需对话消息传递,MessageGraph更高效。
通过上述对比可见,两者的核心差异在于状态结构的灵活性和适用场景的针对性,开发者需根据具体需求选择合适的图模型类。