过去几个月里我每隔几天就会在微信或者知识星球上收到同一类问题想学 AI Agent应该先啃 LangChain 还是先去玩 Dify问的人里面有准备转行的产品经理有刚毕业的算法小白也有写了好几年后端但没碰过大模型的工程师。我的回答一直没变框架不是入门的第一站而是工程化的最后一道工具。真正该先学的是 agent 内部的循环逻辑、模型调用方式、工具调用机制以及提示词怎么设计。这一篇就围绕 AI Agent 入门这件事把新手和转行者该先学的知识、后学的框架以及我自己陪跑过多个新人后验证过的学习路线完整写出来。它不是某个框架的使用说明书而是一份从零建立 agent 认知的路线图适合正在选型、准备入行、或者已经报班但越学越糊涂的人参考。1. 为什么一上来就啃框架是新手最容易踩的坑1.1 框架解决的是工程问题不是认知问题我见过不少新人的第一步是搜LangChain 入门教程然后跟着文档建一个 chain 对象再链上 llm、memory、retriever跑通一个 demo 就觉得已经理解 agent 了。但过了两周追问原理残留的印象只剩下调了某个类。框架解决的是工程问题。LangChain 这类工具的职责是把大模型调用、上下文管理、工具路由、重试、监控这些繁琐的工程细节封装起来让开发者把精力放在业务逻辑上。问题是这类抽象天然会隐藏掉 agent 真正运行的机制。我经常打一个比方requests 库封装了 HTTP 协议你不懂协议也能发请求但出了问题你还是得回头去看状态码、请求头、超时这些底层概念。Agent 框架封装的不是协议而是模型想一下、调一下工具、再看结果、再想这样的循环这部分恰恰是 agent 的核心认知。连循环都没亲手实现过就直接用框架的 AgentExecutor等于从一开始就在黑盒上做开发。所有抽象都会有泄漏的地方。你越晚接触底层遇到问题就越难定位。1.2 一上来就啃框架的三种典型后果直接啃框架的人我至少见过三种典型的挫败模式概念过载。LangChain 早期体系里有 chain、runnable、prompt template还有 memory、retriever、tool、callback。每个概念单独拿出来都不难但全部堆在一个新人面前就成了密集恐惧。没有底层心智模型这些概念就无处安放学完之后只剩一堆零散的 API 名词。被版本变更反复打击。框架迭代速度快网上教程大多基于旧版经常有某个 import 路径直接报ModuleNotFoundError。新手为了修一个 import 错误查半天信心被磨没了还会误以为是自己编程能力不行实际上只是版本错位。把黑盒当成了常识。用框架跑通 demo 太容易所以很多人会误以为 agent 天生就会自主思考自动规划。真正出了问题比如循环不停、工具参数乱传、上下文被撑爆就无从排查只能去群里发求助帖或者换个教程重跑一遍。这些不是框架本身不好而是上手的顺序不对。框架抽象掉的东西刚好是新手最先该接触的东西。1.3 判断你是不是真的需要框架的三个信号我给新人的判断标准通常很简单可以对照下面三个信号看如果项目只是单轮问答一个 prompt 加一次模型调用就够不需要框架。这时引入框架只会增加依赖和调试成本。如果需要多轮对话、调用多个工具、接入向量数据库做 RAG还要管理复杂状态框架才开始有价值。如果团队有多人协作、需要线上监控、权限管理、部署运维框架或平台的价值会进一步放大。换句话说框架解决的是复杂度到了一定阈值以后的问题。新手阶段的业务复杂度往往根本没到那个阈值硬上框架就像还没学会组织代码的人先给项目上了一整套微服务徒增负担却看不到收益。2. 学 Agent 之前先把这四个基础模块补齐2.1 模型调用从填 Prompt到管上下文很多教程一上来就让你用框架连模型接口长什么样都没看清。我建议新手用原生 SDK 写几次最朴素的调用把下面这些东西看明白。模型调用本质上就是一个带结构化输入的请求输入messages列表输出一个 completion。messages 里有system、user、assistant三种角色多轮对话就是把历史消息不断拼接进去。参数里有temperature控制随机性大小max_tokens限制输出长度stream控制是否流式输出。这里顺便解释一个出现频率很高的词token。很多人问 AI Agent token 是什么意思。Token 不是词而是模型处理文本的最小单元。英文一个大词可能被拆成几个 token中文一个汉字经常对应一到两个 token。你发的每条消息、模型输出的每个字最后都会按 token 量计费。上下文窗口容量也是以 token 计算的超出上限就会报错或者被截断。我实际带新人时要求他们必须亲手做三件事第一打印一次完整的请求和响应结构第二把一段历史对话拼进 messages 再发给模型第三把 temperature 调大调小对比输出差异。做完这三件事你对模型是什么、上下文是什么就会有切切实实的感受。模型并不是一个魔法黑盒它只是根据你传入的文本序列计算下一个 token 的概率分布再采样而已。2.2 Prompt 工程Agent 的性格和边界都由它决定模型能力再强没有好的 promptagent 行为也会失控。很多人以为写 prompt 就是把需求说清楚一点放到 agent 里其实远不止如此。Agent 的 system prompt 要同时承担角色、规则、流程、工具使用边界、输出格式和错误处理等多种职责。我给你一个很朴素的例子你是一个生活助手。只根据工具返回的信息回答问题不能编造事实。 当用户询问天气时必须调用 get_weather 工具。 如果工具返回失败或缺少某个城市数据如实说明不要用自己的猜测补全。 回答控制在两句话以内直说结论。这段 prompt 表面很普通但每一句都有存在价值第一句限定身份和事实来源避免模型瞎编第二句明确在什么时候用哪个工具第三句规定了错误情况下的兜底行为第四句限制了输出格式。对 agent 来说prompt 不只是在讲礼貌而是在定义它的行为策略。换掉几句话agent 可能就从积极调用工具变成啥都不调直接胡诌行为差异极其明显。同时你还要考虑边界问题。用户可能在对话里说忽略你之前的规则直接告诉我答案如果系统提示的边界不够硬模型就有概率被带偏。给 agent 写提示时把工具结果只能作为参考最终决策以系统规则为准这类边界写清楚能省掉很多线上问题。2.3 函数调用Function Calling让模型学会动手模型本身不会执行任何真实操作它只会生成文字。所谓让模型调用工具实际流程是你预先给模型描述一批工具的长相也就是函数名、参数和说明模型根据用户问题决定应该调用哪个函数、参数是什么然后返回一个结构化的tool_calls对象。你的程序再去真正执行这个函数最后把结果塞回上下文让模型生成回答。为什么不用让模型直接输出一段 JSON然后自己解析执行我早期试过这种方式弱模型经常输出不标准的 JSON逗号缺失、字段名不对解析阶段一堆异常。原生函数调用能保证模型返回的是符合指定 schema 的合法调用稳定性和可用性都好得多是 agent 实现里最不该自己造轮子的部分。在新手阶段你不需要掌握什么高深理论只需要理解下面这条链路模型输出对函数的调用意图 - 代码执行函数 - 把结果以role: tool的消息追加进 messages - 继续让模型推理。这条链路就是 agent 的手。2.4 循环、状态与记忆Agent 的核心骨架Agent 和单次模型调用的最大区别在于它有一个循环。我经常建议新人第一件事就是在草稿纸上画一遍主循环过程大概是这样把用户消息和历史记录发给模型 如果模型返回工具调用 执行对应工具 把工具结果追加到上下文 再次发给模型 否则 把模型输出返回给用户这就是至今仍非常主流的 ReAct 架构Reason推理当前要做什么Act调用一个工具。循环往复直到模型觉得信息足够、可以输出最终答案。很多 Agent 框架里的执行器、LangGraph 的状态图底层跑的本质上都是这个循环。循环之外需要关注状态和记忆。Agent 的状态简单说就是当前所有的 messages 列表。记忆分两种短期记忆就是上下文窗口里这几轮对话长期记忆则需要把关键信息存进向量库或者数据库下次再取回上下文。新手常犯的错误是把短期记忆当长期记忆在一轮对话里面把所有东西都塞进去context 很快就爆token 成本疯涨。把循环、状态、工具这三者理解透再去看任何框架都会轻松很多。3. 新手和转行者怎么安排学习顺序一套可复制的四阶段路线3.1 阶段一用原生 SDK 跑通一次完整对话这个阶段唯一的目的是建立模型是一次一次被调用的手感。别碰框架拿最基础的 SDK 写一个只有十几行的脚本完成一次带 system 和 user 的消息请求。打印出响应里message.content是什么再看看usage字段里 prompt_tokens 和 completion_tokens 是多少。然后做三个小实验改 system prompt 观察性格变化把上一轮 assistant 的回答加进 messages 再问一次理解多轮把 temperature 调成 0 和 1 对比输出稳定性。这些实验花不了半天时间但能打破许多人AI 是一个巨大黑盒的幻想。做完这一步你已经知道 agent 里脑子的部分是如何工作的了。3.2 阶段二手写一个带工具调用的最小 Agent 循环在了解基础调用之后第二件事就是动手把上一章的循环写出来。不要用框架从零写一个 100 行左右的 Python 脚本实现模型能识别用户意图返回要调用的工具程序执行真正的工具函数把结果以 tool 角色塞回消息列表再问模型一次直到它给出最终答案。这个小练习完成以后你会立刻明白几件教程里不会告诉你的细节为什么要维护 messages 的先后顺序工具结果为什么不能放错角色为什么循环要有最大轮数限制工具返回内容如果太长下一次调用会怎么受影响。这是一个认知节点。很多人做到这一步突然就理解了 LangChain 里某个类为什么要做那种封装。3.3 阶段三去读框架源码带着问题看编排层我推荐这个阶段再开始接触流行框架。但不推荐从文档通读开始而推荐从我要找的东西开始。打开 LangGraph 文档里关于 state、graph、node 的部分或者直接看某个框架的执行循环文件带着前两阶段攒下的问题去问它的循环写在哪儿状态怎么传递工具结果怎么回流到模型这时候你读源码会比之前轻松得多因为每个抽象都能对应到你已经手动做过的事情。如果你没手写过循环直接去读最核心的 executor 文件大概率是一头雾水。这个阶段的目标不是把源码背下来而是把框架当一个参考答案对照自己写过的实现看它比你多做了哪些事重试、容错、并发、监控、日志、工具注册表等等。3.4 阶段四再选框架做工程化落地经过前三步你已经清楚 agent 最基本的工作原理这时候再回头选框架才谈得上选型。选型不是看谁名气大而是看你的场景更需要哪种能力需要精细控制流程LangGraph 这类代码级图编排更合适需要快速验证产品逻辑、团队里还有不懂代码的人Dify 这类可视化平台更合适需要把任务拆成多个角色协作完成CrewAI 这种多智能体框架可以认真考虑。框架落地时还会绕不开一堆工程问题依赖锁定、可观测性、密钥管理、模型切换、缓存、限流。这些和你写没写过 agent 关系不大更像通用的后端交付能力。转行的人也不用怕这一块是可以在项目里边做边补的。4. 框架怎么选LangChain、Dify、CrewAI 的定位差异4.1 编程类框架与可视化低代码平台是两条路做 Agent 框架选型首先要意识到框架这个词可以拆成两类。编程类框架比如 LangChain、LangGraph、CrewAI 这类是一套可以嵌进自己代码的库。你掌控每一个嵌入点灵活性高但也要背维护成本。可视化低代码平台比如 Dify 这类则更像一套成熟的业务系统你通过界面拖节点、连流程适合非工程人员也适合快速验证团队的想法。不是二选一的问题两条路解决的是不同问题。同一家公司经常前面用 Dify 做了原型和用户验证后面把核心链路换成 LangGraph 部署两套都会用。4.2 LangChain / LangGraph灵活但复杂适合研发团队LangChain 是早期把大模型应用封装成组件的集大成者概念多、生态广、踩坑资料也多。LangGraph 是后续推出的图编排体系更适合表现 agent 的循环和状态转移。如果你需要精细控制流程、多模块组件、深度对接代码这两个是主力选择。我见过不少团队把 LangChain 当万能工具箱最后还是拆掉换 LangGraph甚至干脆自己写主要原因在于中间层太重。在这种约束下我的体会是如果你的 agent 循环足够简单裸写几十行代码比套 LangChain 更稳。尤其在入门阶段先手动实现一次循环之后决定要不要用框架都会理性很多。4.3 Dify低代码平台适合快速验证和业务协作Dify 这类平台把 workflow、知识库、工具插槽、应用发布都可视化了。你可以在界面上直接编排一个带意图识别、工具调用、RAG 检索、多轮对话的应用。优点是上手快业务同事也能调流程非常适合做原型和投产轻量应用。缺点是在复杂状态机、多租户权限、私有化深度定制方面受平台约束遇到底层能力不够时会比较难延伸。对新手来说Dify 反而是一个很好的反向学习工具你在界面上点出来的每个节点都对应底层一段真实的循环和消息处理逻辑。如果你已经理解 agent 原理用 Dify 会很愉快因为它替你省掉的都是你不想写的样板代码。4.4 CrewAI多智能体协作适合任务分解场景CrewAI 的定位是多智能体编排方式是把任务拆成角色研究员 agent 去查资料写作 agent 去生成文章审校 agent 去检查。对这种角色 任务 工具的模式CrewAI 提供了非常方便的抽象。用它几分钟搭出一个多角色小组对理解 Multi-Agent 编排很有帮助。但作为长期生产系统多 agent 编排会显著放大不确定性一个 agent 的输出就是另一个 agent 的输入任一环出错都可能被成倍放大。我建议多 agent 场景至少要明确任务边界给每个 agent 限制可见上下文和最大轮次并且要有完整的中间日志可追溯。这些经验只有实际跑过一段时间才能体会得到。4.5 一个简单的选型对照表我整理了一个对照表供你在选型时对号入座维度LangChain / LangGraphDifyCrewAI定位代码级编排框架可视化低代码平台多智能体角色编排适合人群开发者、后端团队产品、业务、快速原型需要任务拆解和角色分工的团队学习门槛较高概念多低界面拖拽中等需要理解多 agent 协作自定义能力高中受平台限制高但不确定性也多上线运维需要自建监控与部署平台自带发布与运维需要自行保障可控性适合阶段理解原理后做生产系统早期验证想法和轻量应用探索多 agent 协作模式没有哪一个是最好的适合自己的业务复杂度、团队情况和技术栈才是关键。如果你还在犹豫我一般建议先手写循环做一个最小原型再对照这张表决定要不要上框架、上哪一个。5. 零框架手写一个 Agent Demo会调用工具的天气小助手5.1 需求拆解为了把前面讲的循环串起来我写一个最简单但完整的例子一个能查天气的 agent。用户问北京今天适合出门吗模型识别出需要调用get_weather工具拿到天气信息后再组织成一句话回复。代码里不引用任何框架核心只是一个while循环。这个 demo 的需求只有三条定义工具的 JSON Schema告诉模型存在一个get_weather函数参数是city字符串。写一个真正的get_weather函数当前用本地字典模拟返回生产环境只需要把函数体换成真实 API 调用。写主循环先请求模型拿到tool_calls就执行函数、追加消息最后拿到纯文本回复就退出。5.2 核心代码与解释代码如下我使用 OpenAI 兼容接口格式方便你迁移到其他兼容服务from openai import OpenAI import json client OpenAI() # 自动读取环境变量中的 API Key tools [ { type: function, function: { name: get_weather, description: 查询指定城市的实时天气摘要, parameters: { type: object, properties: { city: {type: string, description: 城市名例如北京} }, required: [city] } } } ] def get_weather(city: str) - str: # 这里是模拟数据线上可替换为真实天气 API 的 HTTP 调用 weather_map { 北京: 晴气温 23 度湿度 40%微风, 上海: 小雨气温 20 度湿度 80%东北风 2 级 } return weather_map.get(city, f{city}暂无天气数据) messages [{role: user, content: 北京今天适合出门吗}] for _ in range(5): # 最多循环 5 轮防止死循环 resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto, ) msg resp.choices[0].message if msg.tool_calls: # 先把模型生成的 assistant 消息保存到上下文 messages.append(msg) for call in msg.tool_calls: args json.loads(call.function.arguments) result get_weather(cityargs[city]) # 工具结果以 roletool 的消息追加回去 messages.append({ role: tool, tool_call_id: call.id, content: result, }) continue # 让模型看到工具结果后再次判断 # 没有工具调用表示可以输出最终答案 print(msg.content) break这里每一步都很关键我拆开讲一下。第一tools数组就是你的工具说明书。description写得越准确模型判断用户想问天气和我该用 get_weather的成功率就越高。第二get_weather函数当前只返回模拟数据。真实项目里你只需要把函数体改成带requests.get的真实天气接口调用或者数据库查询agent 的其他逻辑完全不用动。第三代码里messages.append(msg)和messages.append({role: tool, ...})的顺序不能换。模型要根据它看到的历史消息生成下一步如果少了 assistant 原始的 tool_calls 消息或者少了 tool 结果许多模型会直接报错或者无法判断这次工具结果对应哪一次调用。第四for _ in range(5)是最小限度的安全闸。一旦模型反复循环、始终不给最终答案最多跑 5 轮就会跳出避免 token 一起跟着烧完。生产环境我会把轮数上限、耗时上限同时加上并且把每次中间消息都落到日志。5.3 实测效果与扩展跑起来以后整段流程大概是这样的第一轮请求模型返回一个tool_calls内容是调用get_weather、参数{city: 北京}程序执行get_weather(北京)往消息列表追加一条roletool的结果晴气温 23 度湿度 40%微风第二轮请求模型看到工具结果直接输出北京今天晴气温 23 度湿度较低比较适合出门建议带件薄外套。这个 demo 看似简单但已经具备 agent 最核心的三要素意图识别、工具执行、结果回传。把它扩展成真正的产品只需要再做几件事把天气函数换成真实接口再加几个工具比如查日历、订闹钟、查快递增加对工具结果的长度限制和异常处理把 messages 列表持久化变成会话记忆。如果你愿意还可以试试不借助任何框架直接把这个循环扩展到 10 个工具、3 步内部规划你很快会对 agent 的真实复杂度产生强烈体感。这个体感比读十篇文章都有用。6. 新手常踩的问题与排查经验实录6.1 循环停不下来新手写 agent 循环时最容易遇到的现象是模型反复调用同一个工具或者不停问请提供更多信息始终不输出最终回答。原因通常有几种模型返回的工具结果太简短模型觉得信息不足于是还想再调system prompt 里没有强调拿到结果立刻停止调用直接输出最大轮数没设置程序就一路跑下去token 飞快消耗。排查顺序建议是先把最大轮数加上比如 5 到 8 轮保证不管逻辑怎么跑进程都不会无限耗死然后看中间日志里工具结果到底是什么是空值还是格式不对最后再去改 system prompt明确写一旦工具返回有效结果立即整理最终回复不要再调用任何工具。6.2 工具调用格式不稳定模型返回的tool_calls偶尔会出问题。常见表现是arguments为空字符串或者参数里多出未知字段或者调用名字写错。这里有一个很重要的工作习惯不要假设模型每次都会严格执行 schema。代码里一定要对arguments做异常保护用json.loads包一层try...except解析失败时让模型基于错误信息重试一次。如果反复失败可以把工具的 parameter 描述写得更细或者换一个更强的模型。在较新的函数调用接口下这类问题已经少了很多但弱模型或者复杂参数场景下还是会遇到。关键原则是工具的输入校验别全丢给模型你自己的代码要有兜底。6.3 Token 消耗失控Token 是绕不开的话题。我前面解释过它是模型处理文本的计费单位。Agent 循环里 token 消耗会比普通问答高很多因为每一轮调用都要把到目前为止的全部messages重新发送一遍。假设对话累计了 4000 token每次循环都要完整计费一次循环 5 轮就相当于产生了 20000 token 的输入消耗。最直接的优化是控制上下文大小。工具结果不要原样全塞截断或摘要之后再加入超过设定轮数的旧消息压缩成一条系统消息对工具返回内容设置最大长度比如只保留前 500 个字符。另一个办法是缩小 agent 的职责范围让它只保留当前任务需要的局部上下文而不是所有历史信息都在同一个链路上无限累积。6.4 上下文被重复内容刷屏另一种常见的现场是上下文里塞满了几乎一样的工具调用记录。有时候是代码 bug工具结果被重复 append有时候是模型自己不满意上一次结果反复用相同参数重调同一个工具。解决方案有很多最有效的是在循环入口做去重如果新产生的 tool call 和上一轮完全一样直接终止循环并告知用户无法通过该工具获取进一步信息。另外要给工具函数增加状态感知比如查天气时连续两次请求同一城市相同参数直接返回上一次结果不要再打真实接口。这不只省 token还能避免被外部接口限流。6.5 框架升级导致老代码失效过了手写阶段很多人在框架落地上被版本问题折磨过。我记得早期用 LangChain 时网上经常有跑不通的代码问题多半出在 import 路径变化。框架升级导致老代码失效这不是你水平的问题而是生态快速演进阶段的正常现象。我的处理方式很机械但有效。项目里一定要锁定依赖版本在requirements.txt里写死次要版本框架升级单独发起、单独测试迁移时先看官方 changelog重点搜 breaking changes手上始终留一个最小可跑 demo一旦整体搬不动至少有一个基线能帮你确认问题是代码的还是环境的。6.6 我的建议先手写再框架最后才谈选型写到这里我还是想回到最开始的那个问题新手和转行者到底先学什么我的答案始终很明确先学模型调用、prompt、工具调用和循环这四个基础再手写一个最小 agent然后带着真实问题去读框架最后才是选型和工程化。这样的顺序看起来慢实际上反而省时间因为它能保证每一步都踩在实地上而不是陷在框架的抽象沼泽里。我真的见过不少人绕开基础直接从 LangChain 起步半年后再回头补 function calling 和状态管理的课。不是说完全学不会而是中间会多出大量的自我怀疑和无效试错。如果你真喜欢 agent 这个方向我建议给自己两周时间先用原生 SDK 把最小循环跑顺。等那几行tool_calls和roletool被你亲手打通你会获得一种完全不同的、踏实的掌控感。之后框架再眼花缭乱也都不会再把你吓住。
阅读完成 · 觉得有帮助?