如何在达到递归限制之前返回状态¶
设置图的递归限制可以帮助您控制图运行的时长,但如果达到递归限制,您的图将返回错误——这可能并非所有用例都理想。相反,您可能希望在达到递归限制 之前 返回状态的值。本操作指南将向您展示如何做到这一点。
设置¶
首先,让我们安装所需的包
为 LangGraph 开发设置 LangSmith
注册 LangSmith 以快速发现问题并提高您的 LangGraph 项目的性能。LangSmith 允许您使用追踪数据来调试、测试和监控您使用 LangGraph 构建的 LLM 应用程序——在此处阅读更多关于如何入门的信息。
不返回状态¶
在此示例中,我们将定义一个总是达到递归限制的虚拟图。首先,我们将在不返回状态的情况下实现它,并展示它如何达到递归限制。此图基于 ReAct 架构,但它只是无限循环,而不是实际做出决策和采取行动。
API 参考:StateGraph | START | END
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()
让我们验证我们的图是否总是会达到递归限制
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 个步骤以内。
现在,当我们运行图时,应该不会收到任何错误,而是得到在达到递归限制之前状态的最后一个值。
API 参考:StateGraph
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()
太好了!我们的代码没有错误地运行了,正如我们预期的那样!