Skip to main content
中断允许你在特定点暂停图的执行,等待外部输入后再继续。这启用了需要外部输入才能继续的人机协作模式。当中断被触发时,LangGraph 使用其持久化层保存图状态,并无限期等待直到你恢复执行。 中断通过在图节点中的任意位置调用 interrupt() 函数来工作。该函数接受任何 JSON 可序列化的值,并将其呈现给调用者。当你准备继续时,使用 Command 重新调用图来恢复执行,Command 随后成为节点内 interrupt() 调用的返回值。 与静态断点(在特定节点之前或之后暂停)不同,中断是动态的:它们可以放置在代码的任何位置,并可以基于应用逻辑进行条件判断。
  • 检查点保持你的位置: 检查点器写入精确的图状态,因此你可以在之后恢复,即使处于错误状态。
  • thread_id 是你的指针: 设置 config={"configurable": {"thread_id": ...}} 来告诉检查点器要加载哪个状态。
  • 中断载荷通过 chunk["interrupts"] 呈现: 当使用 version="v2" 流式输出时,你传给 interrupt() 的值会出现在 values 流式部分的 interrupts 字段中,让你知道图正在等什么。
你选择的 thread_id 实际上是你的持久化游标。重复使用它会恢复同一检查点;使用新值会启动一个具有空状态的全新线程。

使用 interrupt 暂停

interrupt 函数暂停图执行并向调用者返回一个值。当你在节点中调用 interrupt 时,LangGraph 保存当前图状态并等待你使用输入恢复执行。 使用 interrupt 需要:
  1. 一个检查点器来持久化图状态(生产环境中使用持久化检查点器)
  2. 配置中的线程 ID,以便运行时知道从哪个状态恢复
  3. 在你想暂停的地方调用 interrupt()(载荷必须是 JSON 可序列化的)
当你调用 interrupt 时,会发生以下事情:
  1. 图执行被挂起——恰好在调用 interrupt 的位置
  2. 状态被保存——使用检查点器以便稍后恢复执行。在生产环境中,这应该是持久化检查点器(例如由数据库支持)
  3. 值被返回——给调用者,位于 __interrupt__ 下;可以是任何 JSON 可序列化值(字符串、对象、数组等)
  4. 图无限期等待——直到你使用响应恢复执行
  5. 响应被传回——恢复时传入节点,成为 interrupt() 调用的返回值

恢复中断

在中断暂停执行后,你通过使用包含恢复值的 Command 重新调用图来恢复它。恢复值被传回 interrupt 调用,允许节点使用外部输入继续执行。
关于恢复的要点:
  • 恢复时必须使用与中断发生时相同的线程 ID
  • 传给 Command(resume=...) 的值成为 interrupt 调用的返回值
  • 恢复时节点从调用 interrupt节点开头重新启动,因此 interrupt 之前的任何代码会再次运行
  • 可以传递任何 JSON 可序列化值作为恢复值
Command(resume=...)唯一用于 invoke()/stream() 输入的 Command 模式。其他 Command 参数(updategotograph)设计用于从节点函数返回。不要传递 Command(update=...) 作为输入来继续多轮对话——请传递普通输入字典。

常见模式

中断解锁的关键能力是暂停执行并等待外部输入。这适用于多种用例,包括:

使用人机协作(HITL)中断进行流式输出

构建具有人机协作工作流的交互式智能体时,你可以同时流式输出消息块和节点更新,在处理中断的同时提供实时反馈。 使用多种流模式("messages""updates")配合 subgraphs=True(如果存在子图)来:
  • 实时流式输出 AI 响应
  • 检测图何时遇到中断
  • 处理用户输入并无缝恢复执行
  • version="v2":所有块都是具有 typensdata 键的 StreamPart 字典
  • chunk["type"]:根据流模式("messages""updates" 等)缩窄以进行类型推断
  • chunk["ns"]:标识源图(根图为空元组,子图时有填充)
  • subgraphs=True:嵌套图中的中断检测需要此选项
  • Command(resume=...):使用用户提供的数据恢复图执行

处理多个中断

当并行分支同时中断时(例如,扇出到多个节点,每个调用 interrupt()),你可能需要在单次调用中恢复多个中断。恢复多个中断时,将每个中断 ID 映射到其恢复值。这确保每个响应在运行时与正确的中断配对。

批准或拒绝

中断最常见的用途之一是在关键操作前暂停并请求批准。例如,你可能想让人类批准 API 调用、数据库更改或其他重要决策。
恢复图时,传递 True 批准或 False 拒绝:

审查和编辑状态

有时你想让人类在继续之前审查和编辑部分图状态。这对于纠正 LLM 输出、添加缺失信息或进行调整很有用。
恢复时,提供编辑后的内容:

