LangGraph 源码学习总结 3-单结点图的执行分析

把 LangGraph 的"三步"一次看个够

------从官方文档、示例到源码的完整拆解

一、Pregel 的"三步"模型

官方给出的执行模型如下,关键模型是 Plan、Execution、Update.核心概念有 Actors、Channels

python 复制代码
"""Pregel manages the runtime behavior for LangGraph applications.

## Overview

Pregel combines [**actors**](https://en.wikipedia.org/wiki/Actor_model)
and **channels** into a single application.
**Actors** read data from channels and write data to channels.
Pregel organizes the execution of the application into multiple steps,
following the **Pregel Algorithm**/**Bulk Synchronous Parallel** model.

Each step consists of three phases:

- **Plan**: Determine which **actors** to execute in this step. For example,
    in the first step, select the **actors** that subscribe to the special
    **input** channels; in subsequent steps,
    select the **actors** that subscribe to channels updated in the previous step.
- **Execution**: Execute all selected **actors** in parallel,
    until all complete, or one fails, or a timeout is reached. During this
    phase, channel updates are invisible to actors until the next step.
- **Update**: Update the channels with the values written by the **actors**
    in this step.

Repeat until no **actors** are selected for execution, or a maximum number of
steps is reached.

## Actors

An **actor** is a `PregelNode`.
It subscribes to channels, reads data from them, and writes data to them.
It can be thought of as an **actor** in the Pregel algorithm.
`PregelNodes` implement LangChain's
Runnable interface.

## Channels

Channels are used to communicate between actors (`PregelNodes`).
Each channel has a value type, an update type, and an update function -- which
takes a sequence of updates and
modifies the stored value. Channels can be used to send data from one chain to
another, or to send data from a chain to itself in a future step. LangGraph
provides a number of built-in channels:

### Basic channels: LastValue and Topic

- `LastValue`: The default channel, stores the last value sent to the channel,
   useful for input and output values, or for sending data from one step to the next
- `Topic`: A configurable PubSub Topic, useful for sending multiple values
   between *actors*, or for accumulating output. Can be configured to deduplicate
   values, and/or to accumulate values over the course of multiple steps.

### Advanced channels: Context and BinaryOperatorAggregate

- `Context`: exposes the value of a context manager, managing its lifecycle.
  Useful for accessing external resources that require setup and/or teardown. eg.
  `client = Context(httpx.Client)`
- `BinaryOperatorAggregate`: stores a persistent value, updated by applying
   a binary operator to the current value and each update
   sent to the channel, useful for computing aggregates over multiple steps. eg.
  `total = BinaryOperatorAggregate(int, operator.add)`

LangGraph 把一次图计算拆成无限循环的三步,直到没有任务可跑或达到步数上限:

  1. Plan(选节点)
    看哪些通道的值在上轮被改过,把订阅这些通道的节点挑出来。
  2. Execution(跑节点)
    并发执行被选中的节点;节点读通道、算结果、把"写请求"攒进自己的 writes 列表,但此时并不真正写回通道
  3. Update(落数据)
    等本轮所有节点跑完,一次性把 writes 里的 (channel, value) 写进通道,并更新 checkpoint 版本号。

下一轮再拿新的通道版本重新做 Plan,如此往复。

二、示例验证------单节点图

代码只有 11 行,却完整走了一遍三步:

python 复制代码
from langgraph.channels import EphemeralValue
from langgraph.pregel import Pregel, Channel

node1 = (
    Channel.subscribe_to("a")   # 订阅通道 a
    | (lambda x: x + x)         # 业务逻辑
    | Channel.write_to("b")     # 写通道 b
)
app = Pregel(
    nodes={"node1": node1},
    channels={"a": EphemeralValue(str), "b": EphemeralValue(str)},
    input_channels=["a"],
    output_channels=["b"],
)
print(app.invoke({"a": "foo"}))     # → {'b': 'foofoo'}

Plan :首轮只有 a 被外部输入更新 → 选中 node1
Executionnode1 算出 "foofoo",把 ("b", "foofoo") 塞进自己的 writes。
Updateapply_writes 把 writes 真正写进通道 b,checkpoint 版本号刷新。

下一轮 Plan 发现没有任何通道再被更新,循环结束,返回 {'b': 'foofoo'}

三、源码级定位

  1. Plan
    .venv/lib/python3.12/site-packages/langgraph/pregel/algo.py
    prepare_next_tasks(...)

    • 先处理上轮残留的 pending_sends(PUSH 任务)
    • 再根据 updated_channels + trigger_to_nodes 快速圈出本轮被触发的节点(PULL 任务)
  2. Execution
    .venv/lib/python3.12/site-packages/langgraph/pregel/runner.py
    PregelRunner.tick(...)

    • 并发跑任务,回调 commit(task, exc) 把每个任务产生的原始 writes 缓存起来
    • 本身碰通道,只负责"跑完并收集写请求"
  3. Update

    仍在 algo.py ------ apply_writes(checkpoint, channels, tasks, None)

    • SyncPregelLoop / AsyncPregelLoop下一轮开头 调用
    • 一次性把所有 writes 应用到通道,更新版本号,完成真正的"通道更新"

四、总结

官方文档、示例、源码三者互相印证:
Plan 决定谁跑,Execution 只算不写,Update 集中落盘 ,最终借鉴Pregel、BSP模型实现图的额执行。

相关推荐
SCBAiotAigc1 天前
langchain1.x学习笔记(三):langchain之init_chat_model的新用法
人工智能·python·langchain·langgraph·deepagents
vibag5 天前
构建智能体与工具调用
python·语言模型·大模型·langgraph
deephub5 天前
Agentic RAG:用LangGraph打造会自动修正检索错误的 RAG 系统
人工智能·大语言模型·rag·langgraph
vibag5 天前
使用底层API构建图
人工智能·语言模型·langchain·大模型·langgraph
vibag5 天前
实现ReACT智能体
python·语言模型·langchain·大模型·langgraph
vibag5 天前
LangGraph全家桶使用
python·语言模型·langchain·大模型·langgraph
组合缺一6 天前
灵动如画 —— 初识 Solon Graph Fluent API 编排
java·solon·graph·flow·langgraph·liquor
带刺的坐椅7 天前
灵动如画 —— 初识 Solon Graph Fluent API 编排
java·ai·agent·solon·flow·langgraph
大模型RAG和Agent技术实践9 天前
SQL Agent从“黑盒“到“全透明“:基于LangGraph+Phoenix的可观测性实战指南
数据库·人工智能·sql·agent·langgraph
╭⌒若隐_RowYet——大数据12 天前
AI Agent开发实战QuickStart
ai·langchain·agent·langgraph·langsmith·langfuse