ReAct.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import re
  2. from llm_client import HelloAgentsLLM
  3. from tools import ToolExecutor, search
  4. # (此处省略 REACT_PROMPT_TEMPLATE 的定义)
  5. REACT_PROMPT_TEMPLATE = """
  6. 请注意,你是一个有能力调用外部工具的智能助手。
  7. 可用工具如下:
  8. {tools}
  9. 请严格按照以下格式进行回应:
  10. Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步行动。
  11. Action: 你决定采取的行动,必须是以下格式之一:
  12. - `{{tool_name}}[{{tool_input}}]`:调用一个可用工具。
  13. - `Finish[最终答案]`:当你认为已经获得最终答案时。
  14. 现在,请开始解决以下问题:
  15. Question: {question}
  16. History: {history}
  17. """
  18. class ReActAgent:
  19. def __init__(self, llm_client: HelloAgentsLLM, tool_executor: ToolExecutor, max_steps: int = 5):
  20. self.llm_client = llm_client
  21. self.tool_executor = tool_executor
  22. self.max_steps = max_steps
  23. self.history = []
  24. def run(self, question: str):
  25. self.history = []
  26. current_step = 0
  27. while current_step < self.max_steps:
  28. current_step += 1
  29. print(f"\n--- 第 {current_step} 步 ---")
  30. tools_desc = self.tool_executor.getAvailableTools()
  31. history_str = "\n".join(self.history)
  32. prompt = REACT_PROMPT_TEMPLATE.format(tools=tools_desc, question=question, history=history_str)
  33. messages = [{"role": "user", "content": prompt}]
  34. response_text = self.llm_client.think(messages=messages)
  35. if not response_text:
  36. print("错误:LLM未能返回有效响应。"); break
  37. thought, action = self._parse_output(response_text)
  38. if thought: print(f"🤔 思考: {thought}")
  39. if not action: print("警告:未能解析出有效的Action,流程终止。"); break
  40. if action.startswith("Finish"):
  41. final_answer = self._parse_action_input(action)
  42. print(f"🎉 最终答案: {final_answer}")
  43. return final_answer
  44. tool_name, tool_input = self._parse_action(action)
  45. if not tool_name or not tool_input:
  46. self.history.append("Observation: 无效的Action格式,请检查。"); continue
  47. print(f"🎬 行动: {tool_name}[{tool_input}]")
  48. tool_function = self.tool_executor.getTool(tool_name)
  49. observation = tool_function(tool_input) if tool_function else f"错误:未找到名为 '{tool_name}' 的工具。"
  50. print(f"👀 观察: {observation}")
  51. self.history.append(f"Action: {action}")
  52. self.history.append(f"Observation: {observation}")
  53. print("已达到最大步数,流程终止。")
  54. return None
  55. def _parse_output(self, text: str):
  56. thought_match = re.search(r"Thought: (.*)", text)
  57. action_match = re.search(r"Action: (.*)", text)
  58. thought = thought_match.group(1).strip() if thought_match else None
  59. action = action_match.group(1).strip() if action_match else None
  60. return thought, action
  61. def _parse_action(self, action_text: str):
  62. match = re.match(r"(\w+)\[(.*)\]", action_text)
  63. return (match.group(1), match.group(2)) if match else (None, None)
  64. def _parse_action_input(self, action_text: str):
  65. match = re.match(r"\w+\[(.*)\]", action_text)
  66. return match.group(1) if match else ""
  67. if __name__ == '__main__':
  68. llm = HelloAgentsLLM()
  69. tool_executor = ToolExecutor()
  70. search_desc = "一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。"
  71. tool_executor.registerTool("Search", search_desc, search)
  72. agent = ReActAgent(llm_client=llm, tool_executor=tool_executor)
  73. question = "华为最新的手机是哪一款?它的主要卖点是什么?"
  74. agent.run(question)