从零搭建一个AI Agent:Python实战教程,手写一个能上网搜索的智能助手
从零搭建一个AI Agent:Python实战教程,手写一个能上网搜索的智能助手

前言:为什么需要AI Agent?
说实话,做了多年开发,我感觉2026年最大的变化就是——AI不再只是聊天工具,而是变成了能真正干活的"数字员工"。
ChatGPT刚出来的时候,大家觉得哇,能聊天。后来加了联网搜索,能查资料。再后来出现了Cursor、Devon这些AI编程工具,能写代码了。但这些东西都是各管各的,没有一个能打通所有环节的"智能体"。
这就是AI Agent的价值所在——让AI不仅能想,还能做。
什么是AI Agent?
说白了,AI Agent就是一个能自主思考、自主决策、自主执行的AI程序。它不像传统程序那样按固定流程走,而是像个真人一样:
- 理解你的目标(你想干啥)
- 制定计划(怎么干)
- 调用工具(用什么干)
- 执行并反馈(干得怎么样)
听起来玄乎,但实现起来其实没那么复杂。今天我们就手写一个能上网搜索的AI Agent。
环境准备
首先确保你的Python版本 >= 3.10:
python --version
# Python 3.10.0+
安装依赖:
pip install openai httpx beautifulsoup4

第一步:设计Agent的核心架构
一个Agent的核心就三个东西:
- 大脑:大语言模型(LLM),负责思考
- 工具:能调用的外部能力,比如搜索、计算、读文件
- 记忆:上下文,记住之前聊了什么
我们用一个简单的类来表示:
from openai import OpenAI
import json
from typing import List, Dict, Any
class SimpleAgent:
"""一个简单的AI Agent"""
def __init__(self, api_key: str, base_url: str = None):
self.client = OpenAI(api_key=api_key, base_url=base_url)
self.messages = [] # 对话记忆
self.tools = {} # 注册的工具
def register_tool(self, name: str, func: callable, description: str):
"""注册一个工具"""
self.tools[name] = {"func": func, "description": description}
第二步:实现联网搜索工具
Agent能不能"上网"就靠这个了。我们用HTTPX来抓取网页内容:
import httpx
from bs4 import BeautifulSoup
async def search_web(query: str) -> str:
"""联网搜索,返回摘要信息"""
async with httpx.AsyncClient(timeout=30.0) as client:
url = f"https://lite.duckduckgo.com/lite/?q={query}"
resp = await client.get(url, headers={
"User-Agent": "Mozilla/5.0"
})
soup = BeautifulSoup(resp.text, "html.parser")
results = []
for link in soup.select("a.result__a")[:5]:
results.append(link.text.strip())
return "\n".join(results) if results else "未找到相关结果"

第三步:让Agent学会"思考"
Agent的核心是ReAct模式(Reasoning + Acting)。简单说就是:
思考 → 决定用哪个工具 → 执行 → 观察结果 → 再思考…
用代码实现:
class SimpleAgent:
# ... 前面定义的代码 ...
def run(self, user_input: str) -> str:
self.messages.append({"role": "user", "content": user_input})
tools_desc = "\n".join([
f"- {name}: {info[\"description\"]}"
for name, info in self.tools.items()
])
system_prompt = f"""你是一个智能助手。
可用工具:
{tools_desc}
当你需要调用工具时,请返回JSON格式:
{{"tool": "工具名", "args": {{"参数名": "参数值"}}}}
其他时候正常回复即可。"""
response = self.client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": system_prompt},
*self.messages
]
)
reply = response.choices[0].message.content
try:
cmd = json.loads(reply)
if "tool" in cmd and cmd["tool"] in self.tools:
tool_result = self.tools[cmd["tool"]]["func"](**cmd.get("args", {}))
self.messages.append({"role": "assistant", "content": f"工具返回: {tool_result}"})
return self.run("根据工具返回结果继续回答我的问题")
except json.JSONDecodeError:
pass
self.messages.append({"role": "assistant", "content": reply})
return reply
踩坑记录
搞这个过程中踩了几个坑:
坑1:异步函数调用
Tool函数如果是async的,需要await。但LLM返回的JSON里可不会告诉你这个。
坑2:上下文窗口爆炸
每次工具调用结果都塞进messages,跑几轮上下文就超了。加个滑动窗口:
MAX_HISTORY = 10
def trim_messages(self):
if len(self.messages) > MAX_HISTORY * 2:
self.messages = self.messages[-MAX_HISTORY * 2:]
坑3:循环调用
工具返回结果不满意,它会反复调用同一工具。加最大迭代次数限制。
MAX_ITERATIONS = 5
def run(self, user_input, iteration=0):
if iteration >= MAX_ITERATIONS:
return "我已经尽力了,但这个问题可能需要更多信息才能回答。"
常见问题
Q: 必须用OpenAI吗?能用国产模型吗?
完全可以。国内的DeepSeek、通义千问、豆包都支持Function Calling,只需要改base_url和api_key。
Q: 这个Agent能用在生产环境吗?
说实话,这个demo版不太行。生产环境需要加错误重试、日志、监控、安全沙箱等一堆东西。但作为学习原型完全够用。
Q: 有没有现成的框架?
有,LangChain、AutoGen、CrewAI、Dify都挺好用。但建议先手写一个,理解原理后再用框架,不然出了问题你都不知道怎么debug。
总结
说实话,AI Agent没有想象中那么神秘。核心就是:
- LLM当大脑,负责推理和决策
- 工具当手脚,负责执行具体操作
- 循环当机制,负责持续迭代直到完成目标
你只要搞懂这三个东西,就能搭出一个能用的Agent。
下一步建议去玩玩LangChain的Agent模块,或者看看AutoGen的多Agent协作——多个Agent一起干活,那才是真正的生产力。
有什么问题欢迎评论区交流~
更多推荐


所有评论(0)