:Agent 的核心循环:思考、行动、观察,就这么简单)
这是系列的第 23 篇。整个系列写给零基础、想入行 AI 的朋友每天一篇30 天后你会做出 3 个能写进简历的项目。这篇解决什么问题昨天说 Agent 的核心三件套是大模型、工具、循环。今天我们来造那个最关键的部件循环。不夸张地说今天这一篇是整周技术含量最高的。但代码不超过 50 行而且结构极其清晰。跑通之后Agent 对你来说就再也不是黑盒了你会知道它每一步在想什么。一、循环到底在循环什么先说清楚逻辑再写代码。你让 Agent 做一件事它不会一次就做完。它需要一个过程每轮循环做三件事思考现在信息够了吗不够的话下一步该用哪个工具行动真的去调用那个工具观察看看工具返回了什么然后进入下一轮什么时候停两种情况AI 认为信息够了给出最终答案或者达到了最大步数上限防止它死循环烧钱。整个程序的骨架就是一个 while 循环里面套着一次 API 调用。就这么多。二、用大白话写出流程在写代码前我们用自然语言把程序走一遍准备好工具清单和对话记录 设定最大步数 5 while 还没到最大步数: 把对话记录和工具清单发给大模型 如果它说要调用工具 执行这个工具把结果追加到对话记录 继续下一轮 如果它直接给了回答 输出回答结束循环这就是全部。接下来把每一块填上代码。三、造一个最小 Agent新建 agent_demo.py。先准备两个工具简单点但要有实际意义importjsonfromopenaiimportOpenAI clientOpenAI(api_key你的密钥,base_urlhttps://api.deepseek.com)# 工具一算数AI 自己算数容易错交给代码算defcalculate(expression):try:returnstr(eval(expression))# 教学演示用正式项目别用 evalexceptExceptionase:returnf计算出错{e}# 工具二查资料模拟的真实项目里换成查数据库或搜索defsearch_notes(keyword):notes{项目:项目一是文件整理助手项目二是RAG知识库,面试:面试重点准备RAG流程、Function Calling原理、成本优化,}returnnotes.get(keyword,没有找到相关笔记)然后是给 AI 看的工具说明书tools[{type:function,function:{name:calculate,description:计算数学表达式。当需要做数字运算时使用比如 12*38,parameters:{type:object,properties:{expression:{type:string,description:要计算的表达式}},required:[expression]}}},{type:function,function:{name:search_notes,description:在个人笔记里搜索关键词。当需要回忆之前记录的内容时使用,parameters:{type:object,properties:{keyword:{type:string,description:搜索的关键词}},required:[keyword]}}}]# 工具名到函数的映射方便代码按名字调用tool_map{calculate:calculate,search_notes:search_notes}现在写核心循环defrun_agent(task,max_steps5):跑一个 Agent最多走 max_steps 步messages[{role:system,content:你是一个助理可以用工具帮用户解决问题。信息足够时直接给答案。},{role:user,content:task}]forstepinrange(max_steps):print(f\n 第{step1}步 )responseclient.chat.completions.create(modeldeepseek-chat,messagesmessages,toolstools)msgresponse.choices[0].message# 情况一它想调用工具ifmsg.tool_calls:messages.append(msg)# 先把它的请求记下来forcallinmsg.tool_calls:namecall.function.name# 工具名argsjson.loads(call.function.arguments)# 参数print(f决定调用{name}参数{args})# 真的执行工具functool_map.get(name)resultfunc(**args)iffuncelse没有这个工具print(f执行结果{result})# 把结果交回给 AImessages.append({role:tool,tool_call_id:call.id,# 回执单号必须对上content:result})continue# 继续下一轮循环# 情况二它给出最终回答print(最终回答,msg.content)returnmsg.content# 走到最大步数还没结束兜底print(达到最大步数任务未完成)returnNone跑起来试试run_agent(我笔记里关于面试的记录是什么帮我算一下 24*365 等于多少)你会看到它走好几步先搜索笔记再算数最后把两件事合起来回答你。每一次决定调用哪个工具都是它当场判断的不是你写死的。这个体验很关键。你第一次看到一个程序会自己规划步骤就是现在。四、为什么必须设最大步数上面代码里那个 max_steps5不是凑数的是保命用的。Agent 可能死循环。举例工具一直返回空结果它就一遍遍重试或者它理解错了任务反复调用同一个工具。没有上限你的钱包会被它一直烧下去。所以 max_steps 是 Agent 的必备护栏。行业内所有成熟的 Agent 框架都强制要求设这个上限你写上去就是专业习惯。除了步数上限还有两个护栏值得知道第一成本上限。记录累计 token超标就停。第二无进展检测。如果连续两轮调用同一个工具、参数也一样判定为卡住直接停。这个属于进阶优化面试时提到会很加分。五、最小 Agent 和真 Agent 的差距你今天写的这个已经能叫 Agent 了但它还很初级。差在哪说清楚你心里有数工具太少还都是假的不会把大任务拆成子任务只会一步步走没有记忆上次跑的结果这次不记得没有错误恢复工具失败一次可能就卡住Day 24 会解决工具的问题Day 25、26 解决拆任务和错误处理。但记住一件事后面所有的能力都是加在今天这个循环上的。循环是骨架别的都是肉。常见报错排查报错一Agent 反复调用同一个工具停不下来。两个原因一是工具的 description 写得不够清楚它不知道该用哪个二是工具返回的结果没解决问题它只能再试。检查工具的返回内容是不是真的有用。报错二报错说 tool_call_id 不匹配。追加 tool 消息时漏了 tool_call_id或者复制错了。这个字段是回执单号一次调用对应一个不能乱。报错三它不调用工具直接自己编答案。检查 tools 参数有没有传以及 description 里的“什么时候用”是否写清楚了。AI 完全靠这段描述判断该不该用工具。报错四循环里 messages 越来越长最后报 context 超限。长任务必然出现。用 Day 10 的滑动窗口裁剪或者只保留最近几轮的工具结果。报错五工具报错导致整个程序崩掉。工具内部要自己包异常把错误信息当结果返回给 AI让 AI 自己决定要不要换个做法。这是明天要详细讲的内容。今天的作业把最小 Agent 跑通然后加一个你自己的工具比如查当前时间、或者从预设数据里查天气。用它跑一个需要两步以上才能完成的任务把每一步的打印输出贴到评论区。看到“决定调用”“执行结果”“最终回答”这三行交替出现你就算真的入门了。明天预告Day 24《让 Agent 拿到工具查天气、读文件、算数学》。今天工具还是模拟的明天讲怎么设计真正有用的工具。工具设计是 Agent 成败的关键同一个功能描述写得好和写得烂AI 用得对不对天差地别。另外还有一个关键技巧工具报错了怎么让 AI 自己修。————————————————*系列目录30天从零开始学AI应用 开发