首页 / 资讯中心 / 文章详情

AI Agent入门路线:先用原生代码手写一个,再学框架

AI Agent入门路线:先用原生代码手写一个,再学框架 ★ FEATURED ARTICLE
说实话这两年我见过太多新手和转行者冲进来学 AI Agent第一步就是打开某几个热门编排框架的文档装了一堆依赖照着教程跑通一个 demo然后发个朋友圈就完事了。再过两天问他原理基本答不上来项目也改不动版本一升级就全崩。问题不出在不努力而是顺序反了。我自己的体会是AI Agent 本质上是“大模型 工具 记忆 决策循环”的组合框架只是把这几个东西打包好、加了一层调度逻辑而已。新手真正该做的是先搞懂模型调用、提示词、结构化输出和工具设计然后用原生代码手写一个极简 Agent让它在自己手里跑起来之后再回头看框架你一眼就能看穿它到底做了什么。这篇文章就给打算入门、以及从传统开发转行做 Agent 的朋友画一条路线。不讲玄学不推框架只讲第一性原理和能落地的实操你按这个顺序学至少能省两个月弯路的钱。1. 先想清楚AI Agent 到底是什么1.1 一句话本质大模型驱动的决策循环很多人把 Agent 想得很玄其实拆到最底层它就是一个循环接收用户目标 → 大模型思考下一步 → 调用一个工具/给出回答 → 把结果带回来 → 再思考 → 循环直到任务完成这个循环里有四个核心零件缺一个都不成立大模型负责理解意图、拆解任务、决定下一步动作。它是“大脑”但它自己不会执行只会输出文字。工具模型能指挥的外部能力比如查数据库、发请求、算数、搜索、操作文件。这是 Agent 能做事而不是只会聊天的关键。记忆上下文窗口是有限的Agent 需要把历史对话、工具结果、长期知识保存下来在合适的时机塞回给模型。这部分最容易被新手忽略也最容易翻车。循环控制什么时候继续什么时候停出错怎么恢复怎么防止同一个工具被反复调用这是判断一个 Agent 工程质量的分水岭。你看这四个零件没有一个是某个框架专属的。你完全可以用标准代码把它们拼起来。1.2 为什么别一上来就啃框架我先说个扎心的事实框架抽象掉了大量细节而这些细节恰恰是新手最该练的基本功。拿常见的编排框架来说它给你封装好了 Agent、Tool、Memory、Retriever、Plan 这些概念你写几行配置就能跑。但代价是什么是出了问题你不知道去哪查。模型返回了一个奇怪的 JSON你不知道是框架解析的锅还是模型输出的锅。工具一直重试你不知道是框架的重试策略还是你自己业务代码的 bug。想把长上下文做个截断你得先翻半天框架源码看它有没有隐藏逻辑。我打个比方这就好比学做菜正常人肯定先学切菜、备料、开火、调味你直接去五星酒店后厨跟行政总厨学“如何管理一个后厨团队”学是能学到东西但你连颠勺都不会学完也做不出一桌菜。框架是给已经懂原理的人用的。它帮你省的是重复劳动不是帮你省学习。所以新手入门第一步不是打开框架文档而是把一个 Agent 能跑起来的最小闭环用最原始的 API 调用自己亲手搭出来。1.3 建议的学习路线总览我给自己带的新手团队定的路线固定是四层任何人我都拦着不让跳级大模型调用层搞懂 API 怎么调、输入输出长什么样、参数怎么控制。结构化输出层搞懂怎么让模型稳定输出 JSON、工具调用指令怎么处理失败。工具与服务层搞懂怎么设计一个能被模型可靠调用的工具怎么接外部系统。状态与循环层搞懂记忆怎么管、循环怎么控制、Agent 怎么评估。四层全部用原生代码过一遍快的话一周半慢的话三周。之后再去学框架你会发现它的每个概念你都能对上号看源码就像看自己写的代码再也不会被一堆抽象概念绕晕。2. 入门第一课把大模型调用玩熟2.1 跑通一次 API 调用比你想象的更有价值很多人觉得“不就是调个 API 吗”但作为数学和编程基础相对薄弱的转行者这一步千万别跳过。你需要亲手在代码里完成一次完整的对话补全并且理解三个关键东西。第一消息格式。最常见的格式是一个数组里面有 system、user、assistant 三种角色。system 负责定规则user 是用户输入assistant 是模型自己的历史回复。多轮对话就是把这个数组不断追加进去。初学者最容易犯的错是新的一轮只传当前用户问题导致模型“失忆”。第二几个核心参数。temperature 控制随机性一般写代码、做工具调用设低一点比如 0.1 到 0.3闲聊可以设高一点。max_tokens 控制回复长度很多人忽略它结果模型回复到一半被截断JSON 解析直接失败。top_p 现在用得少了保持默认也行。第三上下文窗口。模型一次能看到的 token 数是有限的你的历史消息越多留给新问题和新工具结果的空间就越少。后面讲到记忆时你会反复遇到这个问题但你在第一次调 API 时就该有这个意识。我建议你写一个小脚本用任意一门熟练语言发一条请求打印出完整响应。然后故意调高 temperature 到 1.5观察回复变得多么离谱故意把 max_tokens 设成 10观察回复怎么被截断。这比看任何教程都印象深刻。2.2 手写一个最小的 ReAct 循环ReAct 是 Reasoning Acting 的缩写意思是模型一边推理一边行动也是最朴素的一种 Agent 模式。下面是核心伪代码不依赖任何框架function run_agent(goal): messages [{role: system, content: system_prompt}, {role: user, content: goal}] for step in range(max_steps): reply call_llm(messages) messages.append({role: assistant, content: reply}) if reply contains FINAL_ANSWER: return extract_answer(reply) else: tool_name, tool_input parse_action(reply) result call_tool(tool_name, tool_input) messages.append({role: system, content: 工具返回: result}) return timeout_error你可以看到Agent 的核心就是一个循环循环里只发生了三件事把历史交给模型、解析模型输出、执行工具并把结果回填。框架里的 Agent 执行器翻来覆去做的就是这件事。我建议你把这段伪代码真正跑通加一个最小工具比如“计算两个数之和”或者“查当前时间”。你会发现一个很现实的问题模型可能不按你说的格式输出行动指令可能输出一段散文而不是 “TOOL_NAME: xxx, INPUT: yyy”。从这一步起你就开始体会 Agent 工程师日常的痛了。2.3 提示词是新手的第一套“隐形框架”很多转行的人以为框架是配置出来的其实是“提示词 代码”对出来的。你的第一套框架应该是能在提示词里把任务边界写清楚。我常用的 system prompt 结构是四段式角色你是谁专长是什么在什么场景下工作。目标你现在要完成的任务是什么成功标准是什么。约束哪些事情绝对不能做哪些情况必须请求工具回复格式是什么。示例给一两个输入输出的例子尤其是“工具调用格式”的例子。这里有一条经验示例要贴近真实场景不要用“用户问天气”这种通用例子。你让模型调用订单查询工具就给它一个带订单号、平台、时间字段的真实 JSON 例子模型大概率会照着你的格式输出比你在提示词里写一百遍“你必须输出 JSON”管用得多。另外务必要给模型“思考的空间”。比如你直接问“这个用户的订单状态是什么”模型可能猜但如果你提示它“先检查是否有订单号没有就问用户要”它就会按你的流程走。这就是思维链最简单的用法不需要什么复杂技巧先把推理步骤写进提示词里就能明显提升准确性。3. 转行者最缺的一块工具调用与结构化输出3.1 Function Calling 到底是怎么一回事很多从传统后端转过来的朋友对 Function Calling 天生产生误解以为“模型在执行我的函数”其实不是。模型只是一个文本生成器它生成的是“调用意图”真正执行的是你的代码。举个具体场景。你有一个函数 query_user(name)Function Calling 的过程是这样你事先给模型一份“工具说明书”说明有哪些函数、每个函数接受哪些参数、参数的含义和格式。当用户说“帮我查一下张三的信息”模型看懂了意图就输出一个结构化的指令你可以理解为调用函数 query_user参数 name 张三。你的代码收到这个指令自己执行 query_user拿到结果把结果作为一条新消息发给模型。模型再根据结果组织回答。关键点在于函数的执行结果模型本来不知道模型只知道“我已经请求调用某个函数了”结果是你喂给它的。所以工具返回结果的格式非常重要最好整理成简洁、结构化的文本不要一股脑把一个超大的 JSON 原样塞回去。好的工具结果可以这样设计查询成功。 用户: 张三 账户状态: 正常 当前余额: 1280.50 元 最近一笔交易: 2024-11-03 充值 500 元差的工具结果是把整个数据库行、几十个字段、嵌套对象直接丢给模型。模型确实能读但会浪费大量 token而且容易在无关字段上产生幻觉得不偿失。3.2 不靠框架自己实现一个工具路由自己写工具路由其实很考验工程能力正好适合转行者练手。我推荐的做法是“注册表模式”。先定义一个统一接口所有工具都返回同一个结构。然后你维护一张注册表注册表里记录工具的元信息包括函数名、描述、参数 schema、真实处理函数。最后写一个分发器根据模型输出的工具名去注册表里查找到就执行找不到就返回错误。我贴一个简化版本用伪代码解释这个模式tools {} def register_tool(name, description, params_schema, handler): tools[name] {description: description, schema: params_schema, handler: handler} def dispatch(tool_name, arguments): tool tools.get(tool_name) if not tool: return 错误: 未知工具 tool_name try: result tool[handler](**arguments) return 成功: format_result(result) except Exception as e: return 失败: str(e) # 注册一个工具 register_tool(get_user_info, 根据用户名查询用户账户信息, {user_name: string, 必填}, query_user_db)这个模式的优点有三个新工具接入只加一个注册项不用改主干代码工具列表可以动态生成随时能拼到提示词里告诉模型有哪些可用工具出了错能根据工具名快速定位。这套思路等你以后看框架源码你会发现很多框架底层就是这么做的只是它用装饰器和配置帮你省了注册这一步。3.3 工具层最容易踩的坑这部分是我带团队时整理出的高频问题新手基本都会踩一遍先列出来给你打个预防针。第一参数校验千万别省。模型输出的参数是它“猜”的可能出现字段缺失、格式不对、value 超出枚举范围甚至直接输出 null。你的 handler 里必须做严格校验不要假设模型一定按 schema 来。很多项目工具调用半天不成功最终一查就是参数里混进去一个空格。第二超时和重试必须有。工具可能调用一个远程服务如果这个服务 10 秒没响应你的 Agent 会一直卡在循环里。我的做法是每个工具调用设置一个超时时间超出就返回一个明确错误“工具执行超时请换一个方式查询”让模型自己去决定是重试还是换策略。第三工具返回结果必须加长度上限。模型上下文是有限的一个工具返回了 10000 个 token整个 Agent 直接撑爆后面什么事情都做不了。我的习惯是在工具里做摘要、截断、只返回关键字段。返回前先把数据压缩一遍别偷懒。第四权限边界不能全交给模型。根据模型判断“要不要调用有副作用的工具”是不可靠的比如发邮件、删文件、转账这类操作一定要在代码里设置二次确认或者用只读/可写两套模式区分。这不是技术问题是安全意识问题。4. 核心难点状态、记忆与循环控制4.1 记忆分层短期、长期、工作记忆新手往往会问模型不是能记住上下文吗为什么还要自己做记忆原因前面说过上下文窗口有上限而且每轮对话全部重发token 成本会高得离谱。所以你要自己设计记忆体系。我把 Agent 的记忆粗分成三层工作记忆当前任务用到的关键信息比如临时变量、上一步工具结果任务结束就清空。实现上就是放一个 dict。短期记忆最近几轮的对话摘要用来保持多轮任务的连续性。常见做法是滑动窗口截断只保留最近 N 条或者用模型把早期对话压缩成摘要。长期记忆跨会话保存的用户偏好、历史结论、领域知识。一般存到向量数据库里按需检索出来塞进提示词。我建议入门阶段先别碰向量数据库用一个简单的滑动窗口就够。关键代码逻辑是当消息总长度超过阈值时把最早的消息删掉或者把最旧的一段对话用模型摘要成一行字然后继续。等你的任务真正需要跨会话记忆时再引入向量检索不迟。4.2 循环控制与终止条件防止 Agent 越跑越偏没有终止条件的 Agent 就是定时炸弹。我见过一个 demo 因为没有最大轮次限制模型反复调用同一个垃圾工具一分钟内花掉了几十块钱的 token。所以无论你手写还是用框架下面四个终止条件都必须有最大轮次限制一般任务 5 到 10 轮内应该解决超过即终止。目标任务完成条件如果你知道完成的标准比如“日期已经拿到且用户没有其他要求”就主动终止。重复工具检测同一个工具、同样的参数连续被调两次以上基本可以判定模型在打转直接中断。用户取消永远留一个入口让模型或前端能停止循环。我甚至建议你在日志里给每个循环打个编号标记第几步、用什么工具、结果摘要。一旦 Agent 出了问题你能像回放录像一样看它每一步干了什么。这套日志习惯比任何框架功能都重要。4.3 怎么评估一个 Agent 做得好不好这是入门的人很少想、但实际工作一定会遇到的问题。你不能只说“感觉它变聪明了”要有可量化的指标。我自己的评估棋盘是这样的我先准备一小组测试任务比如 30 条人工标好期望结果。然后跑 Agent记录三个数任务完成率也就是成功完成的比例工具调用准确率也就是整个任务中模型选择的工具和参数是否合理平均耗时和平均 token 成本。每次改提示词、改工具格式就重新跑一遍这组测试对比看数值涨跌。这不是什么高深的评测体系但它是你做后续一切优化的基准。没有这个基准你会陷入“改一下试试好像好一点又好像差一点”的死循环。我强调一句这句话同样适用于以后你学框架、换模型、调参先定基线再谈优化。5. 再决定要不要学框架什么时候上框架才合理5.1 框架到底帮你解决了什么我不是反对框架恰恰相反我把这套逻辑彻底跑通之后很多日常项目我也会用框架。但我是带着“我已经知道它底层在干什么”的心态去用的。框架最大的价值在于几个方面。第一省掉样板代码比如消息组装、工具注册、重试策略这些重复劳动框架替你做了。第二提供标准的接口约定尤其是 Tool 的输入输出抽象多团队协作时特别有用。第三内置很多通用模块比如记忆、检索、人机交互的 callback不用自己从零造轮子。这些对你以后的工程效率提升确实很大。你可以把它理解成“一个经验丰富的项目经理”已经把需求对齐、排期、风险和异常处理都帮你打了个模板。但前提是你自己得知道项目逻辑否则模板反而是枷锁。5.2 框架的坑版本迭代快、概念多、黑盒我还是要给你泼点冷水框架本身有三个问题。版本迭代快到离谱。很多热门框架每周发新版本API 说改就改。你上周照着文档写的代码这周可能就报一堆废弃警告。对新手来说网上搜到的教程和当前版本不匹配会让你陷入无尽的排查中。概念抽象层太厚。Agent、Task、Chain、Memory、Retriever 这些概念层层嵌套。你以为你在配置业务逻辑其实你被框架的“世界观”绑架了。遇到问题你根本不知道是配置写错了还是框架的 bug只能去翻源码花的时间比自己手写还长。社区教程两极分化。要么是简单到没有营养的 hello world要么是直接给你一个巨型项目模板新手根本拆不动。学习体验相当差。所以我的结论是在你亲手写过一遍原生 Agent 之前不建议把框架作为学习主线。等你能用 100 行代码跑通一个带工具调用的 Agent再学框架你会感觉非常轻松甚至想吐槽它“怎么多了一层没必要的东西”。5.3 我建议的看框架姿势对照源码而不是照抄教程我自己学框架的方法是这样不追求学会框架的全部功能只挑我手写代码里已经实现的那些模块去源码里找对应部分。比如我已经手写了一个工具注册表那我就去框架源码里搜 “register” 或者 “tool” 关键词看它怎么设计的、有没有处理我没想到的边界情况。我已经写了滑动窗口记忆就去源码里找它的 memory 模块对比一下它的截断策略和我的有什么不同。这种“带着问题看源码”的方式效率大约是看教程的十倍。因为你已经有了实践基础源码里的每一个抽象你都能映射到具体问题上而不是被符号和类名牵着鼻子走。看完之后你很可能有两种收获一种是发现框架比我写得漂亮吸收它的设计另一种是发现框架某个地方其实不如你的实现灵活你以后就知道什么时候不该用它。6. 新手入门必踩的坑与排查思路实录6.1 五个高频问题速查表我把自己带新人过程中最高频的五个问题整理成了一张速查表你收藏起来遇到对着看。问题现象可能原因排查与解决模型不按格式输出工具调用提示词里没给示例或示例与当前场景差异太大在 system prompt 里加一个与真实任务一致的 few-shot 示例同一个工具被反复调用工具返回结果不清晰模型不知道下一步该干嘛把工具结果结构化末尾明确给出“结果已获取还需要给用户组织回答”这类指引上下文一长模型开始瞎答滑动窗口或摘要策略没生效检查消息数组长度强制做截断或在每轮工具调用后删掉历史工具原始结果工具调用成功但 Agent 仍报错参数里混入不可见字符或格式不符在 handler 入口打日志把原始 arguments 完整打印出来肉眼检查成本暴涨任务没完成多少轮就超额最大轮次设置过大或每轮重发大量历史消息设置合理的 max_steps压缩历史消息先跑一个任务估算单次成本这张表里几乎每个问题我都踩过一遍尤其是“同一个工具被反复调用”刚开始手写 ReAct 循环的人遇到概率接近百分之百。你记住一个原则模型不是不听话是你给它的反馈信息不够清楚工具结果里没有告诉它“任务已完成”。6.2 排查 Agent 问题的基础方法论排查 Agent 和排查普通代码最大的区别是普通代码是确定性的Agent 是不确定性的同一句话跑两次结果可能不一样。所以你没法用“打断点、跑单测”那套思路直接套。我的方法论就三条全程日志、回放复现、最小样本。全程日志指的是我要求每个环节都打日志。模型原始输出打一份解析后的工具调用打一份工具真实返回打一份。三条日志对齐基本就能定位问题出在模型、解析还是工具。回放复现指的是把出问题的对话原封不动地保存下来下一次跑测试时直接输入同一段历史。这样你可以反复改提示词、改工具围绕一个固定的样例去验证效果而不是靠随机撞。最小样本指的是别拿一个 50 条任务的复杂测试集去调问题。先把出问题的那一条拎出来写成一个单测调通了再扩大范围。单测跑通是底线跑不通就不要去碰别的任务。这套方法论在我后来的真实项目里帮了大忙。Agent 的问题排查不能靠直觉和运气靠的是把不确定的东西尽量变成可回放的过程。7. 给新手和转行者的三周学习计划7.1 第一周大模型 API 提示词基础这一周的目标只有一个把一个模型 API 调得滚瓜烂熟能用提示词控制它的输出格式。每天固定写一个练习。比如周二实现多轮对话周三实现结构化 JSON 输出周四做一个判断题“给模型一段文本让它提取姓名和日期两个字段输出 JSON”。周五看一篇提示词工程相关的资料然后把前一天练习加 few-shot 示例重跑一遍。到周末你手写一个简单总结器把一段会议记录压缩成三条摘要。第一周最重要的是形成“API 就是编程接口”的直觉。不要觉得调模型是玄学它就是一次带输入输出的函数调用只是输出富有不确定性你需要用提示词和参数去驯服它。7.2 第二周工具调用 手写第一个 Agent这周开始进入真正的 Agent 环节。你选一个熟悉的领域比如查询订单、查天气、做数学计算设计两个到三个工具注册到一个工具注册表里。然后实现一个最简 ReAct 循环让模型根据用户问题选择工具、执行、返回结果。我建议你第一版先不要让模型自由思考直接在提示词里写死流程必须判断是否需要工具不需要就作答需要就输出工具调用的 JSON。跑通后再放开约束让模型自己推理。这周结束时你手里应该有一个能用自然语言驱动两个工具的 Agent哪怕它看起来有点笨。第二周最值得庆祝的时刻是你发现“这个 Agent 真的会自己选择用工具了”。这一刻你对 Agent 的理解会一下子从纸面名词变成肌肉记忆。7.3 第三周记忆 评估 对框架祛魅第三周做三件事。第一给你的 Agent 加上滑动窗口记忆让它能够连续对话十轮以上不崩溃。第二准备一组 20 道题的测试集用手写的方式记录完成率和工具调用准确率。第三找任何一个你之前想学的热门框架用“看源码”的方式对照你自己写的代码理解它的设计。第三周的核心目标是“祛魅”。你会发现框架里的很多东西你已经实现了只是它封装得更成熟同时你也会发现自己的实现确实粗糙需要用框架补齐边界能力。这一步做扎实了以后再学任何新框架你都能快速上手而不是每次都被框架牵着走。7.4 三个适合入门的练手项目如果你不知道自己该做什么练手项目我给你三个选题难度从低到高每一个都能写进项目经历里。第一个是“个人知识小助手”让它读取你收藏的文章接一个向量存储用问答方式查询。这个项目的关键点是文本切块和检索质量能让你体会 RAG 的基础套路。第二个是“自动化周报生成器”让它通过工具读取本周的 Git 提交记录自动生成周报并发送到指定的地方。关键点是工具设计你的“读提交记录”工具必须返回结构化数据模型才能稳定生成总结。第三个是“智能客服问答机器人”让它查询订单状态、退换货政策遇到查不到的信息时能礼貌地转人工。关键点是循环控制你必须给足用户明确回复的时机这是真实场景里最挑剔的能力。这三个项目做完你基本能覆盖 Agent 开发的核心场景检索增强、工具调用、状态管理。面试的时候也很有说服力因为每一步都是你自己写出来的不是照抄框架 demo。写在最后的几句经验我见过很多入门者倒在不同阶段。有人卡在“调 API 都觉得玄”有人卡在“模型老是不按格式输出”也有人卡在“学了框架却发现离不开框架”。说实话这些都是必经之路但顺序错了痛苦会加倍。我个人最深的体会是Agent 开发的门槛不在代码而在“把不可控的东西变成可控”的工程思维。大模型是不可控的但你可以用提示词约束它工具结果是不可控的但你可以用标准化格式驯服它上下文是有限制的但你可以用记忆和截断去管理它。这套思维建立起来之后框架对你来说只是工具而不是信仰。如果你现在还在纠结要不要啃框架听我一句劝先关掉框架文档用一个最普通的 API 调用手写一个最小 Agent让它在你的电脑上跑起来哪怕是只会查时间和算加法。等你跑通的那一刻你对 AI Agent 的理解就超过了 80% 停留在“看过教程”的人。剩下的事都是你见招拆招之后自然会发生的事。
阅读完成 · 觉得有帮助?
咨询建站