当前位置: 首页 > news >正文

50行Python手搓一个原生AI Agent:彻底看懂智能体的本质


你是不是也被各种AI Agent框架搞晕了?LangChain、CrewAI、AutoGPT… 每个框架都有几百个类、几千行代码,文档看到头大,却始终没搞懂Agent到底是什么。

今天我要告诉你一个真相:AI Agent的核心,其实就是一个while循环。所有复杂的框架,本质上都是在这个循环外面包了一层又一层的抽象。只要你理解了这个最基本的循环,你就能看懂所有Agent框架的源码,甚至能自己写出比框架更灵活的实现。

这篇文章我会用纯原生Python,不依赖任何Agent框架,只用50行代码,带你实现一个完整的、具备工具调用能力的AI Agent。你会亲眼看到,所谓的"智能体",到底是怎么工作的。

AI Agent的本质:一个循环而已

在写代码之前,我们先搞清楚一个最核心的问题:什么是AI Agent?

很多人会给你讲一堆高大上的概念:感知层、认知层、执行层、记忆系统、规划模块… 这些都对,但都太抽象了。

从工程实现的角度看,AI Agent = 大语言模型 + 工具集 + 一个无限循环

这个循环就是著名的"ReAct循环":

  1. 思考(Thought):模型根据当前状态,决定下一步要做什么
  2. 行动(Action):调用对应的工具执行操作
  3. 观察(Observation):获取工具执行的结果
  4. 重复:把结果返回给模型,继续下一轮思考

就是这么简单。所有复杂的Agent系统,都是在这个基础循环上扩展出来的。

我画了一张最简单的Agent架构图,你一看就懂:

用户输入目标

初始化消息历史

是否完成任务?

调用大模型思考

需要调用工具?

解析工具调用参数

执行工具函数

将结果添加到消息历史

生成最终回答

返回给用户

看到了吗?整个流程没有任何神秘的地方。大模型只是这个循环中的一个"思考"环节,它的作用就是判断:我现在需要调用什么工具?或者我已经有足够的信息回答用户了吗?

50行代码实现完整AI Agent

好了,理论讲完了,现在开始写代码。我们只需要安装一个依赖:openaiSDK。

pipinstallopenai python-dotenv

然后创建一个simple_agent.py文件,把下面的代码复制进去。我数过了,去掉空行和注释,正好50行左右。

importosimportjsonfromdotenvimportload_dotenvfromopenaiimportOpenAI# 加载环境变量load_dotenv()client=OpenAI(api_key=os.getenv("OPENAI_API_KEY"))MODEL="gpt-4o-mini"# 用最便宜的模型就行,效果足够好# 定义工具函数:这就是Agent的"手脚"defget_weather(city:str)->str:"""查询指定城市的天气"""# 这里模拟API调用,实际项目中替换成真实的天气APIweather_data={"北京":"晴天,25-32℃,微风","上海":"多云,23-28℃,东南风3级","深圳":"雷阵雨,26-30℃,南风4级"}returnweather_data.get(city,f"抱歉,没有找到{city}的天气信息")defget_current_time()->str:"""获取当前系统时间"""fromdatetimeimportdatetimereturndatetime.now().strftime("%Y年%m月%d日 %H:%M:%S")defcalculate(expression:str)->str:"""执行数学计算"""try:returnf"计算结果:{eval(expression)}"exceptExceptionase:returnf"计算错误:{str(e)}"# 工具定义:告诉模型有哪些工具可用TOOLS=[{"type":"function","function":{"name":"get_weather","description":"查询指定城市的天气情况","parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名称,例如:北京"}},"required":["city"]}}},{"type":"function","function":{"name":"get_current_time","description":"获取当前系统时间","parameters":{"type":"object","properties":{}}}},{"type":"function","function":{"name":"calculate","description":"执行数学计算,支持加减乘除和括号","parameters":{"type":"object","properties":{"expression":{"type":"string","description":"数学表达式,例如:123 * 456"}},"required":["expression"]}}}]# 工具映射:方便根据函数名找到对应的函数tool_map={"get_weather":get_weather,"get_current_time":get_current_time,"calculate":calculate}defrun_agent(user_query:str)->str:"""运行AI Agent的主函数"""messages=[{"role":"system","content":"你是一个有用的AI助手。你可以使用提供的工具来帮助用户解决问题。如果需要调用工具,请使用函数调用格式。当你有足够的信息回答用户问题时,请直接给出最终答案,不要继续调用工具。"},{"role":"user","content":user_query}]whileTrue:# 调用大模型思考response=client.chat.completions.create(model=MODEL,messages=messages,tools=TOOLS,tool_choice="auto")message=response.choices[0].message messages.append(message)# 如果模型不需要调用工具,直接返回回答ifnotmessage.tool_calls:returnmessage.content# 执行所有工具调用fortool_callinmessage.tool_calls:function_name=tool_call.function.name function_args=json.loads(tool_call.function.arguments)print(f"\n🤖 Agent正在调用工具:{function_name}({function_args})")# 调用对应的工具函数function_response=tool_map[function_name](**function_args)print(f"📦 工具返回结果:{function_response}")# 将工具结果添加到消息历史messages.append({"role":"tool","tool_call_id":tool_call.id,"name":function_name,"content":function_response})# 测试一下if__name__=="__main__":print("="*50)print("50行Python实现的AI Agent")print("="*50)whileTrue:user_input=input("\n请输入你的问题(输入'退出'结束): ")ifuser_input.lower()in["退出","exit","quit"]:breakprint("\n🧠 Agent正在思考中...")result=run_agent(user_input)print(f"\n✅ Agent回答:{result}")

