1. 为什么我不建议新手一上来就啃框架
AI Agent 这个词这两年快被说烂了。只要打开技术社区,满屏都是 LangChain、Dify、CrewAI、AutoGen,好像不会几个 Agent 框架就不配叫 AI 开发者。但我想先泼一盆冷水:越是新手和转行者,越别急着接触框架。
市面上这些 Agent 框架,本质上是在帮你封装底层逻辑。它们提供了现成的记忆管理、工具调用、多智能体协作机制,表面上省事,实际对初学者来说是个巨大的黑洞。你花三天时间学会了 LangChain 里各种 Chain 的写法,跟着官方文档把例子跑通了,但问你几个底层问题,大概率答不上来:LLM 调用为什么是流式的、一个 Agent 的 ReAct 循环是怎么一点点抠出最终答案的、工具返回的结果是靠什么规则被 Agent 理解并继续行动的。
这些框架的文档写得天花乱坠,每个都宣称自己是 "下一代应用范式"。但文档永远只为“已经懂的人”服务,它默认你理解大模型对话的基本原理,默认你知道 Token 和上下文的真实含义,默认你分得清 Prompt 里哪些内容是给模型说、哪些是留给代码判断的。对新手来说,这种默认就是一道无形的门槛。
我的建议很简单:先花时间去补"不依赖任何框架"的底层能力,用最朴素的 HTTP 请求调一次大模型接口,用几十行代码自己写一个简单 ReAct 循环。等你亲手把一个 Agent 从零搭起来,再回头看那些框架,你会发现框架每天更新的版本、层出不穷的新概念,全都变得无比亲切。那时候你才能判断一个框架到底是解决了真问题,还是单纯在制造新问题。
这个观点不是我拍脑袋想的。结合我身边做 Agent 应用落地的人聊下来的经验,真正能在实际业务里稳定跑起来的 Agent,背后往往是简单的结构加上仔细的工程控制。框架负责锦上添花,但锦怎么织出来,靠的是基本功。所以这篇文章,我就从“新手和转行者入门 AI Agent 到底先学什么”这个角度出发,把学习路径拆开讲清楚,全文用的是我自己的实操体会,不搞框架崇拜,也不堆华丽词汇。
2. AI Agent 入门先学什么:五个必补的基本功
2.1 先搞懂 LLM 调用的最小闭环
很多人口口声声说在做 Agent,但问他“大模型接口返回的 message 里,content 字段和 tool_calls 字段分别是干嘛用的”,他就卡壳了。这不行。
你必须先用最原始的方式理解:LLM 本身是“无状态的文本映射器”。你给一段输入,它给你一段输出。没有网络搜索,没有记忆,没有自动的工具选择。所有 Agent 的天花板能力,都是外层代码一层层叠上去的。
最基本的调用闭环是这样的:
from openai import OpenAI client = OpenAI(api_key="your-key", base_url="https://your-endpoint") resp = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": "你是一个有用的助手。"}, {"role": "user", "content": "请用一句话解释什么是函数调用。"} ] ) print(resp.choices[0].message.content)这段代码里没有什么高深的东西,就一条 HTTP 请求。你自己能用 Python 的 requests 库对着接口文档手写一遍,才真正理解 API 的请求体、鉴权方式、response 结构。这一遍下来,后面学什么框架都不虚。
实操体会:建议每个人都用 fetch 或 requests 裸调一次接口,然后打印 response 的完整 JSON。你会发现里面有个 usage 字段,里面是 prompt_tokens 和 completion_tokens。看明白这个,才能理解为什么上下文一长费用就飙,也才算对“Token 是一个计量单位”这句话有了体感。
2.2 Prompt 工程:Agent 的灵魂不在模型,在指令系统
Agent 和普通聊天应用的最大区别,是多了一层“行为约束”。让模型扮演一个自动化的角色、按指定流程处理问题,本质是靠 Prompt 在控制。很多人迷信模型能力,总觉得换个大模型效果自然提升,实际上 80% 的效果差距出在 Prompt 写得对不对。
以我调 Agent 的经验,好的 Prompt 至少具备三个要素:角色定义、任务拆解、输出格式约束。
角色定义告诉模型“你是谁、你服务的对象是谁、你有哪些边界”;任务拆解把工作分成几步,让模型按顺序推理;输出格式约束则把返回结果圈进 JSON 或固定结构的文本中,方便程序解析。
给你一个我常用的模板:
你是[角色名],服务于[目标用户]。 你的核心任务是[任务描述]。 请严格按以下步骤执行: 第一步:[动作1] 第二步:[动作2] 第三步:[动作3] 所有输出必须以 JSON 格式给出,字段包括:status, result, reason。 如果信息不足,请输出 status 为 "need_more_info",并在 reason 中说明缺少什么。这个模板看起来简单,但实际工作里救了我很多次。以前写 Agent 输出自由文本,下游程序解析起来全是坑。强制 JSON 格式后,下游逻辑瞬间清爽。记住一个原则:Prompt 是给模型看的代码,它也需要版本管理、逻辑清晰、可测试。
2.3 ReAct 模式:Agent 思考与行动的循环机制
AI Agent 底层最经典的思想,是 ReAct(Reasoning and Acting)。通俗点说,就是让模型一边思考“下一步该干什么”,一边决定“是不是要调用某个工具”,然后根据工具返回结果继续思考,直到得出答案。
网上资料喜欢画流程图,我这里用文字描述一下真实运行过程:
- 用户问:“帮我查一下北京的天气,然后告诉我适不适合户外跑步。”
- 模型第一轮输出:Thought(我想我需要查天气)→ Action(调用工具 get_weather)→ Action Input({"city": "北京"})。
- Agent 代码解析出这一串内容,执行 get_weather 函数,获得返回“北京,晴,22度,微风”。
- 模型第二轮输入里,除了原来的用户问题,还要加上刚拿到的工具结果。模型再次输出:Thought(天气很好)→ Final Answer(适合户外跑步,建议穿薄外套)。
- Agent 看到 Final Answer 就把这段文字返回给用户。
这个模式的核心在于:每一次调用大模型,都要把“之前的全部对话 + 工具返回结果”塞回 messages 里,模型才知道下一步怎么做。这就是 Agent 的“上下文闭环”。
不要被各种框架的封装吓唬住,框架无非是把这套循环打包了而已。你只要自己手写过一次 ReAct 循环,再去看 LangChain 的 AgentExecutor、OpenAI 的 function calling,就会觉得豁然开朗。
2.4 工具调用的设计思维:Agent 的能力边界由工具决定
Agent 自己不能上网、不能读数据库、不能操作软件,这些能力全靠“工具”给它开外挂。你可以把一个工具理解为“一个带描述的函数”。
大模型要正确选择并调用工具,靠的是函数的描述声明,所以工具描述写得越清楚,调用成功率越高。这就是“工具的描述是你的第二套 Prompt”。
举一个反面例子。你写一个 send_email 工具,描述写“给用户发邮件”。模型看到这个描述,根本不知道它需要哪些参数、适合什么场景。改进后:
{ "name": "send_email", "description": "向指定邮箱发送邮件。当用户要求主动联系某人、发送通知或回复邮件时使用。需要提供收件人地址、主题与正文。", "parameters": { "type": "object", "properties": { "to": {"type": "string", "description": "收件人邮箱地址"}, "subject": {"type": "string", "description": "邮件主题"}, "body": {"type": "string", "description": "邮件正文"} }, "required": ["to", "subject", "body"] } }描述里包含了触发条件、参数含义、示例场景。模型一看就知道该不该调用、怎么调用、参数填什么。
工具设计上有两个个人经验:
- 每个工具只做一件事,拆细不贪大。一个工具既要查天气又要查空气质量,覆盖面变宽,描述就会模糊,模型反而拿不准。
- 工具数量不是越多越好。初期控制在 5 个以内,模型的选择准确率最高。到 20 个以上,GPT 级别的模型也会开始出现选择漂移。
2.5 记忆机制:上下文窗口和持久化存储的边界
Agent 对话一长就会“失忆”,这是几乎所有新手都会撞上的墙。根源在于大模型上下文窗口有限,且默认不会保存任何历史。
最基础的记忆方案是用列表把所有历史消息存进内存,每次请求全部带给模型。但这样撑不了几轮,Token 一多既贵又慢。工程上常用的策略有:
- 滑动窗口:只保留最近 N 轮对话;
- 摘要压缩:把前面聊过的内容定期让模型提炼成摘要,替换掉原始长文本;
- 持久化存储:把关键信息写进数据库,在需要时按条件检索注入。
稳妥的组合拳是:短期记忆用滑动窗口,长期记忆落库,每次构建 messages 时往系统 Prompt 里插入与该用户相关的检索结果。这一套思路在框架里被封装成了各种 Memory 类,但理解了本质,你用 Redis、SQLite 也能实现,而且更可控。
3. LangChain、Dify、CrewAI 等框架到底怎么选
3.1 先分清框架的定位层级
新手最容易犯的第二个错,是把所有带“框架”两个字的工具混为一谈。实际上 Agent 框架大致分三层:
| 层级 | 代表 | 定位 |
|---|---|---|
| 底层编排库 | LangChain、LlamaIndex | 面向开发者,提供流程编排、工具调用、记忆封装 |
| 低代码平台 | Dify、Coze | 面向业务或快速验证,拖拽配置流程 |
| 多智能体协作框架 | CrewAI、AutoGen | 面向多角色协同任务,定义角色后让它们互相对话分工 |
这三层解决的问题不一样。LangChain 适合写代码的人深度定制,Dify 适合先跑通产品流程,CrewAI 则是你要做“多个 AI 角色配合完成复杂任务”时才派得上用场。
我的忠告是:入门阶段一个都不要急着上。先用裸代码做两个小项目,再挑一个最贴近你业务场景的框架去学。我见过太多人学 LangChain 学了一个月,最后发现产品用 Dify 反而更快,白白浪费了时间。
3.2 一个场景一个选择:教你按需匹配框架
判断标准非常简单,看你是在做“内部工具”还是“外部产品”。
- 如果你要接入公司的业务系统,需要大量私有化定制、精细控制 Prompt 与调用链,选 LangChain 这类库级方案更合适。它是库,不是平台,你可以随意嵌入代码。
- 如果你要快速做业务验证、做演示 Demo,或者团队里没有全职开发者,Dify 这类平台是真香。几分钟就能搭出一个带知识库和工具调用的 Agent。
- 如果你的任务天然是多角色协作的,比如让一个“调研员”Agent 去搜资料、一个“分析师”Agent 去写报告、一个“审核员”Agent 去改错,CrewAI 的设计更贴近。
有一个细节容易被忽略:CrewAI 底层依赖不少模型调用,多个 Agent 之间来回通信,Token 消耗翻倍。很多新人兴奋地搭好流程,一算费用直接傻眼。多智能体不是越高大上越好,能用单 Agent 完成的任务,不要为了复杂度去拆成多 Agent。
3.3 既然避不开框架,什么时候开始碰
前面说了那么多“别急着学框架”,但我也说一个明确的时间点:当你能做到以下三件事中任意一件,就可以正大光明地打开框架文档了:
- 能不带框架地写出一个能调用外部天气 API 并给出出行建议的 Agent;
- 能说清楚 ReAct 循环每一步发生时程序的调用栈长什么样;
- 能在完全没有帮助的情况下,为你的 Agent 增加一个自定义工具。
满足不了的,说明基础还没打牢,老老实实回去补基本功。框架能用,但不能替代你建立心智模型。
4. 零基础搭建你的第一个 Agent:完整实操流程
4.1 需求定义与架构拆解
这一步是很多新手最容易跳过的,但它是最值钱的一步。我们先定一个具体的、可验证的小项目:做一个“会议纪要助手”。它能接收一段会议文本,提取待办事项、负责人和截止时间,并按格式输出。
拆解下来,它需要两部分:一部分是 Prompt 把原始文本整理成结构化 JSON,另一部分是后端逻辑把 JSON 按固定模板渲染成 Markdown 报告。里面不需要外部工具,所以理论上不依赖任何框架,用最基础的大模型 API 就能完成。
设计时的关键决策是“模型只负责信息抽取和整理,不负责排版”。排版这类确定性工作交给代码完成,避免模型输出不稳定、格式时好时坏。
4.2 手写代码实现 ReAct 循环和小工具
我先用最简单的方式实现一个 ReAct 循环骨架,然后在此基础上加一个查询工具,让它具备“能行动”的能力。下面是核心代码:
import json import requests from openai import OpenAI client = OpenAI(api_key="your-key", base_url="https://your-endpoint") def get_weather(city: str) -> str: url = f"https://api.example.com/weather?city={city}" resp = requests.get(url) return resp.json().get("weather", "未知") TOOLS = { "get_weather": { "description": "查询指定城市当前天气", "call": get_weather } } SYSTEM_PROMPT = """ 你是一个会使用工具的助手。当需要查询天气时,按以下格式输出: Thought: 你的思考 Action: get_weather Action Input: {"city": "城市名"} 当获得工具结果后,继续思考,最终回答时使用: Thought: 你的结论 Final Answer: 对用户的最终答复 """ def run_agent(user_input: str, max_steps: int = 5): messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_input} ] for _ in range(max_steps): resp = client.chat.completions.create( model="gpt-4o-mini", messages=messages ) content = resp.choices[0].message.content print("模型输出:", content) if "Final Answer" in content: return content.split("Final Answer:")[-1].strip() # 简单解析工具调用 if "Action:" in content and "Action Input:" in content: action_name = content.split("Action:")[1].split("\n")[0].strip() action_input = content.split("Action Input:")[1].strip() try: action_input_dict = json.loads(action_input) except: action_input_dict = {} if action_name in TOOLS: result = TOOLS[action_name]["call"](**action_input_dict) messages.append({"role": "assistant", "content": content}) messages.append({"role": "tool", "content": str(result)}) continue messages.append({"role": "assistant", "content": content}) return "已达到最大步骤数" print(run_agent("北京今天能出门跑步吗?"))这套代码虽然简陋,但 ReAct 的精髓全在里面。解析工具名、执行函数、把结果塞回 messages、继续产模型输出,这就是 Agent 的核心引擎。
4.3 让输出结果可控的进阶手段:结构化输出
上面的代码里,文本解析依赖“Action:”这类关键词,模型输出稍微不规范就断链。现实工程中,我会更倾向于让模型直接返回 JSON,然后用 pydantic 做校验。
from pydantic import BaseModel class AgentStep(BaseModel): thought: str action: str = "" action_input: dict = {} final_answer: str = "" SYSTEM_PROMPT_JSON = """ 你是会议纪要助手。请阅读用户输入的会议内容,提取待办事项。输出必须是 JSON,格式如下: { "todos": [ {"task": "任务描述", "owner": "负责人", "due_date": "截止日期"} ] } 不允许输出 JSON 以外的任何文字。 """用结构化输出把模型限制住,后面的一切处理都变得异常舒适。这也是我给所有新人的建议:大模型的输出越结构化,程序就越稳定。自由文本是 Agent 的敌人,约束格式是 Agent 的朋友。
4.4 现场记录:跑通这个小 Agent 的过程与坑
我实际跑上面代码的时候,遇到过三个非常典型的问题,这里如实记录一下。
第一次跑,模型把 Action Input 的 JSON 里用了单引号,json.loads 直接崩溃。这是我预料之中的坑,所以我在解析前加了异常处理。后来我干脆在 Prompt 里强制要求“Action Input 必须是合法 JSON,key 必须用双引号”,崩溃率明显下降。
第二次跑,模型在同一个问题上来回调用同一个工具,形成了死循环。原因是我没有在循环里判断“如果 Action 是刚才调用过的同一个,就换一种方式输出”。加了最大步数和重复检测后,才彻底解决。
第三次是 Token 问题。我把每轮模型输出都塞回 messages,工作区一长,请求体膨胀,响应速度肉眼可见地变慢。后来我只保留最近的 4 轮上下文,再把之前的内容压缩成一句摘要,速度又回来了。
这三个坑,几乎每个 Agent 项目都会遇到。新手要是直接上手框架,遇到同样的问题根本不知道该去哪里排查,因为框架把细节都藏起来了。
5. Agent 开发中常见问题速查与排查技巧
作为一个踩过不少坑的人,我把新手问得最多的问题列了个清单,方便你直接对照排查。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 模型一直调用同一个工具,不结束 | 缺少停止条件与工具去重判断 | 设置最大步骤数;检测到重复工具调用时强制让模型总结回答 |
| 输出格式时而 JSON 时而文本 | Prompt 约束不严格 | 在系统 Prompt 中强调“只输出 JSON”;用结构化输出 API 代替纯文本 |
| Agent 多轮后越发越慢 | 上下文无限制膨胀 | 引入滑动窗口或摘要压缩,控制每轮 messages 条数 |
| 工具调用参数报错 | 工具描述里的参数示例与函数签名不一致 | 让工具描述与函数参数一一对账,并写单元测试覆盖 |
| 模型乱选工具 | 工具数量多且描述含糊 | 精简工具数量;重写描述,加入“什么时候该用/不该用” |
| 回答带有用户不该看到的内部过程 | 调试信息混进了最终返回值 | 前后端彻底分离,Agent 中间过程只写日志,最终用户只收 final_answer |
排错基操我一般按三步走:第一步,把 messages 完整打印出来,看模型到底收到了什么;第二步,检查工具函数返回的数据格式有没有变化,是不是塞了 None 或者空数组;第三步,把相同的输入丢到 Playground 里手动试,看是不是历史上下文干扰了模型判断。
很多时候问题不在代码,而在“模型当前能看到的上下文”。一个被遗忘的工具调用残留信息,可能直接带偏模型下一轮的决策。所以日志里开通“完整 messages 链路的 dump 开关”,是你排查 Agent 问题最锐利的武器。
另外我还想分享一个独家习惯:每次给 Agent 升级 Prompt 后,我都会准备一组固定的测试用例,自动跑一遍,看结构化输出和 Final Answer 的成功率。这些测试用例是基线,任何一次 Prompt 修改,先过基线,再上线。没有基线的 Prompt 改动基本就是盲人摸象。
6. 罗列一下入门学习路线与分阶段清单
前段时间有位读者问我:“你说了半天别学框架,那总得有个路线图吧。” 我干脆把路线压缩成了三阶段清单,按照这个节奏走,新手大概 4 到 8 周能完成基本认知到实战的过渡。
| 阶段 | 学习重点 | 产出物 | 是否需要框架 |
|---|---|---|---|
| 第一阶段(第 1 周) | HTTP 调用大模型接口;理解 API 结构;写一个最简单的问答脚本 | 一个命令行对话机器人 | 完全不需要 |
| 第二阶段(第 2-3 周) | ReAct 循环;工具函数设计;理解上下文与记忆 | 一个能查天气/查任务的单工具 Agent | 完全不需要 |
| 第三阶段(第 4-6 周) | 结构化输出;多工具管理;错误处理与日志 | 一个可用于实际场景的垂直 Agent | 可选,若项目复杂度上升可引入 |
| 第四阶段(第 7-8 周) | 对比学习一个主流框架;读其源码中关于记忆和工具调用的部分 | 用框架重写第三阶段的项目 | 是 |
个人建议第一阶段尽量压到最短,别恋战。API 调用本身没多少知识量,快速过一遍就够了。第二、三阶段是真正的体力活和心智积累,值得反复练习。
一个很关键的心态是:学 Agent 不是学“某个软件的说明书”,而是学“一套组合思想”。你最终的自由度不取决于你会用哪个框架,而取决于你能不能用最小成本拼出自己的流程。我见过用五个 Python 文件加一个 Redis 实现稳定生产级 Agent 的团队,也见过用 LangChain 跑 Demo 都经常出错的团队。前者把基本功打在投标上,后者把复杂度堆在玩具上。
7. 选对模型与部署思路:AI Agent 踩坑避雷指南
7.1 模型能力的分工原则
很多人做 Agent 的时候,把所有智能都押在一个模型上。实际工程里更合理的思路是“按任务难度分模型”。
简单分类任务,比如意图识别、关键词抽取,用小模型又快又便宜;复杂推理任务,比如多步规划、长文生成,用大模型保证准确率;代码生成任务,则可以用专门优化过的代码模型。这个“模型路由”思想,能让你的 Agent 成本下降 50% 以上,效果反而更稳。
我实际测过的组合方案是:意图识别用一个小参数模型,对话生成用中档模型,复杂工具编排才调用旗舰模型。四条链路各司其职,Token 费用和响应延迟都控制得相当好。
7.2 本地部署与云端 API 的取舍
新手常被“开源模型的部署成本”劝退,其实要分情况看待。纯做学习和验证,直接用云端 API 是效率最高的选择。但如果你的业务涉及敏感数据、需要低延迟离线运行,本地部署开源模型就绕不开。
本地部署需要关注的指标包括显存占用、推理速度、量化格式。以 7B 级别的模型为例,用 4bit 量化大约需要 6GB 显存,普通家用的消费级显卡就可以跑起来,速度尚可。如果要做高吞吐服务,还得考虑 GPU 集群和推理框架优化,这部分工作量和成本都不小。
我的建议是:小项目先在云端跑通逻辑,确认 PMF(产品市场匹配)之后再谈本地化部署。开头就纠结部署细节,多半是在错误的地方浪费精力。AI Agent 的核心价值是“解决问题的能力”,不是“跑在谁的服务器上”。
8. 从入门到能接业务:一个真实的转行者经验复盘
我个人是从传统后端开发转到 AI 应用方向的,当时最大的恐慌也是“框架学不过来”。现在回头想,真正帮我打通任督二脉的不是框架文档,而是自己在纸上一遍遍画 ReAct 循环的图、手动模拟工具调用的一来一回。
那段时间我做了四个小项目:命令行天气助手、会议纪要结构化整理、微信群自动消息汇总、还有一个小型 RAG 客服问答机器人。其中每个项目都没有用现成的 Agent 框架,全部基于 OpenAI SDK 加 requests 手写。日记账本上大概记了两万字的心得,也积攒了大量“参数调整的直觉”。这些直觉在后来看 LangChain 源码、甚至自己写轻量内部框架的时候,发挥了决定性作用。
有一位我认识的转行产品经理,用了完全相反的路径:她先考完一堆框架认证,开口闭口都是“我这个 Agent 用了 LangChain 加 Chroma”,但面试官让她现场设计一个“自动订餐 Agent”的工具调用流程,她画了一个小时也画不利索。后来她花了三周老老实实补基础概念,再回头看那些框架教程,发现有 80% 的内容她之前根本没看懂、只是记住了名词。
这两个例子没有谁更聪明,差别只是学习顺序。框架是“已知正确答案的总结”,但如果你连问题本身都看不懂,看答案也没有意义。
9. 推荐阅读材料与下一步探索方向
既然你不该只盯框架,那应该看什么?我给你列一个精简过的清单:
- 概念类:OpenAI 官方文档中关于 Function Calling、Structured Outputs、Agents 的说明,这是最权威的基础;
- 论文类:ReAct 原论文是必读的,篇幅不长,但读完能理解 Agent 的思想源头;
- 源码阅读:挑一个你感兴趣的框架,不要从头看到尾,只读其 agent 执行循环、tool registry、memory 三个模块;
- 实践类:Kaggle、GitHub 上有大量 “minimal agent” 项目,找那种几百行代码以内的小项目,直接读源码比看几千字的教程高效得多。
进阶方向上,如果你已经能驾驭单 Agent,下一步可以考虑多 Agent 协作、复杂工作流编排和主动学习型 Agent。这些方向都建立在你对底层理解足够深的前提下,否则只会陷入框架的术语海洋。
我个人后续打算做的内容方向是:把一套“轻量内部 Agent 框架”的演进过程完整记录下来,包括从零手写的 v0.1 版本、到逐步抽出工具注册表、记忆模块、重试机制、再到接入更稳定模型的过程。这既是对我自己的工程复盘,也是一个给新手看“框架从哪来”的活教材。如果你对这个方向感兴趣,可以顺着这个思路自己先做一版,遇到的问题越多,进步越快。