Langgraph实战-Agent-ReAct(Reason+Act)概述
概述
ReAct 架构将推理与动作相结合,使Agent能够通过生成想法并基于这些想法执行动作。这种决策透明度使Agent能够更负责地执行任务,因为它会记录每一步的推理过程。
这种架构最适合Agent需要评估多个选项并选择最佳操作的任务。例如,它可以用于客户服务应用程序,Agent必须评估客户查询并决定如何响应。
ReAct Agent代表了AI系统推理(reasoning)与行动(acting)整合的突破,旨在基于动态输入和外部数据实时做出决策并采取行动。该架构由普林斯顿大学和谷歌研究院的姚顺宇等人(2023)在 ReAct 论文中提出。ReAct 框架以交错的方式将语言推理和特定任务的操作结合在一起,从而实现推理轨迹和操作之间的协同作用。这带来了更强大的任务解决能力,尤其是在动态或知识密集型任务中。
历史上,AI系统要么专注于推理(例如,思维链或 CoT 提示),要么专注于执行动作(例如,强化学习)。这些方法虽然单独使用时有效,但在需要reasoning和acting结合的任务中却常常失效。例如,纯粹基于推理的模型常常会产生幻觉,而基于动作的模型则缺乏情境和规划能力。ReAct 通过在推理(思维)和动作(执行任务并收集额外信息)之间建立反馈回路来解决这些缺陷。这种架构已被证明在 ALFWorld 等交互式环境和 HotPotQA 等知识密集型任务中有效。
ReAct 的关键概念
- 推理和行动协同: Agent通过可用数据或选项进行推理,然后根据该推理选择行动。
- 透明的决策: Agent记录其想法和行动,提供决策如何做出的清晰记录。
- 迭代过程:推理和行动周期可以重复,如果初始行动没有产生预期的结果,则允许 Agent改进其方法。
实施步骤
- 定义环境和 Agent目标:首先,描述Agent运行的环境。定义 Agent需要实现的目标。
- 列出可用操作:列举 Agent可以执行的所有操作。这些操作可能包括查询数据库、调用 API 或响应用户查询。
- 记录观察结果:记录所采取的行动和由此产生的观察结果(例如,行动成功还是失败?有哪些新数据可用?)。
- 生成推理:基于观察结果,促使 Agent对下一步行动产生想法或推理。此过程持续进行,直至目标达成。
- 执行动作:一旦 Agent完成推理过程,它就会选择一个动作并执行它。
LangGraph中的ReAct Agent
LangGraph以高度灵活的方式实现了ReAct架构,允许用户创建能够进行推理、工具调用和决策的动态Agent LangGraph ReAct Agent采用模块化结构,其中大型语言模型 (LLM) 逐步推理,并动态决定是否调用工具、检索数据或终止流程。
LangGraph 中 ReAct的关键组件
- 推理:Agent根据输入产生想法并决定潜在的行动。
- 工具调用:基于推理,Agent决定调用特定工具,例如 API 或知识库,并将工具输出集成回到推理循环中。
- 观察:工具的输出被传回推理阶段,使Agent能够完善其思维并采取进一步的行动或最终确定其反应。
- 记忆:Agent可以在多次交互中保留数据,从而允许它根据之前的步骤做出明智的决策。
构建 ReAct Agent的最佳实践
- 结构化的思考和行动的循环:确保Agent的推理步骤与行动步骤分离。这样可以清楚地识别Agent的思维方式和正在采取的行动。
- 有效的工具集成:ReAct Agent应该能够访问丰富的工具集,以便在需要时获取外部数据。在 LangGraph 中,工具集范围从简单的 Python 函数到复杂的 API。
- 记忆的使用:对于较长的对话或任务,保持记忆至关重要,这能让 Agent“记住”过去的步骤和交互。LangGraph 提供了用于短期和长期记忆的记忆模块。
- 迭代思维-行动(Thought-Action)循环:设计您的 ReAct Agent根据需要多次循环推理和行动,让它们在每次循环中完善对任务的理解。
- 错误处理和反馈:实施反馈机制,使Agent可以识别错误并从错误中恢复,或者如果不确定下一步,则要求澄清。
ReAct Agent的例子
计算加法和乘法
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
# 1. 通过 ChatOpenAI 初始化一个 LLM 模型
local_llm = "Qwen/Qwen2.5-7B-Instruct"
# 使用硅基流动提供的模型服务s
base_url = "https://api.siliconflow.cn/v1"
llm = ChatOpenAI(model=local_llm, base_url=base_url, api_key="sk-xxx")
# 2. 定义工具
def add(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
def multiply(a: int, b: int) -> int:
"""Multiply two numbers together."""
return a * b
tools = [add, multiply]
# 3.创建ReAct agent
graph = create_react_agent(model=llm, tools=tools)
# 4. 用户输入
# inputs = {"messages": [("user", "Add 3 and 4. Multiply the result by 2.")]}
inputs = {"messages": [("user", "(3+4*2)*2=?")]}
# 5. 运行ReAct agent
messages = graph.invoke(inputs)
for message in messages["messages"]:
print(message.content)
输出结果
PS D:\my_dev\do_langx> & C:/Users/issuser/.conda/envs/ailab/python.exe d:/my_dev/do_langx/react_agent_1.py
(3+4*2)*2=?
To solve the expression \((3 + 4 \times 2) \times 2\), we need to follow the order of operations (PEMDAS/BODMAS):
1. First, perform the multiplication inside the parentheses: \(4 \times 2 = 8\).
2. Then, add this result to 3: \(3 + 8 = 11\).
3. Finally, multiply the result by 2: \(11 \times 2\).
Let's perform the final multiplication using the `multiply` function.
22
The result of the expression \((3 + 4 \times 2) \times 2\) is \(22\).