资讯动态

AI Agent入门:先手写循环,别急着上框架

发布时间:2026/10/22 6:17:41 来源:尧图企业网站定制
最近半年几乎每周都有人来问我同一个问题想做AI Agent该从哪开始学我的回答往往让很多人意外——先别急着装那些现成的编排框架也别一上来就啃各种Agent框架的源码。新手和转行做Agent的人最该先搞懂的其实是一套循环、一个接口协议以及几千行Python代码里最基本的几个库。这篇文章就按我真实的入门路径来写把我踩过的坑、后来验证过有用的方法一次性说清楚。1. 先搞明白Agent的“循环”它不是一个ChatGPT套壳1.1 Agent 模型 循环 工具而不是一个更大的模型很多人一听到AI Agent第一反应是“这不就是ChatGPT加了个外壳吗”。这个理解不算错但会害了你。因为一旦你抱着这种理解去学框架会发现框架里的概念又多又绕什么Chain、什么Planner、什么Memory每个都认识连起来就头晕。我更愿意把Agent拆成三个部分来看模型、循环、工具。模型负责“思考”的那部分也就是大语言模型本身。循环一个反复执行的流程通常是“观察→思考→行动→再观察”。工具模型可以调用的外部能力比如计算器、搜索、数据库查询、发邮件。三者的关系用人来类比就很好懂了。模型是大脑循环是工作流程工具是手和脚。大脑不能直接搬砖手和脚也不能自己决定搬哪块砖。Agent的价值就是把这三者串起来让大脑能指挥手脚去干活而且干完一步能回头看结果、再决定下一步。这个“回头看结果再决定下一步”的环节就是循环的核心。它和普通聊天完全不同。普通聊天是“你问一句模型答一句”答完就结束了模型不关心这句话之后发生什么。而Agent不是回答完就完事它会根据你的问题自己决定要调用什么工具看到工具返回的结果再判断下一步做什么直到它认为任务完成了。我见过不少新手一上来就翻框架文档看了一堆“AgentExecutor”“ToolNode”“Planner”这类名词越看越混乱。原因很简单框架把底层循环封装得太深了你只看到表面接口看不到背后的数据流。所以我的建议是先不要碰任何框架先自己在脑子里把“循环”这个概念扎稳。1.2 三个必须理解的边界工具、记忆、规划理解了循环之后还有三个边界必须清楚否则后面写代码一定踩坑。第一工具边界。模型本身不执行任何真实操作它只负责“决定”调用哪个工具以及“生成”传给工具的参数。真正执行的是你那几千行代码。新手最容易犯的错是把希望全寄托在模型身上以为模型能自己神奇地访问数据库、操作文件。模型确实可以生成访问数据库的代码但这些代码需要在我们自己的环境里跑起来跑通了结果再传给模型去分析它才能进一步处理。说白了模型像是一个项目经理它安排任务真正搬砖的是你的代码。第二记忆边界。大模型本身没有记忆能力。它每轮对话都只接收你本次给它的全部上下文上一次聊了什么如果不主动带着它不会自动记得。Agent系统里的记忆通常有两种一种是把历史对话拼进下一次请求里这叫短期记忆靠的是上下文窗口另一种是把重要信息存到外部数据库需要的时候检索回来这叫长期记忆。新手很容易忽视一个问题上下文窗口是有限的而且塞得越多响应越慢、成本越高。所以“记什么”和“怎么记”比“能记多少”更重要。第三规划边界。模型能生成看起来很合理的“步骤拆解”但这不代表它真的能按计划执行到位。执行过程中遇到意外情况它需要根据实时反馈调整计划。这种“边做边修正”的能力靠的正是循环。很多新手设计的Agent只会让模型输出一个完整的计划然后傻乎乎地按计划执行中间任何一步出了岔子整个任务就断了。所以规划不是一次性的它是循环里“思考”这个环节反复干的事。把这三条边界想清楚你再去看任何框架的文档会发现思维清晰很多。因为你已经知道框架里的Memory模块是在解决记忆问题ToolNode是在解决工具执行问题Planner是在解决规划问题。你带着问题去学而不是被名词牵着走。2. 不碰框架先用API把最小闭环跑起来2.1 你真正要会的Python基础比想象中少转行者最担心的就是编程基础。我直接说结论做AI Agent入门你需要的最少Python技能就那么几条不需要精通数据结构更不需要会写复杂的算法。字典和列表的读写这是处理JSON的基础。函数的定义和调用把工具封装成一个个函数。用requests或httpx发HTTP请求调大模型API和外部服务的通用能力。用json.loads和json.dumps做序列化和反序列化。用try-except做异常处理工具调用一定会出错不处理会直接崩。会读环境变量API密钥这类敏感信息绝不写死在代码里用os.getenv读取。就这些没了。有人可能会问那pandas、numpy要不要学不用。至少入门阶段不需要Agent的核心是“编排逻辑”不是“数据处理算法”。你只要能把一个函数的返回结果交给模型再把模型的决策传给另一个函数这个骨架就撑得起来。我见过有些转行者花了三个月学Python基础语法越学越心虚觉得前面还有无数知识盲区迟迟不敢动手。其实正确的做法是先掌握上面这几条然后立刻开始做一个小Agent在做的过程中遇到不会的现查现学。真实的项目会逼着你快速掌握最常用的那几个库效率远高于抱着教程空学。2.2 调用大模型API的几个关键参数先不讲复杂概念单说调API这件事。所有大模型开放平台基本都提供一个文字生成接口。你给它一段消息列表它返回模型生成的文本。这一段调用是所有Agent的地基。地基里最需要搞懂的有几个参数我一个个说temperature控制随机性取值范围通常是0到2。做Agent时我一般设很低比如0.1甚至0。因为它需要稳定地输出符合格式的结果而不是天马行空地创作。如果是写文案之类偏创意任务才把温度调高。新手常犯的错是默认值凑合用结果发现模型偶尔返回的JSON格式不规则排查半天发现是温度太高导致输出飘了。max_tokens限制生成的最大长度。这个参数既能控制成本也是防呆设计。不设的话模型可能一个劲儿输出下去钱哗哗地烧。Agent场景里模型主要任务是输出“决策”不会太长一般给个几百就够。stop停止序列。可以指定一个字符串模型一旦生成到这个字符串就停下来。比如你希望模型只输出一个JSON对象可以把“}”作为结束标志之一或者在更复杂的场景里用特定分隔符让模型在哪段停下来。这个技巧在Agent循环里非常实用能有效地让模型输出“到点就停”。stream是否流式输出。入门阶段建议先不开等响应再整体解析逻辑更简单清晰。这些参数原则上都值得亲手试一遍。我的习惯是拿到一个新模型的API先写个十行左右的脚本把温度从0调到1.5看看输出会有什么变化把max_tokens调到10看看截断长什么样。对这个“感觉”越熟悉后面做Agent越稳。2.3 结构化输出JSON就是Agent内部的“接口协议”做Agent时模型输出可不是给人看的散文而是要作为机器可以解析的指令去执行的。这里就引出了整个Agent系统里最关键的工程细节结构化输出。最常见的做法是约定模型必须返回一个固定格式的JSON对象里面包含“动作类型”和“动作参数”。比如{ action: calculator, action_input: { expression: 1 2 } }你的代码拿到这个JSON解析后知道模型想调用calculator工具参数是一个算式于是执行对应函数得到结果3再把这个结果拼到消息里回传给模型。这就是一次完整的“Agent思考→调用工具→获得结果→继续思考”的最小闭环。这个结构化输出的约定我习惯把它叫作Agent内部的“接口协议”。就像两个团队之间要对接得先定好接口规范一样。模型和代码之间的接口就是这份JSON约定。接口约定得越严格、越简单系统就越不容易出错。怎么让模型稳定输出JSON有几个经验在系统提示词里写清楚格式要求并给出一个JSON例子。模型的Few-shot能力很强给一个好的示范比单纯描述格式更有效。要求“仅输出JSON不要任何解释或前后缀”。否则模型经常输出“好的这是您需要的JSON”之类的话解析就会报错。温度设低。随机性越高越容易输出不合规内容。一定要写解析兜底的逻辑。也就是模型偶尔给不出合法JSON时你的代码要做异常处理或者干脆把错误信息回传给它让它自我纠正。3. 手写30行核心代码从零搭一个会调用工具的Agent3.1 用“动作字典”代替框架的Agent执行器接下来是实战。我不准备贴一个完整的项目那会让人有“看完还是不会”的挫败感。我只展示最核心的循环骨架大概三四十行但它是理解所有框架的一把万能钥匙。思路很简单把工具装进一个字典字典的key是工具名value是工具函数。模型输出的“action”字段就是字典的key。代码查字典拿到函数执行它得到结果回传。这样一个极简的“Agent执行器”就出来了。import json import os from openai import OpenAI client OpenAI(api_keyos.getenv(LLM_API_KEY)) def calculator(expression: str) - str: 安全的算术计算仅支持加减乘除与括号 allowed set(0123456789-*/(). ) for ch in expression: if ch not in allowed: return 错误表达式包含不允许的字符 try: result eval(expression) return str(result) except Exception as e: return f计算失败{e} def get_weather(city: str) - str: 模拟天气查询真实场景换成API调用 fake_weather { 北京: 晴25度, 上海: 多云28度, } return fake_weather.get(city, 暂无该城市数据) tools { calculator: calculator, get_weather: get_weather, } system_prompt 你是一个智能助理。你可以调用以下工具 - calculator算术计算参数为expression字符串类型 - get_weather查询天气参数为city字符串类型 你需要根据用户问题输出一个JSON对象格式如下 {action: 工具名, action_input: {参数名: 参数值}} 仅输出JSON不要任何其他内容。 def run_agent(user_input: str, max_steps: int 5): messages [ {role: system, content: system_prompt}, {role: user, content: user_input}, ] for step in range(max_steps): response client.chat.completions.create( modelyour-model-name, messagesmessages, temperature0.1, ) content response.choices[0].message.content.strip() print(f第 {step 1} 步模型输出{content}) try: decision json.loads(content) except json.JSONDecodeError: messages.append({role: assistant, content: content}) messages.append({ role: user, content: 解析JSON失败请只输出合法JSON不要包含任何额外文字。 }) continue action decision.get(action) action_input decision.get(action_input, {}) tool_func tools.get(action) if not tool_func: messages.append({ role: user, content: f未知工具{action}请从可用工具中选择。 }) continue try: result tool_func(**action_input) except Exception as e: result f工具执行出错{e} messages.append({role: assistant, content: content}) messages.append({ role: user, content: f工具结果{result}。如果任务已完成请直接只输出以下固定格式{{\action\: \final\, \action_input\: \最终答案\}}。 }) if action final: return action_input return 达到最大步骤数任务未完成。 print(run_agent(帮我算 3 * (4 5)然后看看北京天气))这段代码建议你亲手敲一遍别复制。敲的过程里你会注意到很多细节比如参数名对不上、忘记引入异常处理、模型偶尔返回非JSON时怎么办。这些细节才是Agent开发真正的门道。3.2 代码里的两个关键细节循环上限和异常回传这段代码看起来简单但有两个细节是新手最容易忽略的。第一个是循环上限。我在run_agent里设置了一个max_steps参数默认5步。这个设计极其重要。因为模型在实际运行中完全有可能陷入“反复调用工具、反复得到结果、但就是不收敛”的循环里没有步数上限的话你的程序会一直调API钱花出去了用户还在干等。我还见过一个极端案例模型在一个错误参数上反复横跳直到耗尽上下文窗口。所以循环上限是Agent系统的“安全气囊”必须有。在真实项目里我通常还会加一个超时机制。比如每轮工具调用最多等10秒整个Agent任务最多等60秒超时就直接向用户返回“任务超时请稍后重试”。这些保护机制虽然不起眼但决定了你的Agent能不能从demo变成可用的产品。第二个是异常回传。注意我把工具执行包在了try-except里并且把错误信息拼在回传消息中“工具执行出错xxx”。这招是我做了很久之后才意识到价值的。因为模型并不知道你的程序发生了什么它只能看到你回传给它的文字。你如果把错误信息吞掉回传一句“工具返回空”模型就不知道是参数错了还是环境崩了只能瞎猜。但你明明白白告诉它“除以零”、“键不存在”、“网络超时”它就有机会在下一次决策中修正自己的参数选择。这个“把错误当作反馈喂回给模型”的模式是Agent健壮性的核心。错误不是用来打断流程的而是用来帮助模型纠错的。3.3 从单轮工具调用走向多步任务再加两步记忆刚才那段代码只能处理“一次思考、一次工具调用、再看结果”的单轮循环。但真实世界的任务往往是多步的。比如“帮我查北京天气如果超过30度就提醒我带伞”。第一步要查天气第二步根据结果做判断。这两步之间模型需要记住第一步查到的结果。好在这件事不用改循环结构只要稍微改一下消息列表就行。你会发现在我的代码里messages列表一直是累加的。每轮模型的输出和工具的结果都被追加进messages。这样一来模型在下一次请求时就能看到之前所有的交互记录这就是最简单有效的短期记忆实现。如果你想更靠近真实项目可以再加一层简单的“工作记忆”也就是把任务拆成子步骤。比如用一个列表记录每步的目标、状态和结果最终汇总给模型做判断。我在很多项目里就是这么干的不依赖任何框架效果一样稳。走到这一步你已经具备了手写一个极简Agent的能力。这时候再回头看框架你会发现它无非是把这些循环逻辑封装成了可复用的组件再加上更多高级功能——重试机制、模型切换、多Agent协作等等。但底层的骨架就是上面这堆代码的增量扩展。4. 什么时候才该碰框架我的判断标准4.1 框架解决的是效率问题不是理解问题写了三章“不要一上来就碰框架”现在要公平地说说框架的价值。否则有些读者会误以为我彻底否定框架那就走偏了。框架解决的问题是效率问题不是理解问题。当你已经亲手写过一遍Agent循环你对“Agent是怎么跑起来的”已经有了底层认知。这时再接触社区里那些常见的编排框架你会有一种“原来它内部的某组件就是干这个用的”豁然开朗感。你学习框架的速度会快得多而且一旦运行出问题你能更快地定位到是框架配置问题还是你自己的逻辑问题。举个例子。框架里的“工具节点”模块本质就是我上面那段代码里字典查表逻辑的工程化升级。它可能在内部处理了并发、重试、日志、并行调用等复杂需求但核心思想没有变。你如果连手写循环都没有过直接看这个模块的源码大概率是云里雾里。框架的第二个价值是它帮你抽象掉了很多重复劳动。比如多轮对话管理、上下文截断策略、和向量数据库的对接、对多种模型厂商的统一封装。这些事情写起来不难但繁琐。如果你已经懂原理直接用框架是很划算的。4.2 过早用框架的三个典型代价很多新手有一个错觉装了框架就等于会做Agent了。实际上框架只是提供了一套积木怎么搭、搭成什么样拼的还是你对底层原理的理解。过早用框架通常会付出三个代价。第一个代价是“黑盒焦虑”。你只管调方法传参数但不知道背后发生了什么。如果一个环节报错而你连循环的基本流程都讲不清就只能上网搜解决方案搜到什么都试试运气好能试通运气不好就卡死。有一次我帮一个朋友排查问题他用的框架版本里改了API旧的调用方式失效了他一头雾水。我问他“你的数据在哪个环节断了”他答不上来因为他对框架内部的数据流完全没概念。这就是黑盒的代价。第二个代价是“版本迁移成本”。编排框架的迭代速度极快API经常变。如果你对底层原理不熟框架一升级你的代码就可能大面积报错而且根本无从下手。反过来如果你的核心逻辑是自己手写的框架只是一个外层包装升级成本就低很多。第三个代价是“工程化错觉”。框架让你感觉系统很完整但很多关键工程细节——比如上下文管理策略、工具调用的超时和重试、成本控制——仍然需要你自己去设计。这些细节恰恰是Agent能不能稳定运行的关键。框架不会替你思考这些。指望框架解决一切的人最后往往会被框架的复杂抽象所累。4.3 我给新手和转行者的进阶顺序表说了这么多最后给一张可以对照执行的进阶表。它是我自己带过好几个零基础转行的朋友验证过比较顺畅的路径。阶段学习内容目标预计时间第一阶段熟练调用大模型API理解参数能写一个“输入用户问题→输出回答”的脚本搞懂token和上下文1周第二阶段手写一个工具调用循环实现文章里的Agent骨架至少接入2个工具处理JSON解析和错误回传1周第三阶段加入记忆和简单的任务拆解能做多步任务比如“查天气→提醒带伞”1周第四阶段主动看一个常见编排框架的核心概念这次可以装了用它重写第二阶段的Demo体会框架帮你省了什么1周第五阶段深入一个方向RAG、多Agent协作、或生产化部署做出一个自己真正想用的东西依个人而定这个顺序的核心思想是先徒手再上工具。徒手阶段能让你建立不可替代的直觉工具阶段能让你提高效率。如果你直接跳到第五阶段前四阶段欠下的“债”总有一天会以“莫名其妙跑不通”的方式找上门来。5. 新手与转行者最容易踩的5个坑5.1 高频问题速查表把项目里常见的坑整理成一个速查表方便你直接对照。问题典型表现排查思路与解决上下文爆炸消息列表越来越长越到后面响应越慢、越贵记录每轮消息数超过阈值后用摘要压缩旧消息只保留最近几轮完整记录JSON输出不稳定解析时报错模型偶尔输出解释文字温度降到0.1以下提示词里给严格样例解析失败时把错误消息回传给模型让它重试一次工具参数名不匹配Python报“unexpected keyword argument”给每个工具写清晰参数说明在提示词里列清参数名、类型和含义必要时让模型输出JSON后靠代码自动转换字段名循环不收敛模型反复执行同一工具结果原地踏步设置最大步数上限如果某一步的工具结果和上一步完全一样可以强制终止并输出当前结论成本失控一个简单任务调了几十次API限制max_tokens、限制最大步数开启流式但对用户展示结果的同时也行但内部要控制给所有调用加日志统计单次任务成本这里每一个问题我都遇到过不止一次。前三个问题在入门阶段极其普遍后两个则是在你开始做真实项目、要面向真实用户时一定会遇到的。建议把这张表存下来做到对应问题时回来对照。5.2 三个让我印象深刻的排查案例记忆里有一个案例特别典型。一个自己学Agent的开发者做了一个“自动整理邮箱并回复”的小工具。但是它总在某个固定步骤卡住当邮件内容比较长时模型的输出就不是纯JSON了而是前面多了一段“根据邮件内容我建议回复如下”。这段文字一加他的代码就解析失败整个流程中断。他当时的解决方法是不断加大模型输出的长度限制想让模型在足够长的地方再开始输出结果是白烧了钱。正确的做法是什么在提示词里用更强硬的约束再加上一个“解析失败自动重试一次并回传错误信息”的兜底逻辑。我帮他把这两处改掉以后问题再也没出现过。第二个案例是关于工具参数的。那位开发者做了一个“查快递”的工具模型经常把参数传成“快递单号SF123”而函数签名要求是单号字符串“SF123”。就因为提示词里没有说清楚“参数值只写单号不要带字段名”模型每次都在参数里多带几个字。这种案例不是模型傻而是你的接口协议定义得不够严格。解决方式很简单在工具描述里写“参数city为城市名称只写城市名本身例如北京”然后做一个参数预处理函数把常见干扰词剥掉。第三个案例是关于循环不收敛的。有一次我们做一个自动竞标分析模型反复调用同一工具查询同一条数据但每次都因为“再确认一下”继续循环。原因在于我们在提示词里告诉模型“为了确保准确可以多次查询”这类模糊表述。模型“积极”地执行了这个指令。后来我把提示词改成“只有在数据不足或存在冲突时才允许再次查询否则给出最终结论”循环次数骤降成本也明显降下来了。这事给我的教训是给模型的自由度要精准太多或太少都会出问题。5.3 转行者如何稳定推进学习节奏最后聊聊转行者最关心的“节奏”问题。见过太多转行学Agent的人一开始热情高涨学了几天就受挫原因不外乎两种一是目标定太大比如“我要做一个能自动化处理所有邮件的系统”结果第一次调试失败就泄气二是反复犹豫“我是不是还缺什么基础”迟迟不写代码。我的建议是把目标切成特别小的粒度。比如第一个目标不是做Agent而是“让Python程序成功调用一次模型API并打印结果”。第二个目标是“让模型根据我的问题输出一个表示动作的JSON”。第三个目标是“根据JSON去调用我写好的一个函数”。每完成一个小目标就给自己一个明确的反馈。这种进度感比任何学习计划都更管用。转行者还有一个优势。你之前在其他领域的经验——无论是业务逻辑、沟通协调还是问题拆解——在做Agent时非常值钱。因为Agent本质上是在把一套业务规则自动化你需要理解业务该怎么做才能告诉模型要做什么、工具要提供什么。我认识一些背景完全不是编程出身的开发者做起Agent来反而比纯技术的人更顺手因为他们更擅长“把任务讲清楚”。而“把任务讲清楚”恰恰是Agent开发中最稀缺的能力。说实话走到现在我自己回头看最值得庆幸的不是我熟练掌握哪个框架而是第一周就逼着自己把那个最朴素的循环跑通了。那个手写的十几行代码像一根定海神针让我后来不管换什么工具、看什么新框架都能一眼看出它到底在循环的哪个环节上做了增强。今天分享这套学习路径如果能让你少走哪怕一点弯路就值得了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