3.5. 预定义状态
3.5.1. MessagesState
LangGraph 构建的计算图通常会和 LLM 结合使用,而 LLM 在运行过程中通常需要维护一组消息列表。为了提升开发效率,LangGraph 官方提供了一个预定义状态类型:langgraph.graph.message.MessagesState。
开发者可以直接继承该状态类型,并在其基础上扩展自定义状态字段。
源码如下:
class MessagesState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
由此可知,MessagesState 只有一个字段:messages。
该字段的类型是列表,元素类型为 AnyMessage;同时,它通过 Annotated 绑定了内置 Reducer 函数 add_messages。
add_messages 的完全限定名(英文全称 fully qualified name)是:
langgraph.graph.message.add_messages,正是上文 3.2.2.3.2 节介绍的内置 Reducer 函数。
示例如下:
from typing import NotRequired
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import MessagesState
from langchain_core.messages import HumanMessage
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv
load_dotenv(verbose=True)
model = ChatDeepSeek(
model="deepseek-v4-flash",
extra_body={"thinking": {"type": "enabled"}},
)
class OverAllState(MessagesState):
username: str
output: NotRequired[str] # 关键:改为可选
# 不返回 output,让它保持未设置状态(或者返回空字符串)
def node_a(state: OverAllState) -> OverAllState:
return {
"messages": [HumanMessage(content="你好,我是" + state["username"])],
"username": state["username"],
}
def llm_node(state: OverAllState) -> OverAllState:
res = model.invoke(state["messages"])
return {
"messages": [res],
"username": state["username"],
"output": res.content,
}
builder = StateGraph(state_schema=OverAllState)
builder.add_node("llm_node", llm_node)
builder.add_node("node_a", node_a)
builder.add_edge(START, "node_a")
builder.add_edge("node_a", "llm_node")
builder.add_edge("llm_node", END)
graph = builder.compile()
result = graph.invoke({"username": "小黄"})
print(result)
输出如下
{
"messages": [
HumanMessage(
content="你好,我是 小黄",
additional_kwargs={},
response_metadata={},
id="155e1ef4-5bbc-4250-b978-62a7a5918cef",
),
AIMessage(
content="你好呀,小黄!😊 我是DeepSeek,很高兴认识你!有什么我可以帮你的吗?无论是聊天、解答问题、帮你写作、编程,还是其他任何需要,尽管告诉我吧!你名字里的"黄"是哪个黄呀?😄",
additional_kwargs={
"refusal": "None",
},
response_metadata={
"token_usage": {
"completion_tokens": 57,
"prompt_tokens": 10,
"total_tokens": 67,
"completion_tokens_details": "None",
"prompt_tokens_details": {
"audio_tokens": "None",
"cached_tokens": 0,
},
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 10,
},
"model_provider": "deepseek",
"model_name": "deepseek-v4-flash",
"system_fingerprint": "fp_8b330d02d0_prod0820_fp8_kvcache_20260402",
"id": "17d57633-2ffb-4af3-be87-b3d58f9acd2b",
"finish_reason": "stop",
"logprobs": "None",
},
id="lc_run--019e6890-4544-7212-b4f2-aa20fc079911-0",
tool_calls=[],
invalid_tool_calls=[],
usage_metadata={
"input_tokens": 10,
"output_tokens": 57,
"total_tokens": 67,
"input_token_details": {
"cache_read": 0,
},
"output_token_details": {},
},
),
],
"username": "小黄",
"output": "你好呀,小黄!😊 我是DeepSeek,很高兴认识你!有什么我可以帮你的吗?无论是聊天、解答问题、帮你写作、编程,还是其他任何需要,尽管告诉我吧!你名字里的"黄"是哪个黄呀?😄",
}
上述案例中,OverAllState 继承了 MessagesState,因此可用的状态字段为
messages
username
output
只关注 messages 状态,执行流程如下:
node_a返回一条HumanMessage;LangGraph使用add_messages将该消息合并到messages状态字段中;llm_node从state["messages"]中读取完整消息列表,并调用模型;llm_node将模型生成的AIMessage作为状态更新返回;LangGraph再次通过add_messages将AIMessage合并到messages中;- 最终状态中包含完整消息列表。
MessagesState 帮开发者预先定义好了 messages 字段及其合并规则。在构建聊天机器人、Agent、工具调用流程、多轮对话流程时,它可以提升开发效率。
3.5.2. AgentState
AgentState 是 LangChain Agent 内部使用的状态类型。由于 LangChain Agent 底层也是基于 LangGraph 运行图构建的,所以从技术上讲,开发者也可以将 AgentState 或其子类作为自定义 LangGraph 的状态类型。
AgentState 的全类名,也可以称为类的完全限定名(英文全称: fully qualified class name)是:langchain.agents.middleware.types.AgentState
源码如下
class AgentState(TypedDict, Generic[ResponseT]):
"""State schema for the agent."""
messages: Required[Annotated[list[AnyMessage], add_messages]]
jump_to: NotRequired[Annotated[JumpTo | None, EphemeralValue, PrivateStateAttr]]
structured_response: NotRequired[Annotated[ResponseT, OmitFromInput]]
该状态中主要包含三个字段。
messages
messages: Required[Annotated[list[AnyMessage], add_messages]]
messages 用于存储 Agent 运行过程中的消息列表。
该字段和 MessagesState 中的 messages 字段类似,也使用 add_messages 作为 Reducer。
jump_to
jump_to: NotRequired[Annotated[JumpTo | None, EphemeralValue, PrivateStateAttr]]
jump_to 是 LangChain Agent 内部使用的控制字段,主要服务于 Agent 中间件体系。
它通常用于表示运行流程的跳转意图,例如某些中间件希望影响 Agent 后续应该进入哪个节点。
需要注意的是,jump_to 并不是普通 LangGraph 状态图中的通用跳转机制。
在自定义 StateGraph 中,即使状态中定义了 jump_to 字段,LangGraph 也不会因为该字段的值自动跳转到某个节点。普通 LangGraph 运行图如果需要控制后续流向,通常应使用:
Command(goto="node_name")
见下文。
structured_response
structured_response: NotRequired[Annotated[ResponseT, OmitFromInput]]
structured_response 用于存储 Agent 最终生成的结构化输出。
当使用 LangChain Agent 的结构化输出能力时,例如指定 response_format,Agent 最终生成的结构化结果通常会被写入该字段。
其中,OmitFromInput 表示该字段不应作为外部输入字段暴露给调用方,而是由 Agent 运行过程中内部生成。
总体来看,AgentState 是专门为 LangChain Agent 运行时设计的状态类型。
因此,在普通自定义 LangGraph 项目中,一般不建议直接基于 AgentState 扩展图状态。