Appearance
这一章我们具体讨论
- Graph API 的核心抽象是什么
- State 到底是什么
- Node 到底是什么
- Edge 到底是什么
- 为什么一定要 compile
- schema / multiple schemas / reducers 在解决什么问题
messages、channel这些词在这一层怎么理解
Graph API的核心抽象是什么
官方文档中提到,主要用到了三个关键组件
- State
- 一个共享数据结构,表示应用程序的当前快照,它可以是任何数据类型,但是通常是使用共享状态模式定义
- Nodes
- 节点,编码智能体逻辑的函数,它们接受当前状态作为输入,执行一些计算,并返回更新后的状态
- Edges
- 边,根据当前状态决定接下来执行哪个节点的函数,它们可以是条件分支,也可以是固定转换
State 到底是什么
- State 是应用当前快照的共享数据结构。
- State 通常由一个共享 state schema 定义。
- Graph 里的所有 Nodes 和 Edges,都会以这个 State schema 作为输入语义基础。
- State 不只是“字段集合”,还包括 reducer functions,用于定义节点更新如何应用到 state。
- schema 可以用
TypedDict、dataclass、Pydantic BaseModel来定义;官方还特别提示Pydantic验证强,但性能不如TypedDict或dataclass。
本质上是整张图的共享运行状态
Node 到底是什么
- Node 是 function。
- Node 接收当前 state 作为输入,执行计算或副作用,然后返回 state 的更新。
- 官方还特意强调:Nodes and Edges are nothing more than functions。
- Node 里面既可以放 LLM,也可以只是普通代码
Edge 到底是什么
- Edge 也是 function。
- Edge 的职责是:根据当前 state 决定下一个执行哪个 node。
- Edge 可以是固定跳转,也可以是条件分支。
node 负责“做事”,edge 负责“做完之后去哪”。
为什么 Graph 可以做循环、并行,而不是只是线性流程
- 通过组合 nodes 和 edges,可以形成 complex, looping workflows。
- 底层运行机制采用 message passing。
- 执行按离散的 super-steps 推进。
- 同一 super-step 中的 nodes 可以并行,顺序执行的 nodes 会分属不同 super-step。
- 当所有 nodes 都 inactive 且没有消息在传输中时,图执行结束。
为什么一定要 compile
- 构图流程是:先定义 state,再加 nodes 和 edges,最后 compile。
- compile 会做一些基本结构检查,比如 no orphaned nodes。
- compile 也是指定 runtime args 的地方,比如 checkpointers 和 breakpoints。
- 必须 compile 后才能使用 graph。
Schema 在解决什么问题
- graph 可以默认使用同一套 input/output schema。
- 也可以显式定义 input schema 和 output schema。
- 还可以有 internal/private state channels,用于图内部节点通信,而不是暴露给 graph 输入输出。
- 官方明确说了:不同 schema 的意义之一是:
- 输入输出不一定要暴露所有内部状态
- 内部节点之间可能需要私有通信字段。
state channels
部分原文直接用了这些说法:
- “same state channels”
- “private state channels”
- “write to any state channel in the graph state”
所以这里可以明确得出:
- 在 Graph API 这一层,官方虽然主要讲 State,但已经把 State 的 key/slot 看成 channels。
- 也就是说,state 和 channel 在这里不是完全不同的两套世界,而是同一运行模型在不同抽象层上的表述。这个判断还会在 Pregel runtime 那篇被进一步坐实。
Reducer 在解决什么问题
- 节点返回的不是完整 state,而是 state update。
- 这些 update 如何应用到每个 key,由 reducer 决定。
- 默认 reducer 是 override。
- 也可以通过
Annotated[..., add]这类方式定义“累加/合并”式 reducer。