代码逐行解析

别看代码短,它包含了一个完整AI Agent的所有核心组件:

1. 工具定义(第13-35行)

这是Agent的"手脚"。我们定义了三个简单的工具:查询天气、获取时间、数学计算。每个工具都有清晰的描述和参数定义,大模型会根据这些描述来决定什么时候调用哪个工具。

2. 工具映射(第68-72行)

一个简单的字典,把函数名映射到实际的函数对象。这样当模型说"我要调用get_weather函数"的时候,我们就能快速找到对应的函数并执行。

3. 主循环(第85-112行)

这就是Agent的心脏!整个run_agent函数就是一个无限循环:

  • 第89-95行:调用大模型,让它根据当前的消息历史思考下一步
  • 第99-100行:如果模型说"我不需要工具了,我可以回答了",就直接返回结果
  • 第103-111行:如果模型需要调用工具,就解析参数,执行工具函数,然后把结果返回给模型
  • 然后循环继续,直到模型认为任务完成

就是这么简单!没有任何复杂的抽象,没有任何黑箱操作。每一步你都能看得清清楚楚。

运行效果演示

现在我们来运行一下这个Agent,看看它的表现:

================================================== 50行Python实现的AI Agent ================================================== 请输入你的问题(输入'退出'结束): 现在几点了? 🧠 Agent正在思考中... 🤖 Agent正在调用工具: get_current_time({}) 📦 工具返回结果: 2026年05月28日 19:52:37 ✅ Agent回答: 现在的时间是2026年05月28日 19:52:37。 请输入你的问题(输入'退出'结束): 北京今天天气怎么样?适合穿什么衣服? 🧠 Agent正在思考中... 🤖 Agent正在调用工具: get_weather({'city': '北京'}) 📦 工具返回结果: 晴天,25-32℃,微风 ✅ Agent回答: 北京今天是晴天,气温在25-32℃之间,有微风。建议穿短袖、短裤等轻薄透气的衣服,注意防晒。 请输入你的问题(输入'退出'结束): 1234乘以5678等于多少?再加上9876呢? 🧠 Agent正在思考中... 🤖 Agent正在调用工具: calculate({'expression': '1234 * 5678'}) 📦 工具返回结果: 计算结果: 7006652 🤖 Agent正在调用工具: calculate({'expression': '7006652 + 9876'}) 📦 工具返回结果: 计算结果: 7016528 ✅ Agent回答: 1234乘以5678等于7006652,再加上9876等于7016528。

看到了吗?这个只有50行代码的Agent,已经能够:

  • 自主判断是否需要调用工具
  • 正确解析工具参数
  • 连续调用多个工具完成复杂任务
  • 根据工具返回的结果生成自然语言回答

这和你用LangChain写出来的Agent,本质上没有任何区别。

为什么我建议你先写原生实现

很多人一上来就用LangChain,结果遇到问题根本不知道怎么调试。比如Agent突然不调用工具了,或者调用了错误的工具,你根本不知道是提示词的问题,还是框架的问题,还是模型本身的问题。

但是如果你先写过这个原生的实现,你就会明白:

  • 工具调用本质上就是模型输出了一个特定格式的JSON
  • 消息历史是Agent唯一的"记忆"
  • 框架所谓的"AgentExecutor",其实就是一个while循环

