У меня периодически возникает ошибка в моей системе агентов на основе LangGraph. Ошибка возникает в моем основном классе агентов, который использует в качестве своих инструментов другие специальные агенты. Ошибка возникает не каждый раз, но она возникает достаточно часто, чтобы стать серьезной проблемой.
Вот ошибку, которую я вижу:
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
вот мой класс агента
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}
Я пробовал следующее:
Обновлен до последней версии LangGraph.
Операторы печати изменены на ведение журнала.
Эта проблема возникает из-за того, что для CompiledGraph для параметра Step_timeout установлена короткая продолжительность. Его можно воспроизвести, например, следуя примеру Step_timeout, приведенному в руководстве по миграции для AgentExecutor LangGraph. Причина кроется в установке таймаута для concurrent.futures.wait, который позволяет продолжить последующий процесс, даже если ни одна задача не была завершена, т. е. даже если сделано — пустой набор. Поскольку сделано — это пустой набор, обработка else вызывает ошибку UnboundLocalError.
Я воспринимаю это как ошибку в библиотеке LangGraph. Чтобы этого избежать, необходимо включить процесс выхода из цикла while, когда Done представляет собой пустой набор перед циклом for. В качестве временного решения установите для параметра Step_timeout более продолжительное значение или вообще не устанавливайте его.
Кажется, ошибка, связанная с таймаутом, исправлена в LangGraph 0.1.9