W
AI-Wiki
ENTITY

CompiledStateGraph

定义

CompiledStateGraphStateGraph 在调用 compile() 之后得到的可执行图对象,用来承接图的实际运行。 它不是开发者绕开图定义过程、直接手写出来的“运行器”,而是 builder 完成声明与校验后产出的运行时实例。

在本文语境里,一个关键纠偏是:StateGraph 不是运行器,CompiledStateGraph 才是真正能运行的对象。

在 LangGraph 体系中的位置

LangGraph 被概括为 State + Node + Edge + Runtime。其中:

  • StateGraph 负责 builder 侧工作,也就是声明图结构。
  • CompiledStateGraph 负责 runtime 侧工作,也就是把图真正跑起来。

换句话说,开发者先用 StateGraph 把路“画出来”,再通过 compile() 产出 CompiledStateGraph 去执行这张图。 这对应文中的工程化分工:builder 负责定义,compiled graph 负责运行。

它从哪里来

CompiledStateGraph 的来源非常明确:

  1. 先创建 StateGraph
  2. add_node 注册节点。
  3. add_edgeadd_conditional_edges 注册固定路线与条件路线。
  4. 调用 compile()
  5. 得到 CompiledStateGraph

因此,CompiledStateGraph 不是独立于 StateGraph 存在的平行概念,而是后者完成结构组装后的编译结果。

为什么说它才是“真正能运行”的对象

原文把这一点说得很直接:compile() 之后,才有 invokestreamainvoke 这些执行能力。 这意味着:

  • 仅有 StateGraph 时,你拿到的是图定义器,不是执行器。
  • 调用 compile() 后,才进入可运行阶段。
  • 所谓图的运行、流式执行、异步调用,都属于 CompiledStateGraph 的职责范围。

这也是很多初学者容易混淆的地方:看见图已经定义了节点和边,就误以为图本身已经可以执行;但在本文语境中,真正可执行的边界就是是否已经产出 CompiledStateGraph

执行能力

CompiledStateGraph 至少承接了文中明确提到的三类执行入口:

  • invoke:直接运行图。
  • stream:以流式方式运行图。
  • ainvoke:以异步方式运行图。

文末总结也再次强调了这一点:

  • compile 用于“检查结构,生成可执行图”。
  • invoke / stream 用于“运行图,逐步更新状态”。

这说明执行 API 不属于 builder 阶段,而属于编译后的运行时对象。

它的可执行性建立在 compile 校验通过之上

CompiledStateGraph 不是“无条件生成”的;它依赖 compile() 先完成结构校验。 原文给出的校验重点包括:

  • 有没有孤立节点。
  • 入口和出口是否合理。
  • 分支目标是否存在。

用户给定的事实要求中,还强调了节点连通性这一层含义;这与“有没有孤立节点”是同一类结构正确性问题。 因此可以把它理解为:只有当图的基本结构成立、入口出口清楚、分支跳转目标真实存在、节点连通关系可接受时,builder 才能被编译成可执行的 CompiledStateGraph

也就是说,CompiledStateGraph 的“能运行”,并不是凭空获得的,而是建立在前置结构检查已经通过的基础上。

与 StateGraph 的职责边界

StateGraph 负责什么

StateGraph 的职责是收集和组织图定义信息。原文列出的内容包括:

  • 节点
  • 状态 schema
  • 条件分支
  • 通道
  • reducer

它在初始化阶段会准备若干内部容器:

  • nodes:存节点
  • edges:存固定边
  • branches:存条件分支
  • channels:存状态通道

同时,它还会解析 State schema,提前准备“哪些字段能更新、怎么合并”。

CompiledStateGraph 负责什么

CompiledStateGraph 不再承担“声明图结构”的工作,而是承担“执行这张图”的工作。 也就是:

  • 按图结构激活节点
  • 让节点读取当前 State
  • 接收节点返回的 Partial State
  • 配合 reducer 完成状态合并
  • 按边和条件边把控制流交给下一个节点
  • 提供同步、流式、异步等运行入口

因此,两者不是功能重复,而是构建期与运行期的分工。

它所运行的图是什么样的

为了理解 CompiledStateGraph 的职责,需要把它放回 LangGraph 的运行模型里看。 原文强调,图的执行不是一条死链,而更像消息传递:

  1. 某个节点被激活。
  2. 节点读取当前状态。
  3. 执行自己的逻辑。
  4. 写回状态更新。
  5. 通过边把控制权交给下一个节点。

节点本身可以是很多种实现:

  • LLM
  • RAG
  • Tool
  • 人工审批
  • 普通 Python 逻辑

但对图运行器来说,关键约束只有一个:节点读入 State,返回 Partial State。

CompiledStateGraph 运行的正是这样一张已经定义好节点、边、分支和状态合并规则的图。

与状态合并的关系

原文特别强调:复杂 Agent 的节点不要返回整份 State,而是只返回自己改动的部分,然后由 LangGraph 根据 reducer 合并。 这点虽然不是专门给 CompiledStateGraph 下定义,但它直接说明了运行时对象在执行阶段所依赖的机制:

  • 节点执行后产出的是局部更新。
  • 运行时需要按照既定 reducer 把这些更新合并回总状态。
  • 在并行节点、多个结果、列表追加、消息合并等场景里,这种机制尤其关键。

因此,CompiledStateGraph 的运行能力不是简单“按顺序调用函数”,而是建立在状态通道与 reducer 语义已经在 builder 阶段准备好的前提上。

细节与边界

它不是图定义器

如果你还在 add_nodeadd_edgeadd_conditional_edges,你处理的仍然是 StateGraph,不是 CompiledStateGraph

它不是 compile 之前就可运行

原文非常明确:compile() 之后,才有 invokestreamainvoke。 所以“定义完图就能直接跑”的理解是不准确的。

它的运行能力依赖结构正确

如果图存在孤立节点、入口出口不合理、分支目标不存在等问题,就不会进入可靠的可执行状态。

它属于 LangGraph 的 Runtime 一侧

State + Node + Edge + Runtime 这套拆分里,CompiledStateGraph 更接近 Runtime 的承载对象,而 StateGraph 更接近图声明阶段的 builder。

它不等于业务逻辑本身

原文最后强调,LangGraph 不是替你写业务逻辑,而是让复杂 Agent 的业务逻辑“有结构、有状态、有边界”。 对应到这里,CompiledStateGraph 负责把结构化好的业务图跑起来,但不替代节点内部的业务实现。

为什么这个概念重要

在复杂 Agent 场景里,系统往往需要:

  • 分支
  • 循环
  • 状态恢复
  • 人工审批
  • 多 Agent 协作

文章的核心观点是:这类需求最终会把系统推向图式编排。 而一旦进入图式编排,开发者就必须分清:

  • 哪部分是在“定义图”
  • 哪部分是在“运行图”

CompiledStateGraph 的重要性,就在于它把这种边界清楚地落到了对象层面:StateGraph 负责声明,CompiledStateGraph 负责执行。

相关条目