在 ​LangGraph​ 中,​interrupt​ 用于在节点执行过程中暂停整个图的运行,向用户或外部系统展示信息并等待输入;恢复时通过 ​Command(resume=...)​​ 把值送回图中继续执行。它常用于 ​Human-in-the-Loop​ 场景,如审批、编辑状态、澄清提问、工具调用前确认等。interrupt 依赖检查点持久化来保存与恢复状态,通常与 ​thread_id​ 配合使用以标识会话线程。

核心概念与工作机制

  • 触发中断:在节点函数内调用 ​interrupt(value)​,框架抛出 ​GraphInterrupt,图执行暂停;传入的 ​value​ 会随中断事件发送给客户端。

  • 恢复执行:客户端使用 ​Command(resume=...)​​ 提供恢复值,图从触发中断的节点“开头”重新执行(不是从中断行继续),并把 resume 值作为 ​interrupt() 的返回值

  • 多次中断:同一节点内允许多次调用 ​interrupt,恢复时按调用顺序进行“索引匹配”;恢复值列表的作用域限定在该节点的当前任务,不会跨任务共享。

  • 执行语义差异:与 Python 的 ​input()​​ 不同,interrupt 恢复后重跑节点开头到中断处的所有代码,因此应把副作用(如 API 调用)放在中断之后以避免重复。

  • 子图行为:当子图内发生中断,父图会从“调用子图的节点开头”恢复;子图自身从“触发中断的节点开头”恢复。

  • 检查点要求:使用中断需启用 ​checkpointer​(如 ​MemorySaver),否则无法在中断后正确恢复状态。

典型用法与代码示例

  • 基本用法

    • 节点内暂停并等待输入:

      from langgraph.types import interrupt
      def human_node(state):
          answer = interrupt("请提供反馈:")
          return {"feedback": answer}
    • 恢复执行并带回输入:

      from langgraph.types import Command
      # stream 直到中断
      for chunk in graph.stream({"key": "val"}, thread_config): ...
      # 恢复并继续
      for chunk in graph.stream(Command(resume="用户反馈内容"), thread_config): ...
  • 获取中断信息

    • 使用 ​stream/astream​ 会收到包含 ​​"interrupt"​​ 的事件;

    • 使用 ​invoke/ainvoke​ 不在返回值中直接给出中断信息,需在调用后用 ​graph.get_state(thread_config)​​ 获取状态与中断值。

  • 多次中断与验证

    def human_node(state):
        while True:
            ans = interrupt("请输入工龄(整数且>=0):")
            if isinstance(ans, int) and ans >= 0:
                return {"age": ans}
            # 否则继续循环,再次中断等待有效输入
  • 与 Command 的高级配合

    • 可在恢复时同时更新状态并跳转节点:

      Command(resume={"age": "25"}, update={"foo": "bar"}, goto="next_node")

      以上模式覆盖“等待人类输入、用输入更新状态、按条件跳转”的常见交互闭环。

静态断点与动态断点

  • 动态断点:在节点内部按条件调用 ​interrupt()​,最灵活,适合运行时判断是否需要人工介入。

  • 静态断点:在编译图时预置断点,例如

    graph = builder.compile(
        checkpointer=MemorySaver(),
        interrupt_before=["tools"],   # 调用 tools 前中断
        # interrupt_after=["step_1"], # 执行 step_1 后中断
    )

    适合在已知关键节点前/后统一设置“人工关卡”。生产中常以动态中断为主,静态中断用于调试或强约束关卡。

常见坑与最佳实践

  • 副作用放置:把 ​API 调用、写文件/数据库​ 等副作用放在 ​interrupt 之后,避免节点重跑导致重复调用。

  • 恢复语义:记住中断恢复会从节点“开头”重跑,不要依赖“中断行之后”的局部状态;需要“只执行一次”的逻辑应放在中断返回之后。

  • 多中断顺序:同一节点内多个 ​interrupt​ 的匹配按“索引顺序”,避免在运行时动态增删/重排中断调用,防止索引错配。

  • 线程与持久化:务必配置并传递 ​thread_id,并启用 ​checkpointer​(如 ​MemorySaver​ 或持久化存储),否则无法正确暂停与恢复。

  • 调试与发布:静态断点便于调试;发布时更推荐在关键业务节点内使用动态中断,精确控制人机交互时机。

  • 复杂交互:需要“多轮澄清/编辑”的场景,可结合 ​多轮对话模式编辑图状态审批/拒绝路由​ 等设计模式,用 ​Command(resume=...)​​ 回填结果并跳转到合适分支。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