从零手把手搭建第一个 ReAct Agent(简单工具调用版)
引言:从“理解 ReAct”到“真正跑起来”
上一篇我们讲了 ReAct Agent 的核心原理:
Reason(思考) + Act(行动) + Observe(观察)循环。
但只理解原理还不够。
真正开始做 Agent,一定要先跑通一个最小 Demo。
这一篇我们就从零开始,手把手搭建一个最简单的 ReAct Agent。
这个 Agent 只有两个工具:
- 天气查询工具
- 计算器工具
它可以完成:
用户:北京天气怎么样?
Agent:北京今天晴天,25度。
也可以完成:
用户:37 * 12 等于多少?
Agent:444
更重要的是,它可以自动判断:
- 什么时候该查天气
- 什么时候该计算
- 什么时候不需要调用工具
这就是 ReAct Agent 的第一步。
一、我们要实现什么?
这篇文章要实现的目标很明确:
用户输入
↓
ReAct Agent 思考
↓
判断是否需要工具
↓
调用天气 / 计算器工具
↓
观察工具结果
↓
输出最终答案
最终效果类似:
用户:北京今天天气怎么样?
Agent 调用 get_weather("北京")
Agent:北京今天晴天,25度。
再比如:
用户:如果北京今天25度,比昨天高3度,那昨天多少度?
Agent 调用 calculator("25-3")
Agent:昨天是22度。
注意,这里 Agent 不是写死流程。
而是模型自己判断:
我现在应该调用哪个工具?
这就是 ReAct 的核心价值。
二、环境准备
1. 创建项目目录
mkdir react-agent-demo
cd react-agent-demo
2. 创建虚拟环境
macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
Windows PowerShell:
python -m venv .venv
.venv\Scripts\Activate.ps1
激活成功后,你会看到命令行前面出现:
(.venv)
3. 安装依赖
pip install -U langchain langgraph langchain-openai python-dotenv
这里几个包分别负责:
| 包名 | 作用 |
|---|---|
langchain |
基础抽象与消息结构 |
langgraph |
Graph / Agent 执行框架 |
langchain-openai |
OpenAI 兼容模型接入 |
python-dotenv |
加载 .env 配置 |
如果你使用 DeepSeek、通义千问这类 OpenAI 兼容接口,也可以继续使用 langchain-openai。
三、配置 API Key
在项目根目录创建 .env 文件:
OPENAI_API_KEY=你的key
如果你使用 DeepSeek:
DEEPSEEK_API_KEY=你的key
如果你使用通义千问:
DASHSCOPE_API_KEY=你的key
建议不要把 API Key 写死在代码里。
正确做法是:
- 本地开发放
.env - 生产环境放环境变量
.env加入.gitignore
.gitignore 示例:
.env
.venv/
__pycache__/
四、选择模型
这一篇我们以 OpenAI 兼容写法为主。
方式1:OpenAI
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-4o-mini",
temperature=0
)
方式2:DeepSeek
import os
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com",
temperature=0
)
方式3:通义千问
import os
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
temperature=0
)
为了让教程简单,下面完整代码默认使用 OpenAI 写法。
如果你要换模型,只需要替换 model = ChatOpenAI(...) 这一段。
五、定义第一个工具:天气查询
我们先写一个假的天气工具。
真实项目里可以接天气 API,但入门阶段不建议一开始就接外部接口。
因为我们这篇的重点是理解:
Agent 如何选择并调用工具。
代码:
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""查询指定城市今天的天气和温度。参数 city 是城市名称,例如 北京、上海、广州。"""
weather_data = {
"北京": "北京今天晴天,25度。",
"上海": "上海今天多云,28度。",
"广州": "广州今天小雨,30度。",
"深圳": "深圳今天晴天,31度。"
}
return weather_data.get(city, f"暂时没有查询到 {city} 的天气。")
这里有一个非常关键的点:
Tool 的 docstring 很重要。
也就是这一段:
"""查询指定城市今天的天气和温度。参数 city 是城市名称,例如 北京、上海、广州。"""
模型会根据这个描述判断:
- 这个工具是干什么的
- 什么时候应该调用它
- 参数应该怎么填
如果你只写:
def get_weather(city):
"""获取信息"""
模型就很可能不知道什么时候该用它。
六、定义第二个工具:计算器
再写一个计算器工具:
@tool
def calculator(expression: str) -> str:
"""计算一个数学表达式,例如 2+3、25-3、37*12。只接收简单数学表达式。"""
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"计算失败:{e}"
例如:
calculator("37*12")
→ 444
注意:
这里为了教程简单,使用了 eval()。
真实生产环境不建议直接使用 eval(),因为它可能执行危险代码。
生产中更安全的做法是:
- 使用
ast解析表达式 - 使用
numexpr - 只允许白名单运算符
- 后端自己实现安全计算器
但作为入门 Demo,这样最容易理解。
七、使用 create_react_agent 快速创建 Agent
LangGraph 提供了预构建的 ReAct Agent:
from langgraph.prebuilt import create_react_agent
它已经帮我们封装好了:
LLM 节点
↓
Tool 节点
↓
Observation 写回
↓
继续判断是否完成
所以我们不需要手写整个循环。
只需要:
agent = create_react_agent(
model=model,
tools=[get_weather, calculator]
)
这就是最小 ReAct Agent。
八、完整代码
在项目根目录创建:
main.py
完整代码如下:
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
load_dotenv()
@tool
def get_weather(city: str) -> str:
"""查询指定城市今天的天气和温度。参数 city 是城市名称,例如 北京、上海、广州。"""
weather_data = {
"北京": "北京今天晴天,25度。",
"上海": "上海今天多云,28度。",
"广州": "广州今天小雨,30度。",
"深圳": "深圳今天晴天,31度。"
}
return weather_data.get(city, f"暂时没有查询到 {city} 的天气。")
@tool
def calculator(expression: str) -> str:
"""计算一个数学表达式,例如 2+3、25-3、37*12。只接收简单数学表达式。"""
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"计算失败:{e}"
model = ChatOpenAI(
model="gpt-4o-mini",
temperature=0
)
agent = create_react_agent(
model=model,
tools=[get_weather, calculator]
)
def run_agent(question: str):
result = agent.invoke({
"messages": [
{"role": "user", "content": question}
]
})
final_message = result["messages"][-1]
print("用户:", question)
print("Agent:", final_message.content)
print("-" * 50)
if __name__ == "__main__":
run_agent("北京今天天气怎么样?")
run_agent("37 * 12 等于多少?")
run_agent("如果北京今天25度,比昨天高3度,那昨天多少度?")
运行:
python main.py
九、运行效果示例
你可能会看到类似输出:
用户:北京今天天气怎么样?
Agent:北京今天晴天,25度。
--------------------------------------------------
用户:37 * 12 等于多少?
Agent:37 * 12 等于 444。
--------------------------------------------------
用户:如果北京今天25度,比昨天高3度,那昨天多少度?
Agent:昨天是 22 度。
--------------------------------------------------
这里最重要的不是答案本身,而是:
Agent 会自动决定是否调用工具。
当你问天气时,它会调用 get_weather。
当你问数学时,它会调用 calculator。
这就是 ReAct Agent 的基础形态。
十、如何查看 Agent 的中间过程?
如果你想看到 Agent 每一步执行过程,可以用 stream。
例如:
inputs = {
"messages": [
{"role": "user", "content": "北京今天天气怎么样?"}
]
}
for chunk in agent.stream(inputs, stream_mode="updates"):
print(chunk)
你会看到类似:
模型决定调用 get_weather
工具返回 北京今天晴天,25度
模型生成最终回答
也可以使用:
stream_mode="values"
查看每一步完整状态。
这对调试非常有用。
十一、如果你想使用 DeepSeek 或通义千问
只需要替换模型初始化部分。
DeepSeek 版本
model = ChatOpenAI(
model="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com",
temperature=0
)
通义千问版本
model = ChatOpenAI(
model="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
temperature=0
)
其他代码不用改。
这也是为什么我们前面一直强调:
不要把模型能力和业务逻辑耦合在一起。
十二、常见错误排查
1. ModuleNotFoundError
说明依赖没装好。
重新安装:
pip install -U langchain langgraph langchain-openai python-dotenv
2. API Key 没读取到
检查 .env 是否在项目根目录。
可以临时打印:
print(os.getenv("OPENAI_API_KEY"))
如果是 None,说明没有加载成功。
3. Agent 不调用工具
优先检查:
- Tool 名字是否清楚
- Tool docstring 是否清楚
- 用户问题是否确实需要工具
- 模型是否支持工具调用
4. 计算器报错
可能是模型传入了不安全或不合法表达式。
例如:
25 度 - 3 度
计算器只适合接收:
25-3
如果要更稳定,可以在 Tool 里做表达式清洗。
5. create_react_agent 导入失败
尝试升级:
pip install -U langgraph
如果仍然失败,说明你当前环境里 LangGraph 版本较旧或依赖不完整。
建议重新创建虚拟环境后安装。
十三、这个 Demo 的核心意义
这个 Demo 看起来很简单,但它已经包含了 ReAct Agent 最核心的结构:
用户输入
↓
模型思考
↓
选择工具
↓
执行工具
↓
观察结果
↓
最终回答
换句话说:
你已经跑通了一个真正的 Agent 最小闭环。
后面无论你做:
- 搜索 Agent
- 数据库 Agent
- RAG Agent
- 编程 Agent
- 企业办公 Agent
本质都是在这个基础上继续扩展工具和状态管理。
十四、下一步可以怎么扩展?
你可以继续给它加:
1. 更多工具
例如:
- 搜索工具
- 查询订单工具
- 发邮件工具
- 数据库查询工具
2. Memory
让它记住上一轮问题。
例如:
用户:北京天气怎么样?
Agent:北京今天25度。
用户:那昨天呢?
3. LangSmith
查看完整 Trace:
- 模型调用
- 工具调用
- Token 消耗
- Latency
4. 自定义 Graph
当预构建 Agent 不够用时,就可以手写 LangGraph:
- 自定义 State
- 自定义节点
- 自定义边
- 自定义停止条件
结语
一句话总结:
create_react_agent 让我们用最少代码跑通了一个 ReAct Agent。
在这篇文章里,我们完成了:
- 环境准备
- 安装 LangChain / LangGraph
- 定义天气工具
- 定义计算器工具
- 使用
create_react_agent构建 Agent - 运行并查看结果
- 初步调试中间过程
这就是单 Agent 开发的第一个真正实战 Demo。
下一篇,我们可以继续深入:
手写 ReAct 循环:不用预构建 Agent,自己实现 Thought → Action → Observation。
更多推荐




所有评论(0)