断点¶
断点在特定点暂停图的执行,并允许逐步执行。断点由 LangGraph 的 持久层 提供支持,该持久层在每个图步骤后保存状态。断点也可以用于启用 人机环路 工作流程,但我们建议为此目的使用 interrupt
函数。
要求¶
要使用断点,您需要
- 指定一个检查点 以在每个步骤后保存图状态。
- 设置断点 以指定执行应暂停的位置。
- 使用 线程 ID 运行图,以在断点处暂停执行。
- 使用
invoke
/ainvoke
/stream
/astream
恢复执行(参见Command
原语)。
设置断点¶
您可以在两个地方设置断点
- 在节点执行之前或之后通过在编译时或运行时设置断点。我们称这些为 静态断点。
- 在节点内部使用
NodeInterrupt
异常。
静态断点¶
静态断点在节点执行之前或之后触发。您可以通过在“编译”时或运行时指定 interrupt_before
和 interrupt_after
来设置静态断点。
graph = graph_builder.compile(
interrupt_before=["node_a"],
interrupt_after=["node_b", "node_c"],
checkpointer=..., # Specify a checkpointer
)
thread_config = {
"configurable": {
"thread_id": "some_thread"
}
}
# Run the graph until the breakpoint
graph.invoke(inputs, config=thread_config)
# Optionally update the graph state based on user input
graph.update_state(update, config=thread_config)
# Resume the graph
graph.invoke(None, config=thread_config)
graph.invoke(
inputs,
config={"configurable": {"thread_id": "some_thread"}},
interrupt_before=["node_a"],
interrupt_after=["node_b", "node_c"]
)
thread_config = {
"configurable": {
"thread_id": "some_thread"
}
}
# Run the graph until the breakpoint
graph.invoke(inputs, config=thread_config)
# Optionally update the graph state based on user input
graph.update_state(update, config=thread_config)
# Resume the graph
graph.invoke(None, config=thread_config)
注意
您不能在运行时为子图设置静态断点。如果您有子图,则必须在编译时设置断点。
如果您想一次单步执行一个节点来调试图执行,或者如果您想在特定节点暂停图执行,静态断点可能特别有用。
NodeInterrupt
异常¶
如果您尝试实现 人机环路 工作流程,我们建议您使用 interrupt
函数代替 NodeInterrupt
异常。interrupt
函数更易于使用且更灵活。
NodeInterrupt
异常
开发人员可以定义一些条件,必须满足这些条件才能触发断点。当开发人员想要在特定条件下停止图时,动态断点的概念很有用。这使用 NodeInterrupt
,这是一种特殊类型的异常,可以基于某些条件从节点内部引发。例如,我们可以定义一个动态断点,当 input
长度超过 5 个字符时触发。
def my_node(state: State) -> State:
if len(state['input']) > 5:
raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}")
return state
假设我们使用触发动态断点的输入运行图,然后尝试通过为输入传入 None
来简单地恢复图执行。
# Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint
for event in graph.stream(None, thread_config, stream_mode="values"):
print(event)
图将再次中断,因为此节点将使用相同的图状态重新运行。我们需要更改图状态,以使触发动态断点的条件不再满足。因此,我们可以简单地将图状态编辑为满足我们的动态断点条件(< 5 个字符)的输入,然后重新运行该节点。
# Update the state to pass the dynamic breakpoint
graph.update_state(config=thread_config, values={"input": "foo"})
for event in graph.stream(None, thread_config, stream_mode="values"):
print(event)
或者,如果我们想保留当前的输入并跳过执行检查的节点 (my_node
) 怎么办?为此,我们可以简单地使用 as_node="my_node"
执行图更新,并为值传入 None
。这将不会更新图状态,而是将更新作为 my_node
运行,从而有效地跳过节点并绕过动态断点。
其他资源 📚¶
- 概念指南:持久性:阅读持久性指南以获取有关持久性的更多上下文。
- 概念指南:人机环路:阅读人机环路指南以获取有关使用断点将人工反馈集成到 LangGraph 应用程序中的更多上下文。
- 如何查看和更新过去的图状态:使用图状态的分步说明,演示了 重放 和 分支 操作。