首页/新闻资讯/正文详情

从零实现一个最小 AI Agent:ReAct 循环 + 工具调用,200 行 Python 直接跑

发布时间:2026/9/26 12:43:01 来源:云帆数科 栏目:资讯中心
从零实现一个最小 AI Agent:ReAct 循环 + 工具调用,200 行 Python 直接跑
从零实现一个最小 AI AgentReAct 循环 工具调用200 行 Python 直接跑收藏榜上 Agent 原理拆解系列在收收藏Agent 工具链也是最近最大的主题群——但多数人被框架文档劝退。其实 Agent 的最小骨架只有三样东西LLM 工具 循环。本篇不依赖任何框架200 行以内写一个能多步推理、调用工具、自己修参数的 ReAct Agent代码直接跑。结论先放这儿问题答案Agent 是什么LLM 工具 循环没有更多什么任务需要单次问答不需要要根据中间结果调整动作的才需要要不要上框架先跑通最小循环上规模后再说 LangGraph最要命的三坑死循环、上下文膨胀、错误没喂回去一条铁律先记住模型只输出意图执行权永远在你的代码里。模型“决定调用哪个工具、传什么参数”真正执行的是你写的函数——这条既是安全边界也是调试入口。一、最小骨架三样东西LLM负责推理和决策工具集一组函数 各自的说明注册在一张表里循环模型输出“我要调工具 X”→ 你的代码执行 → 结果喂回去 → 模型看结果继续直到给出最终答案对比一下普通 function calling 是一问一答模型最多调一次工具Agent 循环是做完一步、看结果、再决定下一步。“A 公司主要合作方的最大竞争对手的 CEO 是谁”这种多跳问题靠一次调用答不了必须循环。二、ReAct想一步做一步ReAct Reasoning Acting。每轮让模型先输出思考为什么调再输出动作调哪个工具、传什么参工具结果作为观察喂回去。每轮只输出 JSON两种格式之一工具调用或最终答案。选 JSON 而不是自造格式的原因主流平台都有原生 JSON mode输出格式有保证还省 token——重试是最贵的浪费这个在之前的省 token 六技巧里写过。三、完整代码单文件直接跑# agent.py — 最小 ReAct Agent无框架依赖 # 依赖pip install openai export OPENAI_API_KEYsk-xxx import json from openai import OpenAIclient OpenAI()---------- 工具注册 ----------TOOLS {}def tool(name, description): def deco(fn): TOOLS[name] {fn: fn, description: description} return fn return decotool(calculator, 计算四则运算表达式输入字符串如 123) def calculator(expression: str) - str: # ponytail: eval 受限白名单生产换 ast 解析防注入 if not set(expression) set(0123456789-/(). ): raise ValueError(表达式含非法字符) return str(eval(expression))tool(search_notes, 在知识库里检索与问题相关的片段) def search_notes(query: str, k: int 3) - str: # ponytail: 占位假检索换成你的向量库 / GraphRAG 检索 notes [RAG 通过检索相关片段再喂给模型省 token 又缓解长上下文遗忘, Agent 循环每步都是一次 LLM 调用累积延迟和幻觉风险都会放大, 提示词缓存要求稳定内容在前、变化内容在后命中率才高] hits [n for n in notes if any(w in n for w in query)] return \n.join((hits or notes)[:k])---------- Prompt ----------def tool_schemas(): return \n.join(f- {n}: {t[description]} for n, t in TOOLS.items())SYSTEM f你是一个严谨的助手可以调用工具每轮只调用一个。 可用工具 {tool_schemas()}每轮只输出一个 JSON 对象两种格式之一需要调用工具 {{thought: 一句话说明为什么调用, action: {{name: 工具名, args: {{}}}}}}已经有答案 {{final: 给用户的完整回答}}---------- 循环 ----------def run_agent(question: str, max_steps: int 8): messages [ {role: system, content: SYSTEM}, {role: user, content: question}, ] called [] # 死循环检测同样的调用出现第二次就打断 for step in range(1, max_steps 1): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, response_format{type: json_object}, ) out json.loads(resp.choices[0].message.content) if final in out: return out[final], step name, args out[action][name], out[action].get(args, {}) sig json.dumps(out[action], ensure_asciiFalse, sort_keysTrue) if sig in called: return f检测到重复调用 {name}提前终止, step called.append(sig) try: result TOOLS[name]fn except Exception as e: result f工具执行失败{e} # 错误当观察喂回去模型常能自己改对参数 messages [ {role: assistant, content: json.dumps(out, ensure_asciiFalse)}, {role: user, content: f[工具 {name} 返回]\n{str(result)[:2000]}}, ] return 达到最大步数仍未得到答案, max_stepsifname main: answer, steps run_agent(帮我算一下 (12872)*3再用检索确认 RAG 是什么) print(f[{steps} 步] {answer})不花 API 调用的自检验证工具注册和错误路径assert calculator in TOOLS assert calculator(12*3) 7 try: calculator(__import__(os)) assert False, 白名单没拦住 except ValueError: pass四、五个踩坑第一周都会遇到死循环模型反复用同样参数调同一个工具。双保险max_steps 硬上限 重复调用签名检测上面代码里的 called 列表上下文膨胀工具返回大 JSON 直接塞 messages三四轮就把窗口吃满。解法返回值裁剪再喂代码里 str(result)[:2000]更讲究的做法是滚动摘要参数类型漂移模型传k: 3字符串而函数要 int。解法工具入口统一强转或在工具说明里写死类型示例错误不喂回去工具抛异常直接崩掉整个循环。把错误作为观察喂回去模型经常能自己改对参数重试——这一条对成功率提升最明显JSON 输出抖动在 prompt 里反复喊“请输出 JSON”不如原生 response_format格式有保证还省 token五、什么时候上框架这个最小循环没有的东西持久化、断点续跑、人工审批节点、多 Agent 协作、可视化。任务上规模后再补需要断点续跑 / 人工确认节点 → LangGraph复杂状态机 → 框架的状态管理但顺序别反先跑通最小循环知道每一层在解决什么问题再上框架——否则框架只是把黑盒变大出问题都不知道去哪查。总结Agent LLM 工具 循环。铁律压成三句模型只输出意图执行权在你的代码里工具结果也是上下文裁剪后再喂循环必须有上限死循环是第一周就会遇到的事

