不碰框架,手写迷你Agent:掌握核心循环后再学框架
1. 先搞清楚你学的到底是不是 Agent我见过太多人一上来就打开某个 Agent 框架的文档照着快速入门写一个“多智能体协作 Demo”跑通了就觉得自己入门了。然后遇到真实业务需求立刻傻眼——不知道怎么改、不知道怎么调、更不知道为什么有时候能用有时候不能用。问题出在哪出在把“会用框架”当成了“理解 Agent”。先给一个简单的定义Agent 是一个能自己决定“下一步做什么”的 AI 程序。它不是简单地把用户问题丢给大模型然后返回答案而是有一个循环大模型根据当前状态思考、决定调用什么工具、拿到工具结果后再思考、再决定下一步直到任务完成。这个循环才是 Agent 的灵魂。那些把大模型 API 封装一层、加上几个 predefined 的 Prompt 就叫做 Agent 的东西本质上还是单次问答。真正的 Agent 需要具备几个能力拆解任务的能力、选择工具的能力、记忆上下文的能力、以及从错误中恢复的能力。你如果没有亲手实现过一个这样的小循环直接上框架大概率会被框架里的抽象概念绕晕。什么 Planner、ReAct、Graph、State每个名词背后都是一堆设计决策你连基础模型都没有怎么可能判断这些设计合不合理所以我的第一个建议是别碰框架至少前两周别碰。2. 新手和转行者的真实起点先把地基打牢2.1 你需要什么基础比你想的少得多很多人以为学 Agent 需要深厚的算法功底其实不是。做 Agent 开发大部分时间花在写胶水代码上把大模型的输出解析成结构化指令调用外部工具处理各种格式异常。所以你需要的基础很明确Python 基础语法能写函数、类、异常处理能看懂装饰器最好但不会也不致命能看懂 JSON能熟练用 Python 的 json 库做解析和序列化会发 HTTP 请求知道 GET/POST 的区别知道 API Key 怎么放在 Header 里对大模型 API 的输入输出有个基本概念知道什么是 system prompt、user prompt知道 temperature 是干嘛的。这套组合其实就是一个普通后端开发者的日常技能。你不需要会训练模型不需要懂 Transformer 的数学原理不需要会 PyTorch。Agent 开发者的核心能力是“用工程手段把大模型的能力约束在可控范围内”这是工程问题不是算法问题。2.2 大模型 API 的调用逻辑比你想的简单我建议你做的第一个练习不是任何 Agent 框架而是用 Python 直接调用一个大模型的 API自己构造一个多轮对话。这个练习的目的是让你理解对话是怎么持续的。大多数人第一次调用 API 会犯一个习惯性错误每轮对话都重新发一条独立的请求然后把上一次的回复拼在新的 Prompt 里。这样短期能跑但很快你会发现 Context 越来越乱。正确做法是把整个对话历史当作一个 messages 数组传过去系统给你维护这个数组的状态。这一步理解到位了后面理解 Agent 的记忆机制就会轻松很多。import json from openai import OpenAI client OpenAI( api_key你的Key, base_urlhttps://你的服务地址 ) messages [ {role: system, content: 你是一个擅长处理客户反馈的助理回复要求简洁、可执行。}, {role: user, content: 客户说登录页打开很慢请帮我列出排查步骤。} ] response client.chat.completions.create( model你的模型名, messagesmessages, temperature0.3 ) print(response.choices[0].message.content)就这么简单。你不需要框架不需要封装先把这个跑通然后自己加一个循环让用户能在命令行里连续提问每次把历史 messages 传过去。这个命令行多轮对话程序是你 Agent 之路的第一个里程碑。2.3 Prompt 的底层思维把需求说清楚Prompt 太容易被低估了。很多新手把 Prompt 理解成“跟 AI 说话的艺术”其实在 Agent 开发里Prompt 是唯一的“需求文档”也是唯一的“代码注释”。你写的每条 Prompt 都在定义一个函数的行为边界。我常用的一个方法是写 Prompt 之前先问自己三个问题。第一这个 Agent 的角色边界是什么它能做什么、不能做什么要明确写出来。比如“你是订单查询助理只能查询订单状态不能回答任何与订单无关的问题”这比“你是一个有用的助手”要好得多。第二输出格式是什么如果后面要解析模型输出你一定得规定输出格式而且要规定得非常严格。我见过无数次因为模型输出了一句“好的根据您的查询结果是”导致 JSON 解析失败的情况后来学乖了Prompt 里直接写“只输出 JSON 对象不要输出任何解释性文字”解析成功率立刻飙升。第三模型需要用到哪些信息把需要的信息全部放进上下文里缺什么就告诉它“你可以调用某个工具获取”这样就带出了工具调用的概念。你先别急着学框架里的 Function Calling先把这三个问题想透再往 Prompt 里填充内容你的 Agent 就会比 80% 的框架 Demo 更可靠。3. 从零手写一个迷你 Agent比框架更容易上手3.1 明确目标做一个能查天气并给出出行建议的 Agent理论说再多不如直接写代码。我们做一个极简但五脏俱全的 Agent。它的任务是当用户问“今天适合出门吗”时Agent 能自己决定调用天气查询工具拿到天气数据后结合数据给出一句建议。这个项目需要的组件有一个工具函数查天气、一个让大模型决定是否调用工具的逻辑、一个执行工具的循环、以及最终的答案生成。你先别管框架怎么实现我们直接手写。3.2 工具定义与注册关键是参数的描述def get_weather(city: str, date: str 今天) - str: 根据城市名和日期返回天气情况仅供入门演示使用 # 真实场景这里会调用天气服务API mock_data { 北京: {今天: 晴25°C微风, 明天: 多云22°C}, 上海: {今天: 小雨18°C湿冷, 明天: 阴20°C}, } return mock_data.get(city, {}).get(date, 暂无该城市/日期数据)然后你做一个工具注册表把函数名、函数描述、参数 schema 存下来。这里有个关键点函数描述写得越清楚模型越容易在需要时选中它。很多人把描述写成“获取天气”模型经常不知道该在什么场景用写成“当用户询问天气、温度、降雨、出行条件时调用此工具查询指定城市当天的实时天气数据”模型的调用准确率会高很多。这一步就是框架里 Function Calling 的原型你把原理搞懂了框架里的 Function Calling 不过就是个更规范的注册表。3.3 核心循环思考、调用、再思考接下来是 Agent 的核心逻辑。流程是这样的把用户问题发给大模型同时把所有工具的定义发给它。大模型如果觉得需要查天气会返回一个结构化的“工具调用请求”你的代码解析这个请求执行对应函数把结果追加到对话历史中再一次发给大模型。第二次大模型看到了工具返回的数据就能生成最终回答。def run_agent(user_query: str): messages [ {role: system, content: 你是一个出行助手。如果需要天气信息请调用工具查询。查询结果返回后再结合数据生成回答。回答不超过两句话。}, {role: user, content: user_query} ] # 第一步让大模型决定是否调用工具 tools [get_weather] # 真实的 Function Calling 会用更规范的参数描述 resp call_model_with_tools(messages, tools) # 这里简化了实际按你所用平台规范组装 # 第二步如果模型返回了工具调用指令就执行 if resp.get(tool_call): tool_name resp[tool_call][name] args resp[tool_call][arguments] result globals()[tool_name](**args) messages.append({role: function, name: tool_name, content: result}) # 第三步把工具结果放回去让模型生成最终回答 final_resp call_model(messages) return final_resp # 模型认为不需要调用工具时直接返回 return resp我故意省略了具体 API 的细节因为不同平台组装 tools 参数的方式不一样核心思想是一样的。你真正要理解的是这个“循环”模型看到问题决定动作你执行动作把结果喂回去模型再决定下一步。所有 Agent 框架无非是把这个循环包装得更漂亮、更可扩展。你把这段代码调试通了你对 Agent 的理解就超过了只会调框架的水平。3.4 加一个反思步骤让 Agent 学会纠错基础循环跑通后我建议你立刻加一个“反思”步骤。做法很简单当工具调用返回的结果看起来不合理或者模型生成最终回答之前先让它评估一下自己的答案是否真的回应了用户问题。具体操作就是在工具执行完之后加一轮“评价”对话。messages.append({ role: user, content: 请检查你刚才基于工具数据生成的内容确认是否直接回答了用户的问题且没有编造数据。如果回答不合适请重新生成。 })这一招在真实项目中非常有效尤其是接入了多个数据源的 Agent。模型经常会出现“数据明明说下雨它却建议穿短袖”的情况加了反思步骤后错误率会明显下降。你把这个机制亲手做出来再去框架里看 Reflection 的抽象就会觉得“哦原来就是多一次提示”而不是看到一个名词就发怵。4. 从迷你实现到框架使用什么时候上框架4.1 你亲手做过一遍的原型就是最好的教学材料你会说我自己写的这个 Agent 也太简陋了上不了生产啊。对它上不了生产但它给了你一个参照系。现在你再打开任何一个 Agent 框架会发现它的核心概念你全都见过Tool工具注册、AgentState对话状态、Node处理步骤、Edge路由条件。你只是把自己手写的 switch-case 换成了框架里的图结构把 Python 字典换成了 Pydantic 模型把手动拼接 messages 换成了框架托管的消息总线。有了这个基础学习框架就变成了“看它怎么把你已经懂的东西工程化”而不是“学习一个全新的黑盒”。以我个人经验这个阶段一般需要两周到一个月。时间是看你每天能投入多久。如果你每天能写两三个小时代码基本上两周内就可以开始碰框架。前提是你真的把那个复杂的循环思想消化了而不是抄一遍代码就算完。4.2 框架选型的三个实际问题当你决定上框架时不要盲从排行榜先问自己三个问题。第一你的项目是偏简单的单 Agent 工具调用还是偏复杂的多角色协作如果只是单 Agent 几个工具框架反而可能是负担封装一大圈还不如自己写的循环直白。第二团队的维护能力如何框架是代码库的“外来人口”升级快、API 易变。你上框架之前得想清楚以后谁维护这部分。小人数团队在用框架前建议先写清楚版本固定方案别今天升级明天重构最后项目烂在自己手里。第三部署环境是什么有些框架天生依赖某些云服务本地私有化部署会很痛苦。你如果是在内网环境里搭 Agent务必先看框架是否支持纯本地组件别把核心流程绑定在无法离线调用的服务上。4.3 框架不是终点你需要的是一套评测体系上了框架后大多数人会遇到一个新问题Agent 的行为变得不确定。同一个问题今天回答得好好的明天换个模型版本就抽风。这时候如果你没有评测体系根本没法定位问题是出在 Prompt、工具、框架路由还是模型本身。我强烈建议你从第一天就维护一组建模为“测试用例”的评测集。不需要多复杂就是几十个典型的用户问题每个问题后面跟着期望的行为路径和最终答案的关键词。每次改动之后跑一遍看通过率变化。有了这个基线你改 Prompt、加工具、换模型心里都有数不会像无头苍蝇一样乱试。不要一上来就搞复杂的 Agent Benchmark 工具你只需要一个脚本自动把你的测试问题打给 Agent然后把结果和期望做对比输出一个通过率百分比。五十个问题级别就够了。这一个举动能让你的 Agent 项目从“写着玩”变成“可迭代的产品”。5. 常见问题与排查技巧实录5.1 大模型不按格式输出怎么办这是新手遇到最多的问题。你让它输出 JSON它偏要加一段解释文字。这里有两个方向。一是把 Prompt 写绝比如“只输出 JSON不要输出任何其他内容”二是解析兜底正则提取 JSON 片段再解析不行就重试一次。两个方向结合起来能解决 90% 的场景。另外可以试试把“少样本示例”放进 Prompt给一个输入输出的成对示例模型会模仿得更准。这比单纯命令式描述“你必须输出JSON”强得多。5.2 工具调用参数总是传错怎么办模型把城市名传错把日期格式传错这类问题很常见。你先把参数描述写得更细“北京”要允许“北京市”“帝都”等别名入库前统一处理“日期”则明确写成“格式 YYYY-MM-DD”。然后再加一道校验在函数入口处做格式规范化别信模型给的参数。说到底Agent 是概率系统你不能指望它 100% 正确而是要在代码层面做好容错。所有从模型输出中拿到的数据都要假设可能有错然后用代码逻辑去校验、纠偏、兜底。5.3 请求一直报超时是什么原因很多新手会把超时简单地归咎于“网络问题”。其实最常见的原因是 Agent 循环里串行调了太多次模型每一次都需要好几秒链条一长就超时。先看设计上能否减少模型调用次数再看能否把工具结果拼在一次 Prompt 里让模型一次性处理最后才考虑加异步处理或调大超时时间。5.4 模型幻觉工具没返回的信息它自己编工具拿到了天气数据是“小雨”但模型生成时还是硬说“晴朗”。这属于幻觉的典型表现。解决办法不是换更大的模型而是约束生成时的上下文。比较实用的做法是最终生成回答的 Prompt 里强调“只能依据下面工具返回的数据回答数据里没有提到的信息一律不要补充”同时在代码里增加一个校验步骤检查生成文本里是否出现了数据中不存在的高置信度关键词。大多数情况下这两招能把幻觉压到很低。6. 我的一些实操体会写了这么多最后分享一点非技术层面的心得。我觉得入行 Agent 开发最大的门槛不是代码而是心态。因为它和传统软件不一样——传统软件里你写完逻辑行为是确定的Agent 则永远带着不确定性。你没法用“单元测试全绿”来获得安全感只能靠评测基线、日志追踪、容错设计来稳住局面。心态上做好准备比学任何框架都重要。另一个体会是别把 Agent 想得太“智能”。它本质上是一个用大模型做决策引擎的自动化流程。你把流程设计清楚、异常处理做好大部分场景会稳定得让你惊讶你流程一团乱指望模型自己“悟”出来那基本是做梦。Agent 的边界能力确实在快速提升但对于大多数新手和转行者来说把基础循环、Prompt 设计、评测体系这三件事做好已经足够超过平均水平了。如果你正在学 Agent我的建议很简单别急着上框架先花两周时间亲手做一个小循环然后带着那个“亲手跑通的感觉”去学任何框架。磨刀不误砍柴工这个步骤省不掉。等你的小循环加上了反思、评测、容错这几层之后再回头看框架你会发现一切都是通的。