题意:在 LangGraph Agent 执行过程中出现的间歇性 UnboundLocalError
问题背景:
I'm experiencing an intermittent error in my LangGraph-based agent system. The error occurs in my main agent class, which uses other custom agents as its tools. The error doesn't happen every time, but it occurs frequently enough to be a significant issue.
我在基于LangGraph的代理系统中遇到了一个间歇性的错误。这个错误发生在我的主代理类中,该类使用其他自定义代理作为工具。这个错误并不是每次都会发生,但发生频率足够高,以至于成为了一个严重的问题。
Here's the error I'm seeing: 这是我遇到的错误:
An error occurred: local variable 'fut' referenced before assignment
Traceback (most recent call last):
...
File "/Users/yosef/uni/Uni chat store/llm/agents.py", line 326, in run
return self.build().graph.invoke({'messages': [HumanMessage(content=messages)]})['messages'][-1].content
File "/Users/yosef/uni/Uni chat store/venv/lib/python3.10/site-packages/langgraph/pregel/__init__.py", line 1448, in invoke
for chunk in self.stream(
File "/Users/yosef/uni/Uni chat store/venv/lib/python3.10/site-packages/langgraph/pregel/__init__.py", line 980, in stream
del fut, task
UnboundLocalError: local variable 'fut' referenced before assignment
here is my agent class 这是我的代理类
class AgentState(TypedDict):
messages: Annotated[list[AnyMessage], operator.add]
class Agent:
def __init__(self, model, tools, system="", print_tool_result=False):
self.system = system
graph = StateGraph(AgentState)
graph.add_node("llm", self.call_openai)
graph.add_node("action", self.take_action)
graph.add_conditional_edges(
"llm",
self.exists_action,
{True: "action", False: END}
)
graph.add_edge("action", "llm")
graph.set_entry_point("llm")
self.graph = graph.compile()
self.graph.step_timeout = 10
self.tools = {t.name: t for t in tools}
self.model = model.bind_tools(tools)
self.print_tool_result = print_tool_result
def exists_action(self, state: AgentState):
result = state['messages'][-1]
return len(result.tool_calls) > 0
def call_openai(self, state: AgentState):
messages = state['messages']
if self.system:
messages = [SystemMessage(content=self.system)] + messages
message = self.model.invoke(messages)
return {'messages': [message]}
def take_action(self, state: AgentState):
tool_calls = state['messages'][-1].tool_calls
results = []
for t in tool_calls:
print(f"Calling: {t}")
if not t['name'] in self.tools: # check for bad tool name from LLM
print("\n ....bad tool name....")
result = "bad tool name, retry" # instruct LLM to retry if bad
else:
result = self.tools[t['name']].invoke(input=t['args'])
if self.print_tool_result:
# print in blue
print(f"\033[94m{result}\033[0m")
results.append(ToolMessage(tool_call_id=t['id'], name=t['name'], content=str(result)))
print("Back to the model!")
return {'messages': results}
I've tried the following: 我尝试了以下方法:
-
Upgraded to the latest version of LangGraph 将LangGraph更新到了最新版本
-
Changed print statements to logging 修改打印日志语句
问题解决:
This issue occurs because the step_timeout is set to a short duration for CompiledGraph. It can be reproduced, for example, by following the step_timeout example provided in the migration guide for the LangGraph's AgentExecutor. The cause lies in setting a timeout for concurrent.futures.wait, which allows the subsequent process to continue even if no tasks have been completed, i.e., even if done is an empty set. Since done is an empty set, the else processing triggers an UnboundLocalError.
这个问题出现的原因是因为在CompiledGraph中设置了较短的step_timeout
。这个问题可以通过遵循LangGraph的AgentExecutor迁移指南中提供的step_timeout
示例来复现。问题的根源在于为concurrent.futures.wait
设置了超时,这允许后续进程在没有任务完成的情况下(即,即使done
是空集)也能继续执行。由于done
是空集,因此触发了else
处理中的UnboundLocalError
。
I perceive this as a bug in the LangGraph library. To avoid this, it is necessary to include the process of exiting the while loop when done is an empty set before the for loop. As a temporary workaround, please set step_timeout to a longer duration or avoid setting it altogether.
我认为这是LangGraph库中的一个错误。为了避免这个问题,有必要在for循环之前包含退出while循环的过程,即当done为空集时退出。作为临时的解决方法,请将step_timeout设置为更长的持续时间,或者完全避免设置它。