工具中的中断

你也可以直接在工具函数中放置中断。这使工具本身在被调用时暂停以等待批准,并允许在执行前对工具调用进行人工审查和编辑。 首先,定义一个使用 interrupt 的工具:
这种方式在你希望批准逻辑与工具本身一起存在时很有用,使其在图的不同部分中可重用。LLM 可以自然地调用工具,中断会在工具被调用时暂停执行,允许你批准、编辑或取消操作。

验证人类输入

有时你需要验证人类输入,如果无效则再次询问。可以在循环中使用多个 interrupt 调用来实现。
每次使用无效输入恢复图时,它会以更清晰的消息再次询问。一旦提供有效输入,节点完成,图继续执行。

中断规则

当你在节点中调用 interrupt 时,LangGraph 通过抛出异常来挂起执行,该异常信号运行时暂停。此异常通过调用栈向上传播并被运行时捕获,通知图保存当前状态并等待外部输入。 当执行恢复时(在你提供请求的输入后),运行时从节点的开头重新启动整个节点——不会从调用 interrupt 的确切行恢复。这意味着 interrupt 之前运行的任何代码都会再次执行。因此,使用中断时需要遵循一些重要规则以确保行为符合预期。

不要将 interrupt 调用包装在 try/except 中

interrupt 通过抛出特殊异常来在调用点暂停执行。如果你将 interrupt 调用包装在 try/except 块中,你会捕获此异常,中断将不会传回图。
  • ✅ 将 interrupt 调用与容易出错的代码分开
  • ✅ 在 try/except 块中使用特定异常类型
  • 🔴 不要将 interrupt 调用包装在裸的 try/except 块中

不要在节点内重新排序 interrupt 调用

在单个节点中使用多个中断很常见,但如果处理不当可能导致意外行为。 当节点包含多个 interrupt 调用时,LangGraph 维护一个特定于执行该节点的任务的恢复值列表。每当执行恢复时,它从节点开头开始。对于遇到的每个 interrupt,LangGraph 检查任务恢复列表中是否存在匹配值。匹配是严格基于索引的,因此节点内 interrupt 调用的顺序很重要。
  • ✅ 保持 interrupt 调用在节点执行间保持一致
  • 🔴 不要在节点内有条件地跳过 interrupt 调用
  • 🔴 不要使用在执行间不确定的逻辑循环 interrupt 调用

不要在 interrupt 调用中返回复杂值

根据使用的检查点器,复杂值可能无法序列化(例如无法序列化函数)。为了使你的图适应任何部署,最佳实践是只使用可合理序列化的值。
  • ✅ 向 interrupt 传递简单的 JSON 可序列化类型
  • ✅ 传递具有简单值的字典/对象
  • 🔴 不要向 interrupt 传递函数、类实例或其他复杂对象

interrupt 之前调用的副作用必须是幂等的

因为中断通过重新运行所在节点来工作,在 interrupt 之前调用的副作用(理想情况下)应该是幂等的。幂等性意味着同一操作可以多次应用而不会改变初始执行之外的结果。 例如,你可能在节点内有更新记录的 API 调用。如果在该调用完成后调用 interrupt,当节点恢复时它会被多次重新运行,可能覆盖初始更新或创建重复记录。
  • ✅ 在 interrupt 之前使用幂等操作
  • ✅ 将副作用放在 interrupt 调用之后
  • ✅ 尽可能将副作用分离到单独的节点中
  • 🔴 不要在 interrupt 之前执行非幂等操作
  • 🔴 不要在不检查记录是否存在的情况下创建新记录

与作为函数调用的子图一起使用

在节点内调用子图时,父图将从调用子图并触发 interrupt节点开头恢复执行。同样,子图也将从调用 interrupt 的节点开头恢复。

使用中断进行调试

要调试和测试图,你可以使用静态中断作为断点,逐节点步进图的执行。静态中断在节点执行之前或之后的定义点触发。你可以在编译图时通过指定 interrupt_beforeinterrupt_after 来设置。
静态中断推荐用于人机协作工作流。请改用 interrupt 函数。
  1. 断点在 compile 时设置。
  2. interrupt_before 指定在节点执行前暂停的节点。
  3. interrupt_after 指定在节点执行后暂停的节点。
  4. 需要检查点器来启用断点。
  5. 图运行直到第一个断点被触发。
  6. 通过传入 None 作为输入来恢复图。将运行直到下一个断点被触发。
要调试你的中断,请使用 LangSmith

使用 LangSmith Studio

你可以使用 LangSmith Studio 在运行图之前在 UI 中设置静态中断。你还可以使用 UI 在执行的任何时间点检查图状态。 image