引言:终于开始做一个"真的会做事"的 Agent
前面几篇,我们已经讲了 Agent 最核心的几个基础:
- Prompt
- Tool Calling
- Memory
但到这里,很多人还是会觉得:
概念我懂了,可我还是不知道怎么把它们真正拼起来。
所以这一篇,我们不再讲理论,而是直接做一个最小可运行 Agent。
这个 Agent 有两个能力:
- 查天气
- 做数学计算
例如:
text
用户:北京今天天气怎么样?
Agent:北京今天晴天,25 度。
用户:37 * 12 等于多少?
Agent:444
更进一步,它甚至还能自动判断:
text
用户:如果北京今天 25 度,比昨天高 3 度,那昨天是多少?
Agent 会:
- 先查天气
- 再调用计算器
- 最后给出答案
这时候,你就会真正感受到:
Agent 已经不只是"聊天机器人",而是在自动决定下一步该做什么。
一、我们要做的 Agent 长什么样?
整个流程其实很简单:
text
用户输入
→ 模型判断是否需要工具
→ 调用天气工具或计算器工具
→ 得到结果
→ 返回给用户
例如:
text
用户:北京天气怎么样?
→ 调天气工具
用户:12 * 9 等于多少?
→ 调计算器工具
再复杂一点:
text
用户:北京今天 25 度,比昨天高 3 度,那昨天多少?
→ 调天气工具,得到 25
→ 调计算器工具,25 - 3
→ 输出 22
这已经是最基础的 ReAct Agent 雏形。
二、准备环境
首先确认你已经安装:
bash
pip install langchain
pip install langchain-openai
如果你使用国内模型,例如 DeepSeek、通义千问,也一样可以。
例如:
python
llm = ChatOpenAI(
model="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
或者:
python
llm = ChatOpenAI(
model="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
Agent 的代码本身不用改。
三、先写第一个 Tool:天气查询
我们先写一个假的天气工具。
python
from langchain.tools import tool
@tool
def get_weather(city: str) -> str:
"""查询指定城市今天的天气和温度"""
fake_weather = {
"北京": "北京今天晴天,25度",
"上海": "上海今天多云,28度",
"广州": "广州今天下雨,30度"
}
return fake_weather.get(city, f"暂时查不到{city}的天气")
这里我们没有真的去调天气 API,而是先用假数据模拟。
因为学习 Agent 时,最重要的是:
先理解 Agent 如何调用 Tool。
后面你完全可以把这个函数替换成真实天气接口。
四、再写第二个 Tool:计算器
接下来,我们再写一个计算器工具。
python
@tool
def calculator(expression: str) -> str:
"""计算数学表达式,例如 2+3、25-3、37*12"""
try:
result = eval(expression)
return str(result)
except Exception:
return "计算失败"
例如:
text
calculator("37*12")
→ 444
注意:
这里为了简单,我们直接用了 eval()。
但在真实项目里,不建议直接这样做。
因为用户可能输入危险表达式。
更安全的方式通常是:
- ast
- numexpr
- 自己解析表达式
这里只是为了方便理解。
五、把 Tool 交给 Agent
现在,我们已经有两个 Tool:
get_weathercalculator
接下来,把它们交给 Agent。
python
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4.1-mini")
tools = [get_weather, calculator]
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.OPENAI_FUNCTIONS,
verbose=True
)
这里最重要的是:
python
verbose=True
因为它会把 Agent 的思考过程打印出来。
例如:
text
Thought: 我需要先查询天气。
Action: get_weather
Action Input: 北京
Observation: 北京今天晴天,25度
这样你就能真正看到:
Agent 是如何一步一步决定调用工具的。
六、先测试最简单的天气查询
python
response = agent.invoke("北京今天天气怎么样?")
print(response)
你会看到类似输出:
text
Agent 调用了 get_weather(city="北京")
最终结果:北京今天晴天,25度。
七、再测试计算器
python
response = agent.invoke("37 * 12 等于多少?")
print(response)
模型会自动判断:
这是数学问题,需要调用 calculator。
输出:
text
444
八、最有意思的部分:连续调用多个 Tool
现在,我们试一个更像真正 Agent 的问题:
text
北京今天 25 度,比昨天高 3 度,那昨天多少度?
理论上,Agent 会这样思考:
text
1. 需要知道今天温度
2. 调天气工具
3. 得到 25
4. 再调用计算器:25 - 3
5. 输出 22
对应代码:
python
response = agent.invoke(
"北京今天 25 度,比昨天高 3 度,那昨天多少度?"
)
print(response)
如果模型足够强(例如 GPT-4.1、DeepSeek Reasoner、Qwen Max),它通常会自动连续调用两个 Tool。
你会在日志里看到:
text
Action: get_weather
Observation: 北京今天晴天,25度
Action: calculator
Input: 25-3
Observation: 22
Final Answer: 昨天是 22 度。
这一刻,你就真正体验到了:
Agent 不只是"回答",而是在"解决问题"。
九、为什么这个例子很重要?
因为它已经包含了 Agent 最核心的能力:
text
思考
→ 选工具
→ 得到结果
→ 再思考
→ 再选工具
→ 最终回答
这其实已经是 ReAct 的最小版本。
只是因为工具太简单,所以你还没感觉到复杂。
如果把天气工具换成:
- 数据库
- 搜索引擎
- 公司 API
- MCP
- 发邮件
- 调用日历
那么它就已经变成真正的企业 Agent。
十、如何让 Agent 更稳定?
很多人第一次做 Tool Agent,会发现它有时不调用工具,有时调用错。
这通常不是模型太笨,而是 Prompt 和 Tool 描述不够清楚。
例如,你可以给 Agent 加一个 System Prompt:
python
system_prompt = """
你是一个助手。
- 涉及天气时,必须调用 get_weather
- 涉及数学时,必须调用 calculator
- 不允许直接猜测
"""
这样 Agent 会更稳定。
另外,Tool 描述也非常重要。
例如:
python
"""查询指定城市今天的天气和温度"""
要比:
python
"""获取信息"""
效果好得多。
十一、加入 Memory:让 Agent 记住刚才查过什么
如果再进一步,你还可以加 Memory。
例如:
第一轮:
text
用户:北京天气怎么样?
Agent:北京今天 25 度。
第二轮:
text
用户:那比昨天高 3 度的话,昨天多少?
如果没有 Memory,Agent 就不知道"那"指的是什么。
但如果加上 ConversationBufferMemory:
python
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
那么 Agent 就能记住:
刚才我们讨论的是北京天气 25 度。
这时,它就可以继续调用计算器。
这也是为什么:
Tool + Memory,才是完整的 Agent。
十二、完整代码
python
from langchain.tools import tool
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
@tool
def get_weather(city: str) -> str:
"""查询指定城市今天的天气和温度"""
weather = {
"北京": "北京今天晴天,25度",
"上海": "上海今天多云,28度"
}
return weather.get(city, "未找到天气信息")
@tool
def calculator(expression: str) -> str:
"""计算数学表达式"""
return str(eval(expression))
llm = ChatOpenAI(model="gpt-4.1-mini")
tools = [get_weather, calculator]
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.OPENAI_FUNCTIONS,
verbose=True
)
print(agent.invoke("北京今天天气怎么样?"))
print(agent.invoke("37 * 12 等于多少?"))
运行成功后,你就拥有了自己的第一个 Agent。
结语
一句话总结:
Agent 的核心,不是会聊天,而是会自己决定什么时候调用什么工具。
在这个简单例子里:
- 天气 Tool:负责查天气
- 计算器 Tool:负责算数字
- 模型:负责决定先调哪个、再调哪个
这已经不是普通聊天机器人,而是一个真正开始"行动"的 Agent。
而下一步,我们就可以继续进入:
ReAct:让 Agent 边思考、边行动、边观察。