真正难的不是“LangGraph 里有没有 State”,而是:你的数据到底该怎么放,才能既方便模型理解,又方便节点协作和流程控制。
一、 这篇解决什么问题
很多人在第一次写 LangGraph 时,虽然已经知道 State 是全局状态,也知道节点返回的是状态补丁,但一到真正设计字段时,很快就会陷入混乱:
- 用户问题、工具结果、总结文本、路由标记、审批状态,到底是不是都能塞进 messages?
- 为什么有些数据放进 messages 很顺,但有些数据一放进去,整个图就越来越乱?
- 为什么有些字段必须单独拆出来,比如 question_type、need_search、approval_status?
- messages 和结构化字段之间,到底该怎么分工?
这篇文章要回答的核心问题就是:在 LangGraph 里,状态不仅要“能存”,更要“存得合理”。
二、 先给一句最短结论
如果你在设计状态时感到犹豫,请直接用这句话作为判断中轴:
messages 更适合存放“要持续喂给模型看的对话与工具交互历史”; 独立字段更适合存放“要给代码逻辑、路由判断和节点协作使用的结构化状态”。
进一步解释:
- 如果一段数据的主要用途是让模型继续理解上下文,优先考虑放进 messages。
- 如果一段数据的主要用途是让程序判断流程怎么走,优先考虑拆成独立字段。
三、 为什么“什么都塞进 messages”会出问题
在最开始做小 Demo 时,把所有中间信息都塞进 messages 看起来很省事。因为模型本来就会读 messages,工具结果也常常会回填成 ToolMessage,最后总结、判断、路由理由,好像也能当作文本塞进去。
但问题是,一旦流程稍微复杂一点,这种做法会迅速失控。
常见问题:
一句话总结:messages 很重要,但它不是万能垃圾桶。
四、 messages 到底适合放什么
最适合放进 messages 的内容:
一句话概括:messages 适合承载“对模型可见的交互历史”。
五、 什么时候必须拆成独立字段
这是状态设计的重头戏。适合拆字段的典型情况:
一句话总结:结构化字段不是为了“多建几个变量”,而是为了把状态从自然语言里解耦出来。
六、 一个最小反例:把所有东西都塞进 messages
用户问:“今天有哪些值得关注的 AI 新闻?”
如果你把下面这些全塞进 messages:
- 问题分类结果
- 是否需要搜索
- 搜索原始返回
- 搜索结果筛选理由
- 是否继续下一轮搜索
- 最终摘要
那么很快就会出现这些问题:路由节点要从文本里判断 need_search;总结节点要从一堆消息里硬扒搜索结果;模型每轮都被喂很多本来不必重复看的中间文本。状态既难维护,也难调试。
一句话点评:能跑不等于设计合理。
七、 一个正例:把 messages 和业务字段分开
真正的工程级设计,职责必须清晰分明。我们可以这样设计:
class State(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
question_type: str | None
need_search: bool
search_query: str | None
search_results: list[str] | None
summary: str | None
各字段分工:
- messages:保存用户问题、模型回复、工具消息。供模型继续理解上下文。
- question_type:给路由和节点逻辑判断问题类型。
- need_search:给条件边直接判断下一步是否进入搜索节点。
- search_query:给搜索节点用,不必每次都从消息文本里重解析。
- search_results:给总结节点读的结构化中间产物。
- summary:给最终回答节点用的中间结论。
八、 一个实用判断口诀
在实战中,你可以直接用这套口诀来拍板状态设计:
九、 常见误区
- 误区一:messages 就是 State 的全部。 不是。messages 很常见,但绝不是全部状态。
- 误区二:字段越少越高级。 不是。乱塞进 messages 反而会让设计更脆弱。
- 误区三:只要模型能读懂,就不用拆结构化字段。 这是典型误区。程序逻辑和模型理解是两套需求。
- 误区四:所有结构化字段都要暴露给模型。 也不一定。很多字段本来就只该给路由逻辑和节点代码使用。
十、 总结
在 LangGraph 里,State 的难点从来不只是“怎么存数据”,而是“怎么让数据在模型、节点和流程控制之间分工合理”。
messages 适合承载对模型可见的交互历史,独立字段适合承载程序要稳定读取和复用的结构化状态。
一旦你把所有东西都塞进 messages,图虽然也许还能跑,但很快就会变得脆弱、难调、难扩展;而一旦你学会把“对话上下文”和“业务状态”拆开,整个图的可维护性会明显上一个台阶。
所以,State 设计的关键不在于“字段越少越好”,而在于:每一份数据都应该出现在最适合它的位置。