相关推荐

大模型Agent智能体开发实战:从零搭建餐饮服务智能体
大模型Agent智能体开发实战:从零搭建餐饮服务智能体

1. 从"服范-九添菜菜"这个项目名说起:一个智能体到底在解决什么问题 第一次看到"服范-九添菜菜大模型Agent智能体开发实战"这个标题,很多人会愣一下——"服范"是什么?"九添菜菜"又是什么&#xff1f… · 2026/9/26 12:43:01

电商数据分析业务MCP流程建模
电商数据分析业务MCP流程建模

一、商品llm分析满意度调查二、商品EMA销量预测三、用户聚类画像分析四、协同过滤商品推荐五、逻辑回归用户流失预测六、商品降价线性回归促销预测 · 2026/9/26 12:43:01

大模型推理多副本调度:Data Parallel余量感知路由实战
大模型推理多副本调度:Data Parallel余量感知路由实战

1. 从一个反直觉的现象说起:为什么副本空闲,请求却在排队 如果你部署过多副本的大模型推理服务,大概率见过这种场景:监控面板上四个副本的 GPU 利用率分别是 92%、88%、31%、29%,但用户侧的 P99 延迟依然在飙。你打开日… · 2026/9/26 12:43:01

十款免费降AI率工具实测:从检测原理到修改操作全解析
十款免费降AI率工具实测:从检测原理到修改操作全解析

毕业季一到,“降AI率”这几个字几乎成了宿舍夜谈的固定话题。你辛辛苦苦写了几个月,最后论文在AI检测系统里被标出一大片高亮区域,导师一句“这段有AI痕迹,回去改”,就能让人在图书馆坐到天亮。市面上的降AI率工具五花… · 2026/9/26 13:15:08

元宵节Scratch编程案例:接汤圆、猜灯谜与花灯巡游设计详解
元宵节Scratch编程案例:接汤圆、猜灯谜与花灯巡游设计详解

1. 元宵节和Scratch碰撞后的第一个问题:做什么才不像"大杂烩"?每次到传统节日,我的Scratch交流群里都会冒出一批"求节日作品"的帖子。中秋要月亮嫦娥,端午要粽子龙舟,到了元宵节,最常看… · 2026/9/26 13:15:02

Vue3项目集成xgplayer播放器:从封装到踩坑的完整实践
Vue3项目集成xgplayer播放器:从封装到踩坑的完整实践

最近接了个Vue3项目,要做课程视频播放模块。一开始我拿原生video标签凑合,结果倍速、清晰度切换、键盘快捷键、自定义控制条这些功能写完,UI丑得自己都嫌弃。后来换成xgplayer,半天就把这块捋顺了。网上关于Vue3集成xgplayer的资料… · 2026/9/26 13:15:02

软件企业五大核心资产:人才、代码、数据、客户与流程盘点
软件企业五大核心资产:人才、代码、数据、客户与流程盘点

1. 资产盘点先摘掉滤镜:软件企业的家底不写在资产负债表上 1.1 一次尽调引发的扎心问题 上个月和一个做软件公司十几年的老友吃饭,他说自己正筹备把公司整体卖掉,买方已经安排了三个月的尽调。他一边算账一边叹气:几十台电脑、几… · 2026/9/26 13:15:02

autoclip 自托管剪贴板同步:从部署到避坑完整指南
autoclip 自托管剪贴板同步:从部署到避坑完整指南

1. autoclip 到底是什么,解决什么问题 做技术这些年,我发现自己最常浪费时间的场景不是写代码,而是"把这段内容从 A 设备挪到 B 设备"。手机收到验证码,要切到电脑登录页面手动输入;电脑上复制了一段日志&am… · 2026/9/26 13:15:02

知网AIGC检测误杀论文怎么办?降痕工具对比通用AI实测
知网AIGC检测误杀论文怎么办?降痕工具对比通用AI实测

先说个真实场景:你花了两周把论文改了三稿,用AI润色了几段连接词,自己觉得逻辑顺、语言也自然,结果一上知网查重,系统直接给你标了一句“疑似AIGC占比41%”,后面还跟个红条“建议修改后检测”。这还不是个例… · 2026/9/26 13:15:02

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码