
系列100 天系统学习 AI Agent 开发当前阶段Agent 基础与环境搭建Day 006/100今日目标抛开框架名词用原生代码拆解 Agent Loop计划、行动、观察、再计划跑通最小闭环。很多人刚接触 AI Agent 时容易被 LangChain、LangGraph、CrewAI 里各种炫酷的专有名词唬住觉得 Agent 是某种具有“自主意识”的黑魔法。但如果我们戴上工程的眼镜去拆解就会发现一件极具“祛魅”色彩的事实绝大多数 Agent底层都在重复同一个简单到令人发指的循环——理解任务、选择动作、执行工具、读取反馈、决定是否继续。如果今天不把这个 Loop循环从代码层面想透后面做工具集成、长记忆管理和自动化评测时你一定只是在盲目地调包和凭感觉 Debug。今天我们不贪多只讲透这一个点并手写一段任何框架都能用的核心逻辑。一、 3 句人话到底什么是 Agent Loop新手最容易陷入的误区是把 Agent 等同于“一个写得很复杂的 Prompt”。我们先纠正这个认知Agent 不是魔法它是一个将“大模型推理”和“外部代码执行”死死绑在一起的while循环。每次循环里大模型只做做选择题看眼历史记录决定接下来是该“调用某个函数干活”还是“已经有答案了直接回复用户”。所谓的“自主思考Re-plan”不过是代码把工具执行后拿到的“观察结果Observation”塞回历史记录里让模型再做一次选择题而已。二、 责任边界模型干什么代码干什么千万不要把什么活全推给大模型。工程落地落地最重要的一步就是画清“大脑”和“手脚”的边界模块必须由大模型负责思考与决策必须由代码兜底控制与安全任务职责• 解析用户意图与上下文• 决定下一步调用什么工具• 生成正确的工具参数• 汇总最终的人性化回答 | •死循环拦截设置最大轮数• 工具执行的权限校验与沙盒隔离• API 调用失败的重试与错误捕获• 历史记录Observation的持久化与剪裁 |三、 最小闭环与工程实践1. 最小闭环逻辑图把上面的逻辑抽象一下它的流转路线其实非常干净用户输入 (Query) │ ▼ ┌─────────────────────────────────────────┐ │ While 循环在运行 │ │ │ │ ┌─────────────────────────────────┐ │ │ │ 1. Plan: 大模型决定下一步行动 │ │ │ └─────────────────┬───────────────┘ │ │ │ │ │ [ 是否调用工具? ] │ │ / \ │ │ 是 否 │ │ ▼ ▼ │ │ ┌──────────────┐ ┌─────────────┐ │ │ │ 2. Act: │ │ 4. Output: │ │ │ │ 代码执行工具 │ │ 输出最终结果 │ │ │ └──────┬───────┘ └─────────────┘ │ │ ▼ │ │ │ ┌──────────────┐ │ │ │ │ 3. Observe: │ │ │ │ │ 记录结果并回传 │ │ │ │ └──────┬───────┘ │ │ │ │ │ │ └──────────┼─────────────────────┼────────┘ │ (Re-plan) ▼ └──────────────► 任务完成退出循环2. 伪代码实现限制最多 5 轮调用这不仅是一段概念演示你可以直接把它作为自研 Agent 核心路由的雏形defagent_loop(user_query:str,max_steps:int5):# 初始化对话历史把用户意图塞进去messages[{role:user,content:user_query}]step0# 核心由代码控制的最大轮数兜底绝不把停止的命运完全交给 LLMwhilestepmax_steps:step1print(f--- 正在执行第{step}轮思考 ---)# 1. Plan Act决策让模型看历史记录决定下一步responsellm.chat(messagesmessages,toolsavailable_tools)# 2. 停止条件判断如果模型觉得信息够了没有发起工具调用直接输出ifnotresponse.has_tool_calls():print(任务完成)returnresponse.final_content# 3. Act执行解析模型想调用的工具和参数tool_nameresponse.tool_call.name tool_argsresponse.tool_call.argsprint(f- 动作 (Act): 准备调用工具 [{tool_name}]参数:{tool_args})# 4. 代码执行真实的函数捕获异常防止代码崩溃try:observationexecute_tool(tool_name,tool_args)exceptExceptionase:observationf工具执行报错:{str(e)}print(f- 观察 (Observe): 工具返回结果 -{str(observation)[:50]}...)# 5. Re-plan再计划把把这次调用和执行的结果追加到记忆里# 下一次 while 循环时模型就能看到“我调了工具得到了这个结果”从而进行下一步判断messages.append({role:assistant,tool_call:response.tool_call})messages.append({role:tool,name:tool_name,content:str(observation)})# 如果触发了强制退出return已达到最大执行轮数5次任务被迫中止请检查任务复杂度或工具可用性。四、 踩坑实录为什么max_steps绝对不能省略在今天写小实验的时候我想测试一下如果不加while step max_steps会发生什么结果故意输入了一个具有误导性的测试用例反例输入“帮我查一下‘亚特兰蒂斯南区’今天下午2点到3点的准确降雨量精确到毫米。”发生了什么大模型极其认真调用get_weather工具去查。工具老实返回Error: Location 亚特兰蒂斯南区 not found.陷入死循环模型开始展示它“顽强”的自主思考能力Re-plan猜测可能是名字拼写问题于是依次调工具查了“Atlantis”、“亚特兰蒂斯”、“亚特兰蒂斯市”、甚至把问题拆解成去查*“虚拟城市天气查询接口”*…几秒钟内工具被疯狂调用了十几遍不仅瞬间烧掉了一堆 Token还把模拟的下游 API 给触发限流了。教训永远不要假设大模型“知道什么时候该放弃”。当工具报错或任务无解时模型很容易陷入死循环死磕。工程上的强制重试上限max_steps和超时的机制是你的 Agent 不会因为某个 Bug 让你破产的最后一道防火墙。五、 今日产物学习归档按照我们 100 天学习计划的铁律每天都要留下一个可以放入项目 README 或记忆库的工程结构化产物。今天的沉淀已保存至项目目录notes/day_006_learning.md{day:6,topic:Agent Loop 拆解计划、行动、观察、再计划,core_takeaway:Agent 本质是一个将 LLM 决策与代码执行挂钩的 while 循环。自主能力来源于不断把 Observation 塞回 Prompt 后再次生成。,code_artifact:实现了一个带限制上限 (max_steps5) 和异常捕获的原生 Agent Loop 伪代码。,pitfall_recorded:无边界死循环当工具持续返回错误或查询不存在的内容时缺乏轮数限制会导致模型无限尝试消耗大量 Token。,next_day_input:既然 Loop 会把所有的 Observation 追加到 messages 里那明天如果工具返回了一份 5000 行的 JSON上下文窗口被撑爆了怎么办}读者行动指南今日你能怎么做如果你也在同步搭自己的 Agent 项目建议你今天只做一件事打开你现在最常用的 Agent 框架不管是 LangChain 还是 OpenAI SDK找到底层的源码尝试搜索while或者loop关键字。看看那些年收几十万 Star 的框架在剥离了所有包装类后是怎么小心翼翼地维系这个最简单的“思考-执行-观察”循环的。看完你就会懂真正的优雅往往隐藏在最朴素的逻辑里。