Agnet 是 LangChain 最核心的概念,他能让 AI 自动判断何时需要调用工具,并在获取工具结果后继续思考,直到完成任务
什么是Agent
普通的模型调用时一问一答:
用户发送消息,模型回复,结束。
Agent则不同,它进入一个 思考-行动-观察 的循环:
模型判断(是否)需要调用某个工具 -> 执行工具并得到拿到结果 -> 模型根据结果继续判断 -> 可能再调用工具 -> 直到得到最终答案
举个例子:用户提问“今天天气如何?”普通模型智能回答训练数据中的天气(可能是几个月前的)。而Agent会主动调用天气查询工具获取实时数据,然后基于真实数据回答用户
创建第一个 Agent
整个过程需要三步:
- 定义工具
- 创建 Agent
- 运行
步骤1:定义工具函数
使用 @tool 修饰器,把普通 Python 函数变成 Agent 可以调用的工具
# 文件路径:04_first_agent.py
# 定义第一个 LangChain 工具:通过 wttr.in 查询真实天气
# API 文档:https://github.com/chubin/wttr.in
import json
import urllib.parse
import urllib.request
from dotenv import load_dotenv
# 加载 .env 中的环境变量(如 DEEPSEEK_API_KEY)
load_dotenv()
from langchain.tools import tool
# 步骤 1:用 @tool 装饰器定义一个工具
# 函数的文档字符串就是工具的描述,模型会根据描述来判断何时调用这个工具
@tool
def get_weather(city: str) -> str:
"""查询指定城市的天气情况。
Args:
city: 城市名称,如 "杭州"、"北京"
"""
# 对城市名进行 URL 编码,支持中文及含空格的地名
encoded_city = urllib.parse.quote(city)
# wttr.in 免费天气 API,无需 API Key
# format=j1 → JSON 格式,便于程序解析
# lang=zh → 中文描述(部分字段可能仍为英文)
# m → 公制单位(°C、km/h)
url = f"https://wttr.in/{encoded_city}?format=j1&lang=zh&m"
# 设置 User-Agent,避免被服务端拒绝
request = urllib.request.Request(
url,
headers={"User-Agent": "curl/7.64.1"},
)
try:
# 发起 HTTP 请求,10 秒超时
with urllib.request.urlopen(request, timeout=10) as response:
data = json.loads(response.read().decode("utf-8"))
except urllib.error.HTTPError as error:
# 服务端返回 4xx / 5xx
return f"查询 {city} 天气失败: HTTP {error.code}"
except urllib.error.URLError as error:
# 网络不可达、DNS 失败、超时等
return f"查询 {city} 天气失败: {error.reason}"
except (json.JSONDecodeError, KeyError, IndexError):
# 响应不是合法 JSON,或缺少预期字段
return f"无法解析 {city} 的天气数据"
# 从 JSON 中提取当前天气(current_condition 是数组,取第一项)
current = data["current_condition"][0]
weather_desc = current["weatherDesc"][0]["value"] # 天气状况,如 Sunny、Overcast
temp = current["temp_C"] # 当前气温(°C)
feels_like = current["FeelsLikeC"] # 体感温度(°C)
humidity = current["humidity"] # 相对湿度(%)
wind_speed = current["windspeedKmph"] # 风速(km/h)
wind_dir = current["winddir16Point"] # 风向(16 方位,如 NNE)
# 组装为自然语言字符串,供 Agent 直接回复用户
return (
f"{city}:{weather_desc},气温 {temp}°C,"
f"体感 {feels_like}°C,湿度 {humidity}%,"
f"风速 {wind_speed} km/h({wind_dir})"
)
文档字符串(函数的 “””…””” 部分)非常重要。模型会读取工具的描述来决定是否调用这个工具以及传什么参数。描述越清晰,模型就越不容易用错。
步骤2:创建 Agent
# 步骤 2:创建 Agent
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
# 初始化模型
model = init_chat_model("deepseek:deepseek-v4-flash")
# 创建 Agent,传入模型和工具列表
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="你是一个擅于使用工具来回答问题的助手。",
)
参数:
- model
- 说明:使用的语言模型
- 是否必填:是
- tools
- 说明:工具列表,即Agent可以调用的工具
- 是否必填:否(不填则Agent无法调用任何工具)
- system_prompt
- 说明:系统提示词,定义 Agent 的角色和行为
- 是否必填:否
步骤3:运行Agent
# 步骤 3:运行 Agent
# 构建输入消息
# 消息列表中的第一条通常是 HumanMessage(用户消息)
from langchain.messages import HumanMessage
inputs = {"messages": [HumanMessage(content="杭州今天天气怎么样?")]}
# invoke() 运行 Agent,返回最终状态
result = agent.invoke(inputs)
# 查看消息历史(包含 AI 的工具调用和工具返回结果)
print("=== 完整消息历史 ===")
for msg in result["messages"]:
print(f"[{msg.type}] {msg.content[:100]}") # 截取前 100 字符
print("\n=== 最终回复 ===")
# 最后一条 AI 消息就是最终答案
print(result["messages"][-1].content)
运行结果:
=== 完整消息历史 === [human] 杭州今天天气怎么样? [ai] 好的,我来查一下杭州今天的天气情况! [tool] 杭州:Overcast ,气温 23°C,体感 25°C,湿度 61%,风速 4 km/h(WNW) [ai] 杭州今天的天气情况如下: - 🌤 **天气状况**:阴天(Overcast) - 🌡 **气温**:23°C(体感温度 25°C) - 💧 **湿度**:61% - 🌬 **风速**:4 km/h( === 最终回复 === 杭州今天的天气情况如下: - 🌤 **天气状况**:阴天(Overcast) - 🌡 **气温**:23°C(体感温度 25°C) - 💧 **湿度**:61% - 🌬 **风速**:4 km/h(西北偏西) 今天杭州天气比较舒适,不冷不热,不过因为是阴天,建议出门带件外套哦!
Agent 执行流程解析
上述例子的完整执行过程如下:
- 用户发送消息:“杭州今天天气怎么样”
- 模型收到消息后判断:需要查询天气 -> 返回一个tool_call(调用get_weather,参数 city = ‘杭州’)
- Agent 执行 get_weather 工具 -> 返回“杭州:Overcast ,气温 23°C,体感 25°C,湿度 61%,风速 4 km/h(WNW)”
- 模型收到工具结果,判断任务完成,生成回复
调用多个工具
Agent真正为例在于能自动组合调用多个工具
# 问一个需要同时查询天气和计算的复杂问题
inputs = {"messages": [HumanMessage(
content="杭州和北京今天温差多少度?"
)]}
result = agent.invoke(inputs)
print("=== 完整消息历史 ===")
for msg in result["messages"]:
if msg.type == "tool":
print(f"[tool {msg.name}] {msg.content}")
else:
print(f"[{msg.type}] {msg.content[:120]}")
print("\n=== 最终回复 ===")
print(result["messages"][-1].content)
运行结果:
=== 完整消息历史 === [human] 杭州和北京今天温差多少度? [ai] 我来查询杭州和北京今天的天气情况。 [tool get_weather] 杭州:Partly cloudy,气温 23°C,体感 25°C,湿度 61%,风速 4 km/h(W) [tool get_weather] 北京:Partly Cloudy ,气温 26°C,体感 26°C,湿度 37%,风速 15 km/h(NNW) [ai] 根据查询到的天气数据: - **杭州**:今日气温 **23°C** - **北京**:今日气温 **26°C** **温差计算:** 26°C - 23°C = **3°C** 所以,今天北京比杭州高 **3°C**。北京的天气更暖 === 最终回复 === 根据查询到的天气数据: - **杭州**:今日气温 **23°C** - **北京**:今日气温 **26°C** **温差计算:** 26°C - 23°C = **3°C** 所以,今天北京比杭州高 **3°C**。北京的天气更暖和一些,而杭州相对凉爽一点。☀️
Agent 自动执行了三步:(1) 查询杭州天气;(2) 查询北京天气;(3) 计算温差。你不需要写任何逻辑来控制这些步骤,Agent 自动完成了规划和执行。
注意 Agent 在第一次调用模型时就发出了两个工具调用(get_weather(“杭州”) 和 get_weather(“北京”)),它们是并行执行的。模型会自动判断哪些工具调用可以并行。
异步运行
Agent 支持异步模式,适合在 Web 服务等异步环境中使用:
# 异步运行 Agent
import asyncio
from langchain.messages import HumanMessage
async def main():
# ainvoke() 是 invoke() 的异步版本
inputs = {"messages": [HumanMessage(content="杭州天气怎么样?")]}
result = await agent.ainvoke(inputs)
print(result["messages"][-1].content)
# 运行异步函数
asyncio.run(main())
小结
到这里你已经掌握了 LangChain 最核心的用法:
- 用 @tool 装饰器把 Python 函数变成工具
- 用 create_agent() 创建能自动调用工具的 Agent
- 用 agent.invoke() 运行 Agent 并获得结果
