MetaGPT icon indicating copy to clipboard operation
MetaGPT copied to clipboard

ReAct loop can not stop gracefully, usually not stop.

Open Wei-Jianan opened this issue 1 year ago • 0 comments

Bug description

  1. I created a role that simply counts up to 3, after which the goal is considered accomplished. All the LLM I tried usually would not set next_state to -1 in role._think() when operating in ReAct mode.
  2. After I essentially solved 1. the role encountered difficulties in exiting gracefully.
2024-05-24 08:33:16.872 | INFO     | metagpt.roles.role:_think:397 - End actions with next_state=-1
2024-05-24 08:33:16.874 | WARNING  | metagpt.utils.common:wrapper:649 - There is a exception in role's execution, in order to resume, we delete the newest role communication message in the role's memory.
Traceback (most recent call last):
  File "/home/wei/kf/MetaGPT/metagpt/utils/common.py", line 640, in wrapper
    return await func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wei/kf/MetaGPT/metagpt/roles/role.py", line 551, in run
    rsp = await self.react()
          ^^^^^^^^^^^^^^^^^^
  File "/home/wei/kf/MetaGPT/metagpt/roles/role.py", line 520, in react
    rsp = await self._react()
          ^^^^^^^^^^^^^^^^^^^
  File "/home/wei/kf/MetaGPT/metagpt/roles/role.py", line 475, in _react
    rsp = await self._act()
          ^^^^^^^^^^^^^^^^^
  File "/home/wei/kf/MetaGPT/workspace/counter.py", line 53, in _act
    logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
                                                         ^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'name'

During handling of the above exception, another exception occurred:

Bug solved method

  1. 1716540205523 I suppose this issue arises because the LLM might get confused after being instructed 'Just answer a number between 0-{n_states}', and then being told 'If you think you have completed your goal and don't need to go to any of the stages, return -1.' LLM may not be able to return -1.
class Role(SerializationMixin, ContextMixin, BaseModel):
    async def _think(self) -> bool:
        """Consider what to do and decide on the next course of action. Return false if nothing can be done."""
        ....
        next_state = await self.llm.aask(prompt)
        next_state = extract_state_value_from_output(next_state)
        ....
        self._set_state(next_state)
===== after change =====
        return  next_state >= 0 
==== before changed =====
       return True

Wei-Jianan avatar May 24 '24 08:05 Wei-Jianan