run-llama / llama_index

LlamaIndex is a data framework for your LLM applications
https://docs.llamaindex.ai
MIT License
36.2k stars 5.16k forks source link

[Bug]: Infinite ReAct loop when setting max_iterations as 1 #16499

Open rjwharry opened 1 week ago

rjwharry commented 1 week ago

Bug Description

When I set max_iterations to 1, my ReAct Agent stuck in infinite loop.

Version

0.11.14

Steps to Reproduce

Set query that agent can't find information from tool.

agent = ReActAgent.from_tools(
    tools,
    llm=llm,
    max_iterations=1,
    verbose=True,
)
agent.astream_chat(query)

Relevant Logs/Tracbacks

No response

dosubot[bot] commented 1 week ago

When max_iterations is set to 1, the ReActAgent should perform only one iteration and then stop. If it's entering an infinite loop, it might be due to the agent not correctly identifying when a response is complete. The agent should break out of the loop if it determines it cannot answer the question with the provided tools [1][2].

Ensure that the logic for determining a complete response is correctly implemented. If the agent is not following the expected behavior, it might be a bug in version 0.11.14. You may want to check if the handle_reasoning_failure_fn is correctly handling failures, as it can prevent infinite loops by managing reasoning failures [3].

To continue talking to Dosu, mention @dosu.

rjwharry commented 1 week ago

_get_response function in ReActAgentWorker is checking iterations. In current situation, But if current_reasoning starts from 2 and max_iterations is 1, then ReAct agent will be stuck in infinite loop.
So my suggestion is to modify operator == to > when comparing len(current_reasoning) and max_iterations like below.

def _get_response(
        self,
        current_reasoning: List[BaseReasoningStep],
        sources: List[ToolOutput],
    ) -> AgentChatResponse:
        """Get response from reasoning steps."""
        if len(current_reasoning) == 0:
            raise ValueError("No reasoning steps were taken.")
        elif len(current_reasoning) > self._max_iterations:
            raise ValueError("Reached max iterations.")