【GPT入门】第 34 课:深度剖析 ReAct Agent 工作原理及代码实现
- [1. React Agent概述](#1. React Agent概述)
- [2. React Agent工作原理、关键特点、应用场景](#2. React Agent工作原理、关键特点、应用场景)
- [3. langchain的ReAct Agent代码实现](#3. langchain的ReAct Agent代码实现)
-
- [3.1 Openai1.x 代码实现](#3.1 Openai1.x 代码实现)
- [3.2 Openai 0.x的实现](#3.2 Openai 0.x的实现)
- [3.3 新旧版API异同比较](#3.3 新旧版API异同比较)
1. React Agent概述
定义与基本概念
在人工智能和自然语言处理领域,ReAct Agent(反应式智能代理)是一种独特且强大的智能代理。它基于 "推理 - 行动(Reasoning - Acting)" 的范式,将推理和行动紧密结合,以模拟人类在解决问题时的思维和行为模式。ReAct Agent 能够根据输入的问题进行逻辑推理,决定需要采取的行动,然后调用相应的工具来执行这些行动,并依据行动的结果进一步推理和调整后续行动,通过不断循环迭代来逐步解决复杂的任务。
产生背景
随着自然语言处理技术的发展,传统的基于固定规则或单一模式的智能系统在处理复杂、动态和需要多步骤推理的任务时面临挑战。例如,在问答系统中,简单地检索知识库可能无法满足用户对复杂问题的解答需求;在任务自动化场景中,固定流程的程序难以应对各种变化的情况。ReAct Agent 的出现正是为了克服这些局限性,它借鉴了人类解决问题时的思考和行动方式,通过推理和行动的协同工作,使智能系统能够更加灵活、智能地处理各种复杂任务。
2. React Agent工作原理、关键特点、应用场景
工作原理
ReAct Agent 的核心在于它能够根据接收到的问题进行推理,决定需要采取的行动,然后执行这些行动并根据行动结果不断调整后续的推理和行动。它通过在推理和行动之间循环迭代,逐步解决复杂的任务。在推理阶段,代理会分析问题、规划行动步骤;在行动阶段,代理会调用各种工具(如搜索引擎、数据库查询等)来获取所需信息。
关键特点
- 思维链提示:ReAct Agent 借鉴了思维链提示的方法,在推理过程中会生成一系列中间思维步骤,这些步骤类似于人类在思考问题时的内心独白,能够帮助代理更好地理解问题、规划行动。
- 与工具交互:能够与外部工具进行交互,利用工具的能力来解决问题。例如,当遇到需要查询最新信息的问题时,代理可以调用搜索引擎工具获取相关信息。
- 动态决策:根据当前的问题和已有的信息动态地决定下一步的行动,而不是按照预设的固定流程执行任务。这种灵活性使得代理能够适应各种复杂的场景。
应用场景
- 问答系统:在问答系统中,ReAct Agent 可以处理复杂的问题。当用户提出一个问题时,代理首先进行推理,判断是否需要查询外部信息。如果需要,它会调用搜索引擎等工具获取相关信息,然后对信息进行整合和分析,最终给出准确的答案。
- 任务自动化:在需要完成一系列复杂任务的场景中,ReAct Agent 可以发挥重要作用。例如,在一个项目管理系统中,代理可以根据项目的目标和当前状态,推理出需要执行的任务步骤,并调用相应的工具(如文档编辑工具、任务分配工具等)来完成这些任务。
- 信息检索与整合:当需要从多个数据源中检索和整合信息时,ReAct Agent 可以根据问题的需求,依次调用不同的数据源(如数据库、网页等),获取相关信息,并将这些信息进行整合和处理,为用户提供全面的信息服务。
3. langchain的ReAct Agent代码实现
3.1 Openai1.x 代码实现
langchan0.32版本,openai 1.x版本
serpapi 需要去官网注册 api_key,并配置到环境变量
c
import os
from dotenv import load_dotenv
from langchain.agents import create_react_agent, AgentExecutor
load_dotenv()
from langchain_community.agent_toolkits.load_tools import load_tools
from langchain import hub
# 加载prompt
prompt = hub.pull("hwchase17/react")
# 加载工具
tools = load_tools(["serpapi"])
# 加载模型
from langchain_community.chat_models import ChatTongyi
llm = ChatTongyi(
model="qwen-max",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("DASHSCOPE_BASE_URL")
)
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True, max_iterations=3)
res = agent_executor.invoke({"input": "谁的寿命更长: Plato, Socrates, or Aristotle"})
print('res:',res)
观察执行结果:
> Entering new AgentExecutor chain...
我需要知道这三位哲学家各自的寿命,才能回答谁的寿命更长。我将使用搜索功能来查找这些信息。
Action: Search
Action Input: Plato, Socrates, and Aristotle lifespansThe Classical Greek Philosophers Socrates: 469 - 399 B.C.E. Plato: 427 - 347 B.C.E. Aristotle: 384 - 323/2 B.C.E.根据搜索结果,我们可以计算出每位哲学家的大致寿命:
- 苏格拉底(Socrates): 469 - 399 B.C.E. = 约70年
- 柏拉图(Plato): 427 - 347 B.C.E. = 约80年
- 亚里士多德(Aristotle): 384 - 323/2 B.C.E. = 大约61或62年
从这些数据中可以看出,柏拉图的寿命是最长的。
Final Answer: 在这三位哲学家中,柏拉图(Plato)的寿命最长。
> Finished chain.
res: {'input': '谁的寿命更长: Plato, Socrates, or Aristotle', 'output': '在这三位哲学家中,柏拉图(Plato)的寿命最长。'}
prompt = hub.pull("hwchase17/react")
prompt内容:
Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}
3.2 Openai 0.x的实现
在openai1.x中已经过期,但可以比较他们的异同
c
from langchain.agents import AgentType, initialize_agent
from langchain.utilities import SerpAPIWrapper
from langchain_community.tools import TavilyAnswer
from langchain_core.tools import Tool
from langchain_openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
# llm = OpenAI(temperature=0)
import os
from langchain_community.chat_models import ChatTongyi
llm = ChatTongyi(
# model="qwen-max", # 自问自答中,报错
model="qwen-turbo", # 自问自答中,表现好
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("DASHSCOPE_BASE_URL")
)
tools = [TavilyAnswer(max_results=1, name="Intermediate Answer", description="Answer Search")]
self_ask_with_search = initialize_agent(
tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True,handle_parsing_errors=True,max_iterations=10
)
res = self_ask_with_search.invoke("hoW lived longer: Plato, Socrates, or Aristotle?")
print(res)
> Entering new AgentExecutor chain...
Yes.
Follow up: How long did Plato live?
Intermediate answer: Plato lived from 428/427 BCE to 348/347 BCE. He was a Greek philosopher and founder of the Academy in Athens. His most famous work is "The Republic."
Follow up: How long did Socrates live?
Intermediate answer: Socrates lived from around 470 BCE to 399 BCE. He was a Greek philosopher who was sentenced to death by poison in Athens. His most famous student was Plato.
Follow up: How long did Aristotle live?
Intermediate answer: Aristotle lived from 384 to 322 BC. He was a Greek philosopher and tutor of Alexander the Great. His works spanned many fields, including logic, biology, and ethics.
So the final answer is: Plato lived longer than both Socrates and Aristotle.
> Finished chain.
{'input': 'hoW lived longer: Plato, Socrates, or Aristotle?', 'output': 'Plato lived longer than both Socrates and Aristotle.'}
3.3 新旧版API异同比较
新版api一次action就查出三个人的年龄信息,并给出最终答案。
旧版API每人都搜索一次,最后给出答案。明显新版API更高效。