AI Agent入门这个话题,我前前后后带过不少实习生和转行过来的同事,发现大家几乎踩同一个坑:上来不管三七二十一,先搜“AI Agent框架对比”,然后在langchain、dify、crewai之间反复横跳,折腾了两三周,最后连一个最简单的工具调用demo都没跑通。今天我想直接跟你说点实在的:新手和转行者入门AI Agent,第一课不是框架,而是把基础能力补上来之后再碰框架。这篇内容适合完全零基础的小白,也适合后端、前端、测试转AI方向的同学参考。我会把Agent最核心的那点东西拆开揉碎讲清楚,并且给你一条可以直接照着学的基础路线,文章里给出的代码也可以直接抄去当训练项目用。
1. 先搞明白一件事:Agent和框架是两码事
1.1 别被热词带偏了节奏
很多人理解错了“AI Agent”这个词。它不是一个工具、不是一个软件,而是一种程序范式。所谓Agent,本质上是让大模型在一个循环里自主决策:它分析你给的目标,决定下一步调用什么工具,看到工具返回的结果以后再决定下一步做什么,直到任务完成。
而框架是什么?框架是别人提前把这一套循环逻辑封装好、打包好的代码库。LangChain、Dify、CrewAI都干这件事,只是封装的程度、设计理念不一样。
打个比方:Agent是你想做的菜,框架是半成品料理包。你连火候、调味、刀工都没练过,上来先研究哪个料理包的供应链更完善、哪个包装盒更漂亮,这不是本末倒置么?你真正该做的是先把锅铲拿起来,从最基础的东西练起。
1.2 入门之前先认清Agent的三件套
不管业界怎么吹“多智能体”“自主规划”“记忆增强”,Agent跑起来其实就是这三样东西:
- 大脑(LLM):负责理解、规划、判断。没有大模型,Agent就是一堆死代码。
- 手(Tools):大模型不能直接查天气、订票、读写数据库,你需要给它挂上工具,它通过函数调用去操作外部世界。
- 循环(Loop):思考-行动-观察,不断重复,直到得到一个满意的结果。
剩下什么规划、记忆、反思、多Agent协作,都是在这三件套之上叠加的增强手段。你如果一开始就钻进框架源码里,很容易被各种抽象类、回调器、链式调用搞晕,根本不知道该看哪里。反过来,把上面三件套吃透,再去看任何框架,你都能一眼认出“哦,这不就是一个循环外面包了一层封装”。
1.3 我总结的入门路线:先基础,再原理,后框架
带过的人多了,我划线划得很清楚。新手和转行者入门AI Agent,按下面这个顺序走就对了:
- 打基础:Python编程、异步处理、数据模型、调用大模型API。
- 理解原理:把Chat Completions消息结构、Function Calling、ReAct循环搞明白。
- 做最小实现:不依赖任何框架,自己手写一个能调用工具的Agent,跑通一个完整任务。
- 再碰框架:当你发现手写代码开始重复、要处理工程化问题的时候,再去看LangChain、Dify这些。
这个顺序不是我拍脑袋定的。我见过太多人跳过前两步,直接卡在第四步。他们的问题非常类似:丢一个Token进去,不知道为什么会爆;模型不按预期调用工具,不知道参数哪里写错了;配了一个Agent套娃,出bug以后完全没法调试。这些问题的根子都在基础层。
2. 啃框架之前,先把这三项基础夯实
2.1 Python基本功:至少要能写异步和Pydantic
很多转行者说“我会Python”,实际上只会print("hello")和for i in range(10)。做Agent开发,Python水平要求没那么玄乎,但下面几个点你必须能用起来:
- 类型注解:函数签名写清楚参数和返回值的类型。你会发现自己写代码的时候思路会清晰很多,而且Pydantic全靠它。
- 异步编程(async/await):Agent经常要并发调用多个工具、同时请求多个大模型接口,不会
asyncio后面会非常痛苦。 - Pydantic数据模型:现在主流框架的数据校验底层基本都是Pydantic。你会觉得它有点像写类型定义,但又能做校验,非常实用。
我建议你花一周时间,把FastAPI官方文档里的教程过一遍。学完了以后你再看Agent框架,会觉得好多概念特别眼熟,道理都是一通百通的。
2.2 消息结构和Function Calling:Agent的核心命脉
Agent的底层工作对象是“消息”,不是你脑子里的自然语言对话。你去看所有大模型API,发送的内容基本都是一组消息列表,每条消息有角色和内容:
system:系统提示词,设定模型的身份和行为准则user:用户输入assistant:模型的回复tool:工具执行完以后返回的结果
你会注意到,真正的Agent工作流里,这几种角色会反复交替出现。模型输出一段“需要调用工具”的指令,你执行完工具,把结果以tool角色塞回去,模型再接着回答。这个机制,就是Function Calling(函数调用)。
Function Calling的原理我可以一句话讲明白:你预先定义一批工具,每一个工具都用JSON Schema格式来描述它接受什么参数。模型看到你的问题以后,不直接执行工具,它只负责“决定该调用哪个工具、参数应该填什么”,返回给你一个结构化的工具调用指令。真正的执行,还是由你的代码去做的。
很多新手不理解这件事:为什么不让模型直接执行工具?因为模型本身没有“执行代码”的能力,它只能输出文本。同时,让代码来控制执行过程才是最安全、最可控的。理解了这一点,你就理解了一半Agent。
2.3 提示词能力:能不能控住模型
Agent的稳定性,很大程度上取决于提示词。新人觉得提示词就是“你好,请你帮我做某事”,差远了。你至少要学会这几件事:
- 定义角色和边界:告诉模型它是什么、应该做什么、不应该做什么。
- 给定输出格式约束:有时候你需要模型输出JSON,那就明确把JSON格式写进系统提示,甚至给一个示例。
- 使用Few-shot:给一两个输入输出的示例,模型理解你意图的成功率会高非常多。
- 善用CoT(思维链):让模型“先分析,再判断,最后给结论”,而不是直接一股脑输出。你会发现输出质量明显提升。
我见过一个特别典型的情况:新手写Agent,提示词就一句话“帮我查询今天的天气”,然后抱怨“模型不调用工具”。你稍微改一改提示词,跟它说“你先根据用户的问题,判断是否需要调用get_weather工具;需要的话,直接输出json格式的工具调用”,效果立竿见影。这就是提示词能力带来的差距。
2.4 记忆的三种实现,别上来就想着向量数据库
“Agent要拥有记忆”这句话把很多人带偏了。有人一上来就要接Redis、上向量数据库、装Milvus,结果基础模型还没跑通。
记忆在Agent里其实分三个层次:
- 短期记忆:在当前一轮对话的上下文里保留完整对话历史,直接拼进消息列表就行。
- 长期记忆:把关键信息存到外部存储,下次对话再取回来,拼进系统提示或上下文。
- 工作记忆:Agent在执行任务过程中临时记录的一些中间结果,通常放在变量里或额外的上下文字段里。
刚入门,先做好短期记忆就够了。等你把简单的上下文拼接做熟了,再考虑引入向量检索做长期记忆,否则你会被“检索效果差”“相关度不高”“存储结构设计不合理”这些问题折磨到崩溃。
3. 从零手写一个Agent:源码级拆解
3.1 定义工具:JSON Schema其实不复杂
第一步是给大模型准备一份“工具说明书”。下面这段代码,我定义了一个查询天气的工具:
import json import os from openai import OpenAI client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), base_url=os.environ.get("OPENAI_BASE_URL") ) def get_weather(city: str) -> str: """真实环境下这里应该去调用天气服务API, 这里为了演示,直接返回固定字符串""" return f"{city} 今天多云,最高气温 28℃,适合出行。" tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的实时天气情况", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,比如 北京" } }, "required": ["city"] } } } ]这段代码一点花哨的东西都没有,但它把Agent工具机制的核心全讲透了:工具的名字要清晰,描述要写清楚什么情况用什么工具,参数要定义好类型和必填项。模型会依据这个JSON结构来决定怎么调用你的工具。
3.2 主循环:理解ReAct的思考-行动-观察
写主循环是整个Agent实现里最重要的环节。我讲课时经常画一个循环图,其实逻辑很简单:
- 把当前消息列表发给大模型。
- 检查模型的回复。
- 如果模型要求调用工具,就执行工具,把工具结果以
tool角色追加到消息列表,然后回到第1步。 - 如果模型给出最终回复,直接把内容返回给用户,循环结束。
代码实现如下:
def execute_tool(name: str, args_json: str): args = json.loads(args_json) if name == "get_weather": return get_weather(args["city"]) return "未找到该工具" def run_agent(user_input: str, messages: list) -> str: messages.append({"role": "user", "content": user_input}) for step in range(6): # 设置最大步数,防止死循环 resp = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, tool_choice="auto", ) msg = resp.choices[0].message if msg.tool_calls: # 模型要求调用工具 messages.append(msg) for tc in msg.tool_calls: tool_result = execute_tool(tc.function.name, tc.function.arguments) messages.append({ "role": "tool", "tool_call_id": tc.id, "content": tool_result }) else: # 模型给出最终回答 messages.append(msg) return msg.content return "达到最大步数,任务尚未完成,请重试"这个循环里有一个特别容易忽视的细节:tc.function.arguments是一个写JSON字符串,你在真实项目里一定要做异常捕获,防止模型给出来的参数格式不合法。我在生产环境里遇到过一次模型把字符串参数里塞了换行符带上奇怪的引号,导致json.loads直接抛异常,整个Agent就挂了。
3.3 让Agent记住对话:别把历史一股脑全塞进去
上面的messages列表就是短期记忆。你可以把它保存到数据库里,下次用户再来的时候查出来接着拼,Agent看起来就“记住”了之前说过什么。
但是这里有个坑:消息列表不能无限增长。模型上下文窗口有限,资金也不是无限的。你所有历史消息全塞进去,到后面既费钱又容易超出窗口报错。
我处理这个问题的原始办法比较实用:只保留最近几轮对话,或者把早期内容做一层摘要,用摘要代替长历史。你可以先做第一种,简单粗暴,等后面有需要再优化摘要策略。这个思路同样适用于你现在直接上手任何框架的时候,因为框架只是把“手动拼消息”变成“自动拼消息”,底层成本逻辑一点没变。
3.4 补一个真实的调用示例
把上面代码串起来,你可以这么跑:
messages = [] result = run_agent("帮我看看北京今天怎么样", messages) print(result)模型会先回复一个工具调用指令,代码执行get_weather,把结果塞回消息,模型再基于天气结果生成最终回复。你可能会看到类似这样的输出:
北京今天多云,最高气温 28℃,适合出行。建议你穿一件薄外套,中午活动注意防晒。整个链路就闭环了。你亲手把这个闭环跑通以后,再去学任何Agent框架,都会有一种“这背后的东西我已经懂了”的感觉,学习效率完全不是一个量级。
3.5 手写Agent过程中,我被问得最多的三个问题
新手在做最小实现的时候经常遇到一些奇怪问题,这里我挑三个高频的集中说一说:
第一个,模型怎么也不调用工具,怎么办?先检查你的工具描述是否清晰,再检查提示词里有没有明确告诉模型“你可以调用工具完成用户需求”,最后把temperature调低一点,我一般调到0.2左右,可以降低随机性。
第二个,agent陷入死循环怎么解决?加最大步数限制,跟我上面的代码一样。另外,在工具的返回内容里加入“如果这个结果已经是最终结论,请直接输出”,也能有效避免模型傻乎乎地一直原地重复。
第三个,工具返回结果太长导致上下文爆掉。工具该报异常就报异常,该截断就截断,不要无脑把几千几万字原样塞回消息列表。你给模型的信息越多,它反而越容易抓不住重点。
4. 什么时候可以碰框架?选型与心态
4.1 我建议你先问自己三个问题
在你打开LangChain文档之前,先用手写Agent跑通上面那个示例。然后问自己三个问题:
- 我是不是已经在重复写同一个主循环和消息拼接代码?
- 我是不是需要一个RAG流程、内存存储、多Agent协作这些更复杂的机制?
- 我是不是需要快速做一个产品Demo,给老板或客户演示?
如果答案是“是”,恭喜你,现在可以去看框架了。如果三个都是“否”,你想学框架纯粹是因为“大家都在学”,那我还是建议你把基础再磨一磨。
4.2 LangChain、Dify、CrewAI怎么选
我简单讲一下这三个主流框架的差异,方便你按自己的场景去选:
- LangChain:偏代码层的编排库,适合开发者。它提供大量链、工具、记忆组件,灵活度高,但抽象层次比较多,新手上手成本相对大。
- Dify:偏产品化和工作流,适合快速搭建应用,有可视化界面。你不太擅长写代码也可以拖拽出Agent应用,但要深入定制的时候,反而不如LangChain自由。
- CrewAI:主打多Agent角色协作,特别适合做“几个Agent分工配合”的场景。如果你要做任务拆解、角色扮演类Agent,这个框架会省不少事。
我的选型建议是:先按场景选,再看团队熟悉度。如果你只是自己练手,可以先把这三者各跑一个最小的Agent Demo,精力不需要花太多,重点看哪个最贴合你未来的项目场景。
4.3 从框架源码里学设计,才是高层次的学习
很多人用框架只停留在“照着文档抄”,出问题了不会排查。我想给你一个不一样的角度:当你已经会手写Agent以后,看框架源码是最佳的学习路径。
拿LangChain来说,它里面有一个AgentExecutor类,你扒开源码会发现,核心逻辑仍然是我的主循环里那个套路:调用模型、判断工具、执行、返回。框架做的事情是帮你把这些步骤抽象成了可配置的对象,让你能做一些更灵活的处理,比如错误重试、调用次数限制、工具超时等。
这就好像你练毛笔字,先自己一笔一划写熟了,再去临摹名家的字帖,收获很大。如果一开始就直接描摹,你根本不知道哪些笔力扎实、哪些结构巧妙。源码阅读同理,它是你理解和鉴赏框架的最好方式。
5. 新手和转行者最容易踩的坑
5.1 五个高频问题速查
我整理了一张表,是我在实际带人和做项目时反复遇到的问题,你可以直接收藏当备查:
| 现象 | 常见原因 | 排查方向 |
|---|---|---|
| 模型不调用工具 | 工具描述不清晰、参数Schema有误 | 先跑一个最小工具,确认Schema格式;再检查系统提示词 |
| Token莫名其妙暴涨 | 历史消息无限制拼接、工具返回过长 | 做历史截断、摘要;限制工具返回内容长度 |
| Agent进入死循环 | 缺少最大步数、模型没有终止条件 | 加步数限制,在提示词中写清“没有新信息时直接回答” |
| 工具执行失败 | 参数解析失败、工具异常未捕获 | 对json.loads做异常处理;给工具外层加try/except |
| 输出结果不理想 | temperature过高、提示词约束不够 | 调低temperature到0.2左右;在系统提示里加入输出格式约束 |
5.2 排查技巧先怀疑你的提示词,再怀疑工具
我见过太多人一遇到Agent表现不对,第一反应是“框架有问题”“模型有问题”“库版本不对”。实际上,绝大多数问题的根源都在提示词和工具调用逻辑上。
我的排查顺序是这样的:
- 先把
temperature调低。 - 手动把一条对话历史打印出来,逐条看消息角色和内容是不是对的。
- 检查模型到底有没有收到工具定义。很多人把tools参数忘了传,或者在代码里拼错了字段名。
- 最后再怀疑框架和环境。
你可能会发现,80%的bug都是这几个原因,根本不用去翻框架源码。
5.3 给转行者的一句实在话
转做AI Agent方向,最大的优势其实是你的跨界背景。做后端的,系统性思维强,适合搞Agent工程架构;做前端的,交互体验敏感,适合做Agent产品和界面;做测试的,对异常情况敏感,特别适合做Agent的质量保障和调试。
别一上来就觉得“必须成为Prompt大师”“必须把所有框架都学会”。我带了这么多人,真正决定你能不能在Agent方向走下去的,反而是一次次debug之后积累起来的体感。你会逐渐知道模型什么时候会乱来、JSON参数为什么容易被解析错、上下文为什么会失控,这些东西,不是你背多少框架文档能替代的。
最后再分享一个小技巧:你应该自己维护一个“踩坑笔记本”,把每次遇到Agent异常、模型表现不符合预期的案例都记下来,旁边标注原因和解决方案。你自己整理的这套经验,比任何别人的笔记都有效。这也是我到现在为止,遇到Agent问题最快定位、最快解决的核心方法。