如何构建你的第一个 Agent 项目
从 0 到 1,带你理解 Agent 的核心思想,并亲手搭建一个能调用工具的智能体。
一、什么是 Agent?为什么要学它?
传统的 LLM 应用(比如聊天机器人)本质上是"一问一答"------你给一个 prompt,它返回一个回答。而 Agent(智能体) 更进一步:它不仅能理解你的指令,还能自主规划步骤、调用外部工具、根据结果调整策略,最终完成一个复杂任务。
打个比方:
- 普通 LLM:像一个只会回答问题的百科全书。
- Agent:像一个会查资料、会用计算器、会写代码的实习生。
如果你想让 AI 真正"帮你干活",而不只是"陪你聊天",那 Agent 就是必经之路。
二、Agent 的四大核心组件
在动手之前,先搞清楚一个 Agent 由哪些部分组成:
| 组件 | 作用 | 类比 |
|---|---|---|
| LLM(大语言模型) | 大脑,负责理解、推理、决策 | 人的大脑 |
| Tools(工具) | 让 Agent 能与外部世界交互(搜索、计算、查数据库) | 人的手脚 |
| Memory(记忆) | 保存对话历史和任务上下文 | 人的短期/长期记忆 |
| Planning(规划) | 把复杂任务拆解成子步骤 | 人的思考过程 |
理解了这四个组件,你就理解了 90% 的 Agent 系统。
三、环境准备
工欲善其事,必先利其器。我们用 Python + 最流行的 Agent 框架来搭建。
1. 安装依赖
bash
pip install openai python-dotenv
这里我们不依赖任何重型框架,只用 OpenAI SDK 原生实现,方便你理解底层原理。掌握了原理后,再去用 LangChain、AutoGen 等框架会事半功倍。
2. 配置 API Key
在项目根目录创建 .env 文件:
OPENAI_API_KEY=sk-your-actual-key-here
四、动手实现:一个能查天气的 Agent
我们的目标:做一个 Agent,用户问"北京今天天气怎么样?",它能自动调用天气工具并返回结果。
第一步:定义工具
工具本质上就是一个普通函数,加上一段描述(让 LLM 知道什么时候该调用它)。
python
import json
import requests
def get_weather(city: str) -> str:
"""查询指定城市的天气情况"""
# 这里用一个免费的天气 API 演示
try:
resp = requests.get(f"https://wttr.in/{city}?format=j1")
data = resp.json()
current = data["current_condition"][0]
return f"{city}当前天气:{current['weatherDesc'][0]['value']},温度 {current['temp_C']}°C,湿度 {current['humidity']}%"
except Exception as e:
return f"查询天气失败:{str(e)}"
第二步:把工具注册给 LLM
OpenAI 的 Function Calling 机制允许我们把工具描述传给模型,模型会决定是否调用。
python
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# 工具描述:告诉 LLM 有哪些工具可用
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的实时天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如:北京、Shanghai"
}
},
"required": ["city"]
}
}
}
]
第三步:实现 Agent 主循环
这是最关键的一步。Agent 的核心是一个循环:
思考 → 决定是否调用工具 → 执行工具 → 把结果返回给 LLM → 继续思考...
python
def run_agent(user_query: str):
# 1. 构建初始消息
messages = [
{"role": "system", "content": "你是一个乐于助人的智能助手。当用户询问天气时,请使用工具查询。"},
{"role": "user", "content": user_query}
]
while True:
# 2. 调用 LLM
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
# 3. 如果 LLM 没有要求调用工具,直接返回最终回答
if not message.tool_calls:
return message.content
# 4. 如果需要调用工具,执行并把结果加回对话
messages.append(message) # 把 assistant 的 tool_call 请求加入历史
for tool_call in message.tool_calls:
func_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
# 根据函数名分发执行
if func_name == "get_weather":
result = get_weather(arguments["city"])
else:
result = f"未知工具:{func_name}"
# 把工具执行结果返回给 LLM
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 5. 循环继续,LLM 会根据工具结果生成最终回答
第四步:运行测试
python
if __name__ == "__main__":
answer = run_agent("北京今天天气怎么样?适合出门吗?")
print(answer)
预期输出:
北京当前天气:晴,温度 25°C,湿度 45%。
今天天气晴朗,温度适宜,非常适合出门活动!
看,Agent 自己完成了"理解问题 → 调用工具 → 综合回答"的全过程。
五、让 Agent 更强:多工具 + 记忆
上面的例子只有一个工具。实际项目中,Agent 往往需要多个工具配合。你只需要在 tools 列表里继续添加即可,比如:
search_web():联网搜索calculate():数学计算read_file():读取文件send_email():发送邮件
加入短期记忆
Agent 之所以能"记住"之前的对话,是因为每次请求都把完整的 messages 历史带上。这就是短期记忆。
如果要实现长期记忆(跨会话记忆用户偏好),可以把对话摘要存入数据库,下次对话时作为 system prompt 注入。
六、常见的坑 & 最佳实践
- 工具描述要写清楚 :LLM 是根据
description决定是否调用工具的,描述越准确,调用越精准。 - 控制循环次数:生产环境一定要给 while 循环加上最大迭代次数(比如 10 次),防止 Agent 陷入死循环。
- 错误处理要完善:工具执行失败时,把错误信息返回给 LLM,它通常能自我纠正。
- 先验证再上生产:用简单场景测试 Agent 的行为边界,避免在复杂任务中出现"幻觉调用"。
- 记录完整日志:把每一轮的 messages 和工具调用都记录下来,出问题时方便排查。
七、进阶路线
掌握了原生实现后,你可以按这个路线继续深入:
- 使用框架:LangChain / LlamaIndex / AutoGen,它们封装了记忆、规划、多 Agent 协作等能力。
- 引入 RAG:让 Agent 能查询你的私有知识库。
- 多 Agent 协作:让多个 Agent 分工合作(比如一个负责搜索,一个负责写代码)。
- 可视化观测:用 LangSmith、Langfuse 等工具观察 Agent 的思考过程。
八、总结
构建第一个 Agent 并不难,核心就三步:
- 定义工具------把你想让 AI 做的事封装成函数。
- 描述工具------用 JSON Schema 告诉 LLM 工具的用途和参数。
- 编写循环------让 LLM 在"思考"和"执行工具"之间反复迭代,直到完成任务。