当你理解了这些本质之后,再去看任何Agent框架的源码,都会觉得一目了然。而且在实际项目中,很多时候原生实现比框架更灵活,性能更好,也更容易调试。

扩展方向:从50行到生产级

这个50行的Agent虽然简单,但它是一个完整的骨架。你可以在这个基础上,很容易地扩展出各种高级功能:

  1. 增加更多工具:比如网页搜索、文件读写、数据库查询、发送邮件等
  2. 增加记忆系统:用向量数据库存储长期记忆,实现上下文感知
  3. 增加规划能力:让Agent先把复杂任务拆解成步骤,再一步步执行
  4. 增加错误处理:处理工具调用失败、模型输出格式错误等情况
  5. 增加流式输出:让Agent的回答能够实时显示给用户
  6. 增加多轮对话:支持用户和Agent进行连续的对话

总结

AI Agent不是什么神秘的黑科技,它的核心就是一个"思考-行动-观察"的循环。所有复杂的框架,都是在这个循环的基础上构建起来的。

通过这50行代码,我希望你能真正理解Agent的本质。不要被各种高大上的概念和复杂的框架吓倒。编程的真谛,就是把复杂的问题拆解成简单的步骤,然后用代码一步步实现。

现在你已经有了一个可以工作的Agent骨架,接下来就尽情发挥你的想象力,用它来解决你自己的问题吧。

http://www.rkmt.cn/news/1419698.html

相关文章:

  • MATLAB机器人控制器仿真代码包:从建模、设计到响应验证的一站式实现
  • 如何快速掌握BepInEx:Unity游戏模组开发的终极框架指南
  • 2026年4月目前靠谱的变压器定制推荐,龙门架电力构架/四管塔避雷塔/独立避雷针/三柱塔避雷针,变压器来图加工厂家销售 - 品牌推荐师
  • 别再靠猜了!用SystemView+FreeRTOS实时‘看透’你的任务调度(保姆级配置避坑)
  • 从抓包看本质:Wireshark深度解读TCP报文头每个字段的含义与实战作用
  • 基于Whisper、Llama 2与Bark构建本地离线语音助手实战指南
  • Uber 4 个月烧光 2026 全年 AI 预算:人均月账单 $500-$2000,企业 token 计费失控的第一个公开样本
  • 术语俗话 --- 什么是类C代码
  • 体育科技革命:从数据采集到AI分析,技术如何重塑竞技体育
  • 如何用 ChatGPT 提升学习指导效率?完整实现指南
  • Gemini多语言翻译质量深度拆解(中/日/阿/印地语实测盲区大曝光)
  • 微服务间的远程接口调用:OpenFeign 的使用
  • 鸿蒙数学 108 篇 第二十八篇:计数体系完整推演
  • MATLAB配电网状态估计算法包:最小二乘+解耦双模型,改参数就能跑不同拓扑
  • 如何用tcc-g15实现戴尔G15散热控制的终极开源替代方案
  • Hermes Agent框架连接Taotoken自定义模型提供商详细步骤
  • 2026专业的杭州酒店花园设计施工公司口碑排行榜 - 品牌排行榜
  • Django+OpenCV人脸采集与比对Web系统(含数据库、媒体资源和完整迁移文件)
  • 2025-2026年维克顿数字能源电话查询:使用前请核实资质与产品适配性 - 品牌推荐
  • 炉石传说HsMod插件:55项实用功能全面优化你的游戏体验
  • 水文极值适线拟合工具:支持6h/12h/24h降雨样本,内置皮III型与极值I型分布
  • Claude架构评审实战指南:7步完成生产级AI系统健壮性评估
  • 仅限首批内测团队获取:DeepSeek官方未公开的移动端Profile模板(含GPU占用热力图+KV Cache命中率实时监控)
  • 初创公司如何借助Taotoken以更低成本试错多个AI模型
  • AI开发工具实战:七、一个完整的 AI 开发工作流(系列总结)
  • 【infra之路】C/C++编译链接与执行全链路拆解
  • 易观分析:2026Q1中国GEO服务商市场规模约16亿元,前10名行业集中度不足10%
  • Science Robotics | 不靠大脑靠身体:这群机器人靠“纠缠”就能成群结队地运动
  • Gemini投资者关系管理SOP手册(含SEC/FCA双合规模板+季度财报话术库·限时内部版)
  • 【造数利器】一键生成数十万行高度拟真的测试CSV文件并导入MySQL