react_parser.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. class ReActParser(object):
  2. def __init__(self):
  3. self.action = '\nAction:'
  4. self.action_input = '\nAction Input:'
  5. self.action_input_stop = '\nObservation:'
  6. self.observation = '\nObservation:'
  7. self.observation_stop = '\nThought:'
  8. def parse_latest_plugin_call(self, text):
  9. action = self.action
  10. action_input = self.action_input
  11. observation = self.action_input_stop
  12. plugin_name, plugin_args = '', ''
  13. i = text.rfind(action)
  14. j = text.rfind(action_input)
  15. k = text.rfind(observation)
  16. if 0 <= i < j: # If the text has `Action` and `Action input`,
  17. if k < j: # but does not contain `Observation`,
  18. # then it is likely that `Observation` is ommited by the LLM,
  19. # because the output text may have discarded the stop word.
  20. text = text.rstrip() + observation # Add it back.
  21. k = text.rfind(observation)
  22. plugin_name = text[i + len(action): j].strip()
  23. plugin_args = text[j + len(action_input): k].strip()
  24. text = text[:k]
  25. return plugin_name, plugin_args, text
  26. def _extract_first_target(self, text, start_flag, end_flag):
  27. target = ''
  28. i = text.find(start_flag)
  29. if i != -1:
  30. j = text.find(end_flag, i)
  31. if j != -1:
  32. target = text[i+len(start_flag):j].strip()
  33. else:
  34. target = text[i+len(start_flag):].strip()
  35. return target
  36. def get_first_observation(self, text):
  37. return self._extract_first_target(text, self.observation, self.observation_stop)
  38. def get_first_action_input(self, text):
  39. return self._extract_first_target(text, self.action_input, self.action_input_stop)