如何在达到递归限制之前返回状态¶
设置图的递归限制可以帮助您控制图的运行时间,但如果达到递归限制,图将返回一个错误——这可能并不适用于所有用例。相反,您可能希望在达到递归限制之前返回状态的值。本指南将向您展示如何做到这一点。
设置环境¶
首先,让我们安装所需的包:
使用LangSmith为LangGraph开发进行设置
注册LangSmith,可以快速发现并解决问题,提高您的LangGraph项目的性能。LangSmith允许您使用跟踪数据来调试、测试和监控使用LangGraph构建的LLM应用程序——更多关于如何开始的信息,请参阅这里。
不返回状态¶
在这个示例中,我们将定义一个虚拟图,它将始终达到递归限制。首先,我们将实现一个不返回状态的版本,并展示它达到递归限制的情况。这个图基于ReAct架构,但与实际做出决策和采取行动不同,它只是无限循环。
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
from langgraph.graph import START, END
class State(TypedDict):
value: str
action_result: str
def router(state: State):
if state["value"] == "end":
return END
else:
return "action"
def decision_node(state):
return {"value": "keep going!"}
def action_node(state: State):
# Do your action here ...
return {"action_result": "what a great result!"}
workflow = StateGraph(State)
workflow.add_node("decision", decision_node)
workflow.add_node("action", action_node)
workflow.add_edge(START, "decision")
workflow.add_conditional_edges("decision", router, ["action", END])
workflow.add_edge("action", "decision")
app = workflow.compile()
API Reference: StateGraph | START | END
让我们验证我们的图将始终达到递归限制:
from langgraph.errors import GraphRecursionError
try:
app.invoke({"value": "hi!"})
except GraphRecursionError:
print("Recursion Error")
带返回状态¶
为了避免达到递归限制,我们可以在状态中引入一个新的键,称为remaining_steps
。它将跟踪达到递归限制前的步骤数量。然后我们可以检查remaining_steps
的值,以确定是否应该终止图执行并将状态返回给用户而不引发RecursionError
。
为此,我们将使用一个特殊的RemainingSteps
注解。在内部,它创建了一个特殊的ManagedValue
通道——一个状态通道,它将在图运行期间存在,之后不再存在。
由于我们的action
节点将始终诱导至少2个额外步骤到图中(因为action
节点总是会在之后调用decision
节点),我们将使用此通道来检查我们是否距离限制还有2步。
现在,当我们运行图时,应该不会收到任何错误,而是会收到在达到递归限制之前的状态的最后一个值。
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
from typing import Annotated
from langgraph.managed.is_last_step import RemainingSteps
class State(TypedDict):
value: str
action_result: str
remaining_steps: RemainingSteps
def router(state: State):
# Force the agent to end
if state["remaining_steps"] <= 2:
return END
if state["value"] == "end":
return END
else:
return "action"
def decision_node(state):
return {"value": "keep going!"}
def action_node(state: State):
# Do your action here ...
return {"action_result": "what a great result!"}
workflow = StateGraph(State)
workflow.add_node("decision", decision_node)
workflow.add_node("action", action_node)
workflow.add_edge(START, "decision")
workflow.add_conditional_edges("decision", router, ["action", END])
workflow.add_edge("action", "decision")
app = workflow.compile()
API Reference: StateGraph
完美!我们的代码运行没有任何错误,正如我们所预期的!