从零开始构建AI Agent框架小白友好版收藏学习必备本文将带你一步步构建具备工具调用能力的AI Agent框架内容涵盖大模型适配层、对话记忆系统、工具调用能力、标准化消息格式及整合形成完整ToolAgent的五个步骤。采用ReAct模式让Agent能推理并调用工具完成任务适合编程新手学习最终实现具备Google搜索等功能的智能助手。什么是 Agent 概念理解Agent智能体 大模型大脑 记忆系统 工具调用能力 任务规划能力比喻大模型 大脑思考、理解、决策* 记忆系统 记忆记住对话历史* 工具调用 手脚执行实际任务如搜索、计算* 任务规划 规划能力分解复杂任务 我们的实现目标构建一个简单的 Agent具备以下能力✅ 与用户对话并保持上下文记忆✅ 调用 Google 搜索工具获取实时信息✅ 自动决定何时调用工具✅ 综合工具结果生成最终答案准备工作1 创建项目目录# 在你的桌面创建项目目录cd ~/Desktopmkdir agentcd agent2 创建依赖管理文件创建requirements.txt文件openai1.0.0python-dotenv1.0.0google-search-results2.4.23 安装依赖pip3 install -r requirements.txt4 配置环境变量创建.env文件不要提交到 Git# 方案1使用 DeepSeek推荐有免费额度API_KEYsk-your-deepseek-api-keyBASE_URLxxxxxMODEL_NAMEdeepseek-chat# 方案2使用 OpenAI需要 API Key# API_KEYsk-your-openai-api-key# BASE_URLxxxxx# MODEL_NAMEgpt-3.5-turbo# Google 搜索 API用于工具功能SERPAPI_API_KEYyour-serpapi-key第一步构建大脑- 统一的大模型适配层 目标创建一个统一的大模型调用接口屏蔽不同厂商的 API 差异。 创建文件llm.py# llm.pyfrom openai import OpenAIimport osfrom dotenv import load_dotenvload_dotenv() # 加载环境变量class LLMClient: def __init__(self): # 通过环境变量配置轻松切换不同厂商 self.client OpenAI( api_keyos.getenv(API_KEY), base_urlos.getenv(BASE_URL) ) self.model os.getenv(MODEL_NAME, gpt-4o) def chat(self, messages, toolsNone): 统一的对话入口屏蔽底层差异 参数: messages: 对话历史列表 tools: 工具定义列表可选 返回: OpenAI API 的响应对象 params { model: self.model, messages: messages, } if tools: params[tools] tools # 这里为了演示简洁暂不开启流式输出 return self.client.chat.completions.create(params) 代码解释核心设计思想环境变量配置api_keyos.getenv(API_KEY)base_urlos.getenv(BASE_URL)将敏感信息API Key放在.env文件中避免硬编码在代码里提高安全性统一接口def chat(self, messages, toolsNone): return self.client.chat.completions.create(params)封装 OpenAI API 的调用细节提供简单易用的chat()方法支持tools参数让 Agent 能调用工具易于切换厂商只需修改.env中的BASE_URL和MODEL_NAME代码完全不需要改动 为什么需要这个适配层❌ 没有适配层# 硬编码不安全难以维护import openairesponse openai.ChatCompletion.create( modelgpt-4o, messages[...], api_keysk-xxx # 暴露在代码中)✅ 使用适配层# 简洁、安全、易切换from llm import LLMClientllm LLMClient()response llm.chat([{role: user, content: 你好}])第二步实现基础 Agent - 对话记忆系统 目标创建一个能记住对话历史的 Agent实现多轮对话。 创建文件agent.py# agent.py (基础版)from llm import LLMClientclass SimpleAgent: def __init__(self): self.llm LLMClient() # 初始化记忆设定基础背景 self.messages [{role: system, content: 你是一个乐于助人的AI助手。}] def chat(self, user_input): # 1. 接收将用户输入存入记忆 self.messages.append({role: user, content: user_input}) # 2. 思考带着所有历史记录去请求 LLM response self.llm.chat(self.messages) content response.choices[0].message.content # 3. 闭环将 AI 的回答也存入记忆 self.messages.append({role: assistant, content: content}) return content 代码解释核心概念消息角色# system: 设定 AI 的身份和行为规则{role: system, content: 你是一个乐于助人的AI助手。}# user: 用户的输入{role: user, content: 我叫小明}# assistant: AI 的回答{role: assistant, content: 你好小明很高兴认识你}工作流程三步闭环 用户输入 → 存入记忆 → 调用 LLM带上完整历史→ 获取回答 → 存入记忆 → ✅ 返回给用户为什么需要记忆大模型本身是无状态的每次调用都是独立的通过传递历史消息让 AI 理解上下文实现多轮对话和连贯性 测试基础 Agent创建测试文件test_agent.py# test_agent.pyfrom agent import SimpleAgentdef main(): agent SimpleAgent() print( 简单的AI助手 ) print(输入quit退出/n) while True: user_input input(你: ) if user_input.lower() quit: break response agent.chat(user_input) print(fAgent: {response}/n)if __name__ __main__: main()运行测试python3 test_agent.py示例对话 简单的AI助手 输入quit退出 你: 我叫susie Agent: 你好susie我是SimpleAgent有什么我可以帮助你的吗 你: 你记得我叫什么吗 Agent: 当然记得你叫susie 你: quit第三步装备工具 - 让 Agent 能做事 目标实现工具注册和调用系统让 Agent 能执行实际任务如 Google 搜索。 创建文件tools.py# tools.pyimport inspectimport jsonimport osfrom functools import wrapsfrom google_search_results import GoogleSearchclass ToolRegistry: 工具注册中心管理所有可用工具 def __init__(self): self.tools {} # 存函数实体 self.schemas [] # 存函数说明书JSON Schema def register(self, func): 魔法装饰器自动将 Python 函数转换为 OpenAI Tool Schema name func.__name__ # 函数名 doc func.__doc__ or No description # 函数文档字符串 # 解析函数签名 sig inspect.signature(func) params {type: object, properties: {}, required: []} # 遍历参数生成 JSON Schema for param_name, param in sig.parameters.items(): params[properties][param_name] { type: string, description: f参数 {param_name} } if param.default inspect.Parameter.empty: params[required].append(param_name) # 1. 生成说明书给 LLM 看 self.schemas.append({ type: function, function: { name: name, description: doc, parameters: params } }) # 2. 存储函数实际执行 self.tools[name] func wraps(func) def wrapper(*args, kwargs): return func(*args, kwargs) return wrapper def execute(self, name, args_json): 执行器根据 LLM 的指令运行代码 if name in self.tools: try: args json.loads(args_json) # 将 JSON 字符串转为字典 print(f⚙️ [System] 正在调用工具: {name} 参数: {args}) return self.tools[name](args) # 执行函数解包参数 except Exception as e: return fError: {str(e)} return Tool not found# 创建全局注册表registry ToolRegistry()# 定义工具 registry.registerdef google_search(query: str): 当用户询问当前事件、新闻、天气或不知道的信息时使用此工具进行搜索。 try: search GoogleSearch({ q: query, api_key: os.getenv(SERPAPI_API_KEY), }) # 数据清洗只提取前两条结果的标题和摘要节省 Token results search.get_dict().get(organic_results, [])[:2] return /n.join([ f- {r.get(title)}: {r.get(snippet)} for r in results ]) except Exception as e: return f搜索失败: {e} 代码解释核心设计装饰器模式registry.registerdef google_search(query: str): 函数描述 pass装饰器做了什么提取函数信息名称google_search描述函数的文档字符串参数从类型注解query: str中提取生成 JSON Schema给 LLM 看的说明书{ type: function, function: { name: google_search, description: 当用户询问当前事件、新闻、天气或不知道的信息时使用此工具进行搜索。, parameters: { type: object, properties: { query: { type: string, description: 参数 query } }, required: [query] } } }存储函数实际执行用的self.tools[google_search] google_search # 存储真实的 Python 函数为什么用装饰器没有装饰器时需要手动写一遍函数再写一遍 JSON Schema容易出错。使用装饰器后只需写一次函数自动生成说明书。第四步消息标准化 - 统一通信格式 目标创建消息辅助函数确保消息格式标准化避免手动构造字典出错。 创建文件message.py# message.pydef user_msg(content): 用户消息 return {role: user, content: content}def assistant_msg(contentNone, tool_callsNone): 助手消息 - content: 文本回复可选 - tool_calls: 工具调用请求可选 msg {role: assistant} if content: msg[content] content if tool_calls: msg[tool_calls] tool_calls return msgdef tool_msg(tool_call_id, content): 工具消息 - tool_call_id: 工具调用 ID关键 - content: 工具返回结果 return { role: tool, tool_call_id: tool_call_id, content: str(content) } 代码解释为什么需要标准化❌ 手动构造消息# 容易出错messages.append({role: user, content: 你好})messages.append({rol: assistant, content: 你好}) # 拼写错误messages.append({role: tool, content: 结果}) # 缺少 tool_call_id✅ 使用辅助函数# 标准化不易出错messages.append(user_msg(你好))messages.append(assistant_msg(content你好))messages.append(tool_msg(call_123, 搜索结果))核心概念tool_call_id快递单号LLM: “帮我搜索北京天气” → 生成单号 call_abc123↓调用搜索工具↓工具返回结果附上单号 call_abc123↓LLM 看到单号知道这是北京天气的搜索结果消息类型总结函数role必需字段可选字段用途user_msg()“user”content-用户输入assistant_msg()“assistant”-content, tool_callsLLM 的回复文本或工具调用tool_msg()“tool”tool_call_id, content-工具执行结果第五步整合一切 - 完整的 ToolAgent 目标将前面所有组件整合实现具备工具调用能力的完整 Agent。 创建文件tool_agent.py# tool_agent.pyimport jsonfrom llm import LLMClientfrom tools import registry # 导入工具注册表from message import user_msg, assistant_msg, tool_msgclass ToolAgent: def __init__(self): self.llm LLMClient() # 大脑 self.tools registry # 工具箱 # self.messages 记忆系统 self.messages [{ role: system, content: 你是一个全能助手可以调用工具获取实时信息。如果觉得已经足够回复用户了就不用再调用工具了。 }] def chat(self, user_input): 支持工具调用的 ReAct 循环入口 注意为了演示逻辑清晰这里暂时使用非流式 # 1. 存入用户问题 self.messages.append(user_msg(user_input)) # 设置最大循环次数防止 Agent 陷入死循环 max_turns 5 turn_count 0 while turn_count max_turns: turn_count 1 # 2. 调用 LLM带上 tools 定义 print(f/n [Thinking] 第 {turn_count} 轮思考...) response self.llm.chat( messagesself.messages, toolsself.tools.schemas # 关键把工具说明书发给 LLM ) response_msg response.choices[0].message # 3. 判断 LLM 的意图 tool_calls response_msg.tool_calls if tool_calls: # 情况 A: LLM 想要调用工具 # A1. 先把 LLM 的调用指令存入记忆这步不能省 ai_msg_dict assistant_msg( contentresponse_msg.content, tool_callstool_calls ) self.messages.append(ai_msg_dict) # A2. 遍历所有工具调用请求LLM 可能一次想调多个工具 for tool_call in tool_calls: func_name tool_call.function.name func_args tool_call.function.arguments call_id tool_call.id print(f✋ [Action] 正在调用工具: {func_name} ...) # A3. 执行真正的 Python 代码 tool_result self.tools.execute(func_name, func_args) # A4. 构建 Tool Message观察结果 # 关键一定要带上 call_id否则 LLM 不认账 tm tool_msg(tool_call_idcall_id, contenttool_result) self.messages.append(tm) print(f [Observation] 工具返回: {tool_result[:50]}...) # A5. 循环继续 - 回到 while 开头把结果发给 LLM else: # 情况 B: LLM 没调工具直接回复 content response_msg.content self.messages.append(assistant_msg(contentcontent)) return content return ❌ 任务太复杂超过最大循环次数。# --- 演示代码 ---if __name__ __main__: # 确保 .env 里配置了 SERPAPI_API_KEY agent ToolAgent() while True: try: user_input input(/n 你).strip() # 检查用户输入 if user_input.lower() in [exit, q, 退出]: print(/n再见) break # 如果用户输入为空跳过 if not user_input: continue final_answer agent.chat(user_input) print(/n * 30) print(f Final Answer:/n{final_answer}) print( * 30) except KeyboardInterrupt: print(/n/n 检测到中断退出程序) break except Exception as e: print(f/n❌ 发生错误: {e}) import traceback traceback.print_exc() # 打印详细的错误信息 代码解释核心设计ReAct 模式ReAct Reasoning Acting推理 行动用户今天北京天气怎么样↓LLM 思考我需要查询天气信息↓LLM 行动调用搜索工具↓观察结果北京今天晴天25度↓LLM 思考现在我有了信息可以回答用户了↓LLM 行动生成最终回复为什么需要循环一次对话可能需要多次工具调用用户帮我规划北京一日游↓第1轮LLM 决定先了解北京天气 → 调用搜索工具↓第2轮LLM 得到天气信息继续思考需要知道景点 → 再次调用搜索↓第3轮LLM 得到景点信息综合所有信息 → 生成完整旅游规划关键设计点存储调用指令A1必须将 LLM 的工具调用请求存入记忆否则下次调用时 LLM 会忘记tool_call_idA4必须带上调用 ID让 LLM 知道结果对应哪个工具防止死循环最多 5 轮工具调用避免无限循环运行与测试 运行 ToolAgentpython3 tool_agent.py 示例对话场景1询问天气需要调用工具 你今天北京天气怎么样 [Thinking] 第 1 轮思考... ✋ [Action] 正在调用工具: google_search ... ⚙️ [System] 正在调用工具: google_search 参数: {query: 北京天气} [Observation] 工具返回: - 北京今天天气预报: 晴天气温25°C... [Thinking] 第 2 轮思考... Final Answer: 根据搜索结果北京今天是个好天气晴天气温25°C非常适合外出活动。 场景2简单对话不需要工具 你你好 [Thinking] 第 1 轮思考... Final Answer: 你好我是全能助手有什么可以帮助你的吗 场景3退出 你q 再见或使用 CtrlCMac 上是 CmdC 你^C 检测到中断退出程序常见问题排查❌ 问题1ModuleNotFoundError错误信息ModuleNotFoundError: No module named openai解决方法pip3 install -r requirements.txt❌ 问题2API Key 错误错误信息Error code: 401 - Unauthorized解决方法检查.env文件中的API_KEY是否正确确认没有多余空格或引号重启脚本❌ 问题3余额不足错误信息Error code: 402 - Insufficient Balance解决方法充值 DeepSeek 账户或切换到其他 API如 Ollama 本地模型❌ 问题4搜索失败错误信息搜索失败: Invalid API Key解决方法在.env文件中配置SERPAPI_API_KEY访问 SerpAPI 官网注册获取免费 Key❌ 问题5无法退出现象 输入q后程序不退出解决方法检查代码中是否有break语句确保保存了文件并重启脚本使用CtrlC强制退出总结与进阶 我们实现了什么✅ 统一的大模型适配层 - 轻松切换不同厂商✅ 对话记忆系统 - 实现多轮对话✅ 工具注册和执行 - 让 Agent 能做事✅ 消息标准化 - 确保通信规范✅ ReAct 循环 - 推理行动的智能决策 可以继续扩展的方向添加更多工具registry.registerdef get_weather(city: str): 获取天气信息 passregistry.registerdef calculate(expression: str): 计算数学表达式 pass记忆优化实现记忆窗口限制历史长度重要信息提取和总结长期记忆存储数据库任务规划分解复杂任务多步骤执行目标导向流式输出实时显示 LLM 回复提升用户体验多模态能力图像处理语音交互文件操作## 最后近期科技圈传来重磅消息行业巨头英特尔宣布大规模裁员2万人传统技术岗位持续萎缩的同时另一番景象却在AI领域上演——AI相关技术岗正开启“疯狂扩招”模式据行业招聘数据显示具备3-5年大模型相关经验的开发者在大厂就能拿到50K×20薪的高薪待遇薪资差距肉眼可见业内资深HR预判不出1年“具备AI项目实战经验”将正式成为技术岗投递的硬性门槛。在行业迭代加速的当下“温水煮青蛙”式的等待只会让自己逐渐被淘汰与其被动应对不如主动出击抢先掌握AI大模型核心原理落地应用技术项目实操经验借行业风口实现职业翻盘深知技术人入门大模型时容易走弯路我特意整理了一套全网最全最细的大模型零基础学习礼包涵盖入门思维导图、经典书籍手册、从入门到进阶的实战视频、可直接运行的项目源码等核心内容。这份资料无需付费免费分享给所有想入局AI大模型的朋友扫码免费领取全部内容部分资料展示1、 AI大模型学习路线图2、 全套AI大模型应用开发视频教程从入门到进阶这里都有跟着老师学习事半功倍。3、 大模型学习书籍文档4、AI大模型最新行业报告2025最新行业报告针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估以了解哪些行业更适合引入大模型的技术和应用以及在哪些方面可以发挥大模型的优势。5、大模型大厂面试真题整理了百度、阿里、字节等企业近三年的AI大模型岗位面试题涵盖基础理论、技术实操、项目经验等维度每道题都配有详细解析和答题思路帮你针对性提升面试竞争力。6、大模型项目实战配套源码学以致用在项目实战中检验和巩固你所学到的知识同时为你找工作就业和职业发展打下坚实的基础。学会后的收获• 基于大模型全栈工程实现前端、后端、产品经理、设计、数据分析等通过这门课可获得不同能力• 能够利用大模型解决相关实际项目需求 大数据时代越来越多的企业和机构需要处理海量数据利用大模型技术可以更好地处理这些数据提高数据分析和决策的准确性。因此掌握大模型应用开发技能可以让程序员更好地应对实际项目需求• 基于大模型和企业数据AI应用开发实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能 学会Fine-tuning垂直训练大模型数据准备、数据蒸馏、大模型部署一站式掌握• 能够完成时下热门大模型垂直领域模型训练能力提高程序员的编码能力 大模型应用开发需要掌握机器学习算法、深度学习框架等技术这些技术的掌握可以提高程序员的编码能力和分析能力让程序员更加熟练地编写高质量的代码。扫码免费领取全部内容这些资料真的有用吗这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理现任上海殷泊信息科技CEO其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证服务航天科工、国家电网等1000企业以第一作者在IEEE Transactions发表论文50篇获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。资料内容涵盖了从入门到进阶的各类视频教程和实战项目无论你是小白还是有些技术基础的技术人员这份资料都绝对能帮助你提升薪资待遇转行大模型岗位。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】