第一个简单 Agent 实战:天气查询 + 计算器工具 Agent

引言:终于开始做一个"真的会做事"的 Agent

前面几篇,我们已经讲了 Agent 最核心的几个基础:

  • Prompt
  • Tool Calling
  • Memory

但到这里,很多人还是会觉得:

概念我懂了,可我还是不知道怎么把它们真正拼起来。

所以这一篇,我们不再讲理论,而是直接做一个最小可运行 Agent。

这个 Agent 有两个能力:

  1. 查天气
  2. 做数学计算

例如:

text 复制代码
用户:北京今天天气怎么样?
Agent:北京今天晴天,25 度。

用户:37 * 12 等于多少?
Agent:444

更进一步,它甚至还能自动判断:

text 复制代码
用户:如果北京今天 25 度,比昨天高 3 度,那昨天是多少?

Agent 会:

  1. 先查天气
  2. 再调用计算器
  3. 最后给出答案

这时候,你就会真正感受到:

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_weather
  • calculator

接下来,把它们交给 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 边思考、边行动、边观察。

相关推荐
后端小肥肠2 小时前
公众号破圈难?我写了个skill把长文拆成IP卡片,小红书小绿书同时发
人工智能·aigc·agent
墨心@4 小时前
多Agent系统的编排
人工智能·语言模型·自然语言处理·agent·datawhale·agent设计模式·组队学习
Hhang4 小时前
从 ERP 系统出发,我是如何设计一套 LLM 多 Agent 系统的(二)
前端·人工智能·agent
Java后端的Ai之路4 小时前
还在手写 Agent 代码?封装一个 SDK 让你从“码农“升级“包工头“
人工智能·langchain·ai编程·vibe coding·agent sdk
小兵张健5 小时前
从 Playwright MCP 到 Playwright CLI
程序员·openai·mcp
阿里-于怀6 小时前
Agent 构建变轻、Agent 架构变薄,什么正在变厚?
数据库·mysql·架构·agent·claude·manus·openclaw
羑悻的小杀马特6 小时前
Pinecone向量数据库深度解析:从核心架构到LangChain集成实战
数据库·架构·langchain·pinecone
花千树-01016 小时前
MCP 协议通信详解:从握手到工具调用的完整流程
ai·langchain·aigc·agent·ai agent·mcp
花千树-01016 小时前
内存(Memory)基础:ConversationBuffer、Summary Memory 等
agent·ai agent·上下文·长短期记忆·ai memory·ai 记忆压缩