Sunday面试指南

LangGraph 的 Pregel 和 Super-step 是什么?并行节点何时能读到新状态?

下面是一段教学模拟,不是真实面试记录。

🧑‍💻 面试官:LangGraph 的两个节点并行运行,一个先写入状态,另一个能马上读到吗?

🙋‍♂️ 我:应该能吧,毕竟它们使用的是同一份 State。

🧑‍💻 面试官:那后完成的节点读到什么,岂不是取决于前一个节点跑得有多快?

🙋‍♂️ 我:那是不是需要给 State 加锁?

🧑‍💻 面试官:先不讨论锁。你能说清一个 Super-step 内,状态更新什么时候对其他节点可见吗?

这里要抓住的是「分轮提交」:同一超步内先读取已有状态,节点完成后再更新;新值在下一超步才能被读取。

面试速答(60 秒版)

Pregel 是 LangGraph 的图执行运行时。我们可以把一个 Super-step 理解成一轮调度,而不是一个节点或一次模型调用。

每轮先选出要执行的节点,再让这些节点并行运行,最后将本轮产生的更新写入状态。因此,同一超步里的节点不能依靠另一个节点刚返回的更新继续计算,新状态要到下一超步才可见。

如果两个节点都要更新同一个字段,还需要看这个字段怎样合并。没有合适的 Reducer,不能想当然地认为后完成的节点会覆盖前一个。

设计图时,独立任务可以并行;一个任务要用另一个任务的结果,就应该安排到后续超步。这样才能把数据依赖和执行顺序说清楚。

Super-step:一轮结束再见新状态:本轮提交,下一轮可见

知识点详解:并行执行为什么还要分超步?

先把一轮执行拆成三个阶段

假设用户问:“比较两款数据库的部署成本。”我们安排两个节点分别查资料,再让第三个节点做比较。

在这一轮开始前,State 里只有问题,没有任何检索结果。

运行时首先进行计划:根据图的连接关系和已更新的通道,确定这轮有哪些节点需要执行。接着进入执行阶段,两个检索节点并行工作。等本轮执行完成,再进入更新阶段,将结果提交到相应的状态通道。

因此,Super-step 描述的是一次“选节点、执行、提交”的完整轮次。一个超步可以运行多个节点,某个节点也可能在自己的代码里调用模型多次。这几个计数不能混在一起。官方运行时说明

快节点完成了,慢节点为什么还不能读新值?

假设节点 A 用一秒查完数据库甲,节点 B 用三秒查完数据库乙。

A 返回的结果是本轮的待提交更新。它完成得早,不代表 B 在本轮读取的图状态就跟着改变。

时点A 与 B 本轮可读取的图状态本轮待提交的更新
本轮开始用户问题,暂无检索结果无
A 完成,B 仍在运行仍是本轮开始时可见的状态A 的结果
本轮更新完成下一轮可见两份结果已提交
比较节点开始可以读取两份结果尚未生成比较结论

这套规则避免了“谁跑得快,谁就改变另一个节点输入”的隐含依赖。

不过,这里说的是运行时管理的状态通道,不是 Python 或 JavaScript 里所有对象都会自动隔离。节点如果偷偷修改共享对象、写外部数据库,仍可能产生竞争。不要把框架的状态提交规则当成全局并发安全保证。

快节点结束,慢节点读到什么:同轮不读其他节点新写入

Reducer 解决合并,不解决依赖顺序

如果 A、B 都返回一个检索结果列表,我们可以为这个字段配置合并规则,把两份列表拼起来。

Reducer 要回答的是:同一字段收到多个更新,最终如何得到一个值?它不会让 B 在执行中途看见 A,也不会替我们判断哪条资料更可信。

没有相应合并规则的字段遇到并发更新,可能触发更新冲突,而不是自动采用“最后一个完成的结果”。具体字段定义应按实际版本核对。状态与 Reducer 文档

另外,即使列表能够拼接,也不应依赖节点完成速度来确定业务顺序。如果后续要按数据库名称展示,就在合并后明确排序;如果顺序有业务意义,就把顺序作为数据保存。

有依赖的任务,要放到下一轮

比较节点必须同时拿到甲、乙的资料,才能生成结论。图里应该明确表达这个汇合关系,而不是让它在 A 返回时先运行,再猜测 B 的结果是否已经存在。

我们可以先画清楚三件事:

  • 哪些节点只依赖本轮开始时的状态,可以一起运行。
  • 哪些节点必须等待上一批结果,应该放到后续轮次。
  • 哪些字段会被多个节点更新,需要定义合并规则。

这个方法比“全部并行会更快”更实用。并行只能缩短可以同时做的工作,不能消除数据依赖。

面试官继续追问

一轮里有三个并行节点,算三个 Super-step 吗?

不算。它们如果由同一轮调度并行执行,就属于同一个 Super-step。节点数量、模型调用次数和超步数量分别统计。

本轮一个节点报错,其他节点的外部操作也会撤销吗?

不会因为图状态尚未统一更新,就自动撤销已经发生的邮件发送或数据库写入。涉及外部副作用时,仍要设计幂等、重试和补偿;不能把超步理解成跨所有系统的数据库事务。

给每个字段都加列表拼接 Reducer,就不会有冲突了吗?

这可能让更新“合得起来”,却不保证含义正确。例如审批状态不应该把“通过”和“拒绝”拼成列表后直接使用。要先确定字段代表什么,再决定允许什么更新,以及遇到冲突时如何处理。

面试速记卡

  • Pregel:LangGraph 的图执行运行时。
  • Super-step:计划、执行、更新组成的一轮调度,不等于一个节点。
  • 状态可见性:本轮产生的新更新,下一超步才可读取。
  • Reducer:定义字段怎样合并更新,不负责改变节点依赖关系。
  • 工程边界:图状态的分轮提交,不等于外部操作自动回滚。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历