恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
从零手写大模型智能体:架构拆解与工程落地指南
首页
资讯中心
/
从零手写大模型智能体:架构拆解与工程落地指南
从零手写大模型智能体:架构拆解与工程落地指南
发布时间:2026/10/19 6:58:34
最早折腾大模型智能体(Agent)那段时间我一度以为自己只是在写一个“大循环”把模型输出当成指令接着调用工具再把结果喂回去。直到某次调试一个看似简单的多步骤任务模型在第三步就开始自说自话完全偏离了用户的目标我才意识到Agent 的关键压根不在“循环”而在“循环的每一圈里谁在负责什么、什么信息该留下来、什么信息该扔掉”。这两年关于大模型智能体(Agent)的讨论很多但真正说到点上的文章其实不多。多数内容要么停在概念层面把 ReAct、Plan-and-Execute 念一遍要么直接甩一个框架 Demo跑通后却说不清为什么这么设计。这篇内容我打算换个写法不替某个框架背书而是把 Agent 当作一个“可以徒手搭出来、也值得徒手搭一遍”的系统来讲先说清楚它到底改变了什么问题再把架构拆成决策、感知、行动、记忆四块最后给出能直接落地的实现思路和我在实测中踩过的坑。想深入理解 Agent 而不是只停留在“调用大模型”层面的读者应该能从中得到一套自己的判断框架。1. 先搞明白Agent 真正改变了什么1.1 从“一次性预测”到“闭环决策”传统的大模型应用本质是一次性预测用户输入一段文字模型根据训练学到的概率分布预测最合适的下一段文字。整个过程没有“外部动作”模型也不会记得上一次输出。哪怕你在一次请求里把历史聊天都塞进去它也只是在做一个更长上下文里的预测并没有改变“输入-输出”的单向结构。Agent 的引入改变的是这个结构本身。它把“一次性预测”变成了“闭环决策”模型先基于当前状态选择一个动作动作在外部环境中执行产生一个观察结果然后这个观察结果重新作为模型下一轮决策的输入。用最朴素的话说模型不再只负责“说话”它还负责决定“接下来干什么”并且要承担自己决定的后果。这个循环可以浓缩成这样一段代码state initial_state() # 目标、初始上下文、可用工具 while not done: action llm.decide(state) # 模型输出一个动作 if action.type finish: done True # 模型认为目标已经达成 else: observation execute(action) # 调用工具、访问环境 state update_state(state, action, observation)每一轮循环里都有三个东西缺一不可模型要能输出“下一步指令”外部环境要能执行这条指令并返回结果执行结果必须被写回状态影响下一轮决策。缺了第一条Agent 只是个固定脚本缺了第二条模型永远在空转缺了第三条整个循环就退化成普通的多轮对话。1.2 “调用了工具”不等于“Agent”现在很多产品都声称自己有 Agent 能力但如果你把他们的实现拆开会看到三种完全不同的形态。我把它们列成一张对比表方便对照着看形态决策方式是否执行动作是否根据结果调整后续举例接口调用用户/脚本决定否否调一下大模型接口翻译文本工作流编排预先定义的有向图是否固定“先搜索、再总结”的流水线真正意义上的 Agent模型根据当前状态动态决策是是模型先判断需不需要搜索再决定调用哪个工具如果结果不够再换一条路工作流编排和 Agent 之间最容易混淆。工作流的路径是开发者在写代码时就定死的先做什么、后做什么、遇到什么条件走哪条分支全部有迹可循。Agent 不一样模型自己在每一轮决定下一步可能这次先搜索再计算下次发现可以直接用知识回答连搜索都不碰。开发者的工作从“设计流程”变成了“设计环境”给模型提供目标、工具、规则然后容忍它在解法空间里自由探索。这也是 Agent 项目最难接受的地方它有时候会做出开发者没想到、甚至看着“绕远路”的决策但这恰恰是 Agent 的优势所在。如果所有路径都能提前枚举那用工作流反而更可控、更便宜没必要强行上 Agent。2. 架构三层拆解决策、触手、账本各管哪一段把 Agent 拆开看通常可以分成三个层面负责想决策层、负责动感知与行动层、负责记记忆与状态层。三个层面互相配合任何一层做得糙整个系统都会拖垮。2.1 决策层LLM 不是唯一的大脑决策层是 Agent 的“大脑”但它并不是“只有大模型”。相反在我实际搭建过的系统里决策层往往是混合结构大模型负责开放式推理规则系统负责约束和兜底。具体分解下来决策层要处理三类事情目标拆解把用户的一个模糊目标拆成可执行的子步骤。比如“帮我整理这份会议纪要并总结成邮件”需要拆成“读取文档→提取项目→生成摘要→拟邮件”等若干步。动作选择每一步选择用什么工具、传什么参数。这里大模型是主力因为动作空间常常是开放式的。结果评估执行完一个动作后判断结果是否满足需求是继续推进、换一条路还是直接结束。我见过很多团队把三件事全都丢给大模型结果模型在长任务里越跑越偏。我的建议是让大模型做它擅长的开放式推理用规则兜住它不擅长的边界。比如优先级排序、敏感信息过滤、参数校验这类确定性逻辑用代码写死比让模型判断可靠得多。2.2 感知层把环境变成模型能读的文本大模型只能读文本这是 Agent 设计里最容易被低估的约束。所谓感知层就是负责把各种外部环境信息转换成模型能理解的文本形态。回到我之前说的“循环”感知层其实就是execute(action)之后到update_state(state, observation)之间的那一段。它要做的事包括网页转 markdown而不是把原始 HTML 塞给模型API 返回的 JSON 做字段抽取只保留对当前任务有用的部分数据库查询结果转成简洁的表格文本图片、音视频通过多模态模型描述成文字或者干脆不转直接用外部模型对图片做分类后只传给大模型分类结果。这里最容易犯的错是“原样塞入”。我见过一个 Agent搜索工具返回了 30KB 的网页正文系统提示词里直接拼进去模型不仅没变聪明反而开始胡言乱语因为关键信息被淹没在了一堆广告和噪声里。感知层的核心原则是不是把信息给得越多越好而是把信息处理得越贴近当前任务越好。2.3 行动层工具注册表与执行沙箱行动层负责真正的“动手”。它通常是围绕一个工具注册表构建的每个工具登记四样东西名称、描述、参数规范、执行函数。TOOL_REGISTRY { search_web: { description: 搜索互联网并返回最相关的前 N 条结果适合查找实时信息、新闻、资料。, parameters: {query: string, top_k: int}, function: search_impl, }, calculate: { description: 执行数学表达式计算适合四则运算、公式求值不支持模糊提问。, parameters: {expression: string}, function: calculate_impl, }, }注册表里的“描述”字段极其重要它直接影响模型能不能在决策时选对工具。后面我会专门展开讲工具描述怎么写。除了注册表行动层还要注意执行沙箱工具运行时的权限、超时时间、异常捕获、日志记录都要在这里统一处理。工具崩溃不能导致整个 Agent 挂掉至少要把异常信息转成文本原样给模型看让它决定下一步怎么做。2.4 状态与记忆层这里最容易翻车状态层是所有信息的集散地包含当前目标、任务列表、对话历史、工具执行结果、环境快照。状态层管理得好不好直接决定了 Agent 的“烦”和“蠢”。很多初学 Agent 的人把状态简单理解成“上下文”于是每轮循环都把全部历史一个不落塞给模型。这在单轮任务里没有明显问题任务一旦拉长上下文长度会线性增长模型要么遗忘早期目标要么被无关信息带偏token 成本也快速飙升。所以状态层必须做分层哪些信息放进模型上下文哪些信息存到外部哪些信息可以压缩成摘要都要有明确的规则。这一块内容我在第 5 节单独展开。3. 手写最小 Agent选型、主循环和停止条件我不反对用框架但我强烈建议真正开始写业务代码之前先徒手写一个最小 Agent。原因很简单框架把很多控制点藏起来了你很难感知到“哪一步消耗了多少 token、哪一步该拦一下”这种细节。徒手写一遍这些控制点会逼着你挨个做决定。3.1 技术选型别先想框架先想控制点如果你的任务是一个标准的多步骤工具调用场景选型时不要上来就决定“用哪个 Agent 框架”先想清楚下面几个控制点控制点需要考虑的问题常见选择决策模型要支持多步推理、可处理工具选择性价比要平衡主流大模型 API按推理能力阶梯选择工具执行是否需要沙箱、是否需要审批、是否有超时控制本地函数、容器、或受控的远程服务记忆存储是否需要长期跨会话记忆、需要什么检索方式内存字典、关系库、向量库循环控制最大步数、停止条件、失败重试策略自己用代码写死别依赖框架黑盒初期我建议选一个接口简洁的大模型 API工具直接用 Python 函数包一层记忆暂时放在字典里主循环自己写。这样跑通一个 demo 后你对每一行代码都有掌控感之后再怎么套框架都不慌。3.2 主循环设计谁来决定“下一步做什么”最小 Agent 的主循环本质上就是一个“模型决定动作程序执行动作结果回到环境”的迭代过程。实现时关键是设计好每轮循环给模型的系统提示信息结构。我在实际项目中用的结构大致如下[目标] 用户最终想得到什么用一句话说清楚。 [当前计划/任务状态] 已经完成了哪几步接下来还剩下哪几步当前卡在哪 [可用工具] 工具名功能描述。何时使用……。何时不使用……。参数说明…… [本轮观察] 当前正在处理的这条信息比如刚刚搜索到的结果、表格内容。 [历史简要] 最近 3 轮以内的动作和结果更早的内容一律压缩成摘要。这套结构最核心的一点是不要把所有历史一股脑塞进去要按角色分清楚主次。目标是最高优先级任务状态其次工具说明再其次最后才是具体观察和历史。模型每轮决策都要先“看到目标”否则做几个动作之后它就会忘了用户到底要什么。主循环的伪代码可以写成这样def run_agent(user_task, max_steps10): state { task: user_task, plan: [], history: [], finish: False, } for step in range(max_steps): prompt build_prompt(state) # 按上面结构组装 response llm.chat(prompt) action parse_action(response) # 从模型输出中解析动作 if action.type finish: state[finish] True break try: observation execute_tool(action) except Exception as e: observation ftool execution failed: {e} state[history].append((action, observation)) state update_plan(state, action, observation) return state注意max_steps一定要设置。你永远不会希望一个无人值守的 Agent 无限循环下去那不是智能是 bug。3.3 工具描述怎么写模型才不乱调工具描述可能是整个 Agent 实现里“投入产出比”最高的一部分。我见过不少项目模型频繁调错工具、参数传错类型问题根源都在描述写得含糊。差的描述是这种search_web搜索网页。模型拿到这种描述遇到“帮我查一下明天是否下雨”这种需要天气接口的场景可能会去调search_web搜回来一堆网页还得再解析。好的描述应该像一份精确的操作手册search_web在互联网上检索公开信息返回排名靠前的结果列表。 * 适合查找实时咨询、最新新闻、不熟悉的领域背景资料。 * 不适合无法回答用户的“确定性”问题例如“系统版本是多少”这类需要访问本地系统的问题。 * query 传字符串不要传自然语言问题top_k 默认 3最大 10。描述里加“何时使用 / 何时不使用”这个信息对模型决策的帮助特别大。它相当于主动给模型划了一条工具选择的边界让模型不用在动作空间里瞎猜。多个工具的情况下这个效果尤其明显。3.4 主动结束让 Agent 知道自己“不知道”最小 Agent 的另一个关键设计是停止条件。除了设置最大步数还要让模型有“主动结束”的通道。我通常会在动作类型里加入finish和ask_clarification两种特殊动作。finish表示模型已经得到结论可以输出最终答案ask_clarification表示模型发现目标信息不足需要向用户追问。这样就避免了一种尴尬场面Agent 在信息不足的情况下硬着头皮推断产出一个看起来像模像样、实际上完全错误的结果。主动承认“不知道、不完整”本身就是 Agent 可靠性的体现。工程上可以这样定义如果模型两次输出几乎相同的失败路径也强制引导它调用ask_clarification或直接结束。4. 规划与反思从“走一步看一步”到“先想再走”4.1 ReAct 式的边走边想最经典的 Agent 决策模式是 ReAct核心思路是让模型交替输出“思考Thought”和“动作Action”动作执行后拿到“观察Observation”再进入下一轮思考。它像一个人边走边想根据眼前的反馈不断调整下一步。Thought: 我需要先看看数据库里这个用户的订单记录。 Action: query_orders(user_id1024) Observation: 返回 2024 年共 12 条订单其中 3 条未支付。 Thought: 用户可能想问未支付订单的情况我先汇总一下未支付金额。 Action: sum_amount(statusunpaid, user_id1024) Observation: 等待模型下一次决策……ReAct 的优势是灵活适合探索性强、环境高度不确定的问题。缺点是容易跑偏模型做着做着可能把最初目标忘掉尤其是在长链条任务里。所以它适合“搜索型”任务不适合“流程型”任务。4.2 Plan-and-Execute先列计划再执行另一种常见模式是 Plan-and-Execute。模型在第一轮先把任务拆成一个计划列表之后每一轮按计划取一个子任务来执行执行完再回到计划上下文更新进度。好处是任务目标被显式写进状态里每一步都知道“我正在做计划的哪一部分”不容易跑偏。适合处理步骤清晰、可以拆分的任务比如写报告、批量数据整理、多文档对比。实际实现时计划本身也是状态的一部分。我在系统提示里会给模型一个计划列表的模板每次更新后让它重新输出剩余计划。这样每一轮 Prompt 都包含“当前进度”模型不用靠记忆回溯一定程度上缓解了长任务遗忘问题。4.3 计划之外的反思机制反思机制是我后来补的一块也是把 Agent 从“能走通”推向“走得好”的关键。反思本质上不是让模型“检讨自己”而是把失败经验融入后续决策。工程上有三种常见做法错误回填工具执行抛出异常后不让模型直接原样重试而是让它先读一遍异常信息重新描述问题、换一种工具或换一个参数。判决器模型用一个更便宜的小模型对 Agent 每一步的动作打分如果发现某次动作偏离目标就强制让主模型重新规划。经验记忆库把历史失败的“动作-结果”对存起来在后续相似场景中作为“反面教材”注入上下文。我在实践中发现错误回填是最好实现、收益最明显的。举个真实场景Agent 调用某个查询工具参数传错了第一次报错。如果没有反思机制它可能会原封不动再调一次报错再调直到耗尽步数。加上反思机制后模型会看到“参数格式错误”的提示自己改写成正确格式后重试成功率立刻上了一个台阶。4.4 实际中怎么选模式适合场景主要风险成本ReAct探索型任务、信息收集长链条跑偏中高Plan-and-Execute流程型任务、可拆分任务计划僵化不肯调整中带反思的 Plan-and-Execute需要稳定可靠结果的任务实现复杂调试成本高高我的建议是先从 ReAct 做起跑通后再给主循环加上“计划字段”。绝大多数任务用“边走边想 显式计划状态”就足够了反思机制按需叠加。5. 记忆不是缓存分层存储决定 Agent 能扛多难的活5.1 工作记忆用系统提示词摆好“工作台”工作记忆对应的是 Agent 在当前任务里必须即时可见的信息。实现上它就是每轮请求里的系统提示词加上最近的几轮上下文。我上面说的“目标 / 计划 / 工具 / 观察 / 历史”结构就是工作记忆的组织方式。工作记忆的核心矛盾是容量有限。上下文窗口再大塞进太多东西都会稀释注意力。所以我给自己定了一条经验规则除了系统提示词外具体历史只保留最近 3 轮动作和结果更早的内容全部压缩成摘要。关键是如何压缩摘要。直接让模型“总结一下前面的内容”不靠谱因为摘要容易丢掉关键数字和动作细节。我通常把摘要结构化变成[摘要] 已完成读取配置、查询订单数。 关键数值订单总量 1024未支付 3 条。 待办根据订单状态生成提醒。 需要留意用户询问的是“今年”的数据不是全部年份。结构化摘要比自然语言摘要可控得多。模型后续决策只需要读这几个字段就能快速对齐状态。5.2 长期记忆向量库不是唯一答案长期记忆解决的是跨会话、跨任务的知识沉淀问题比如用户偏好、历史任务结论、领域知识片段。很多人的第一反应是“上向量库”但向量检索并不适合所有记忆。我的分层方案是结构化偏好用普通数据库存。比如“用户希望回复简洁”这种偏好写成key-value存起来检索时直接精确命中。知识片段和任务结论用向量库。比如“某次任务里发现某组件对时区敏感”这种经验适合向量化后按语义检索。时间敏感的记忆要有时间戳。比如“昨天已经查过某数据结论是 X”时间过了一天可能就失效检索时要按时间衰减排序。检索时不是把所有长期记忆都塞进上下文。我通常的做法是基于当前任务文本先从长期记忆里取出 Top 3 条相关结果作为“背景参考”放在系统提示词里同时标注每条记忆的“来源任务”和“置信度”。模型看到的是经过挑选的资料而不是一坨记忆碎片。5.3 忘记机制与更新长期记忆最容易踩的坑是“只存不删”。一次错误的结论被存进记忆库之后会在无数次后续任务里反复污染上下文。我在实现里会给每条记忆加两个字段confidence和last_updated。当新任务产生的新结论与旧记忆冲突时不是直接覆盖而是把两条都带进上下文让模型判断然后把胜出的一条置信度调高另一条调低。定期清理置信度过低、长期未访问的记忆长期记忆库才不会变成垃圾场。记忆更新还有一个细节不要让大模型在正常决策流程里顺便“写记忆”。写记忆是一个独立动作应该由专门的子模块处理对内容做质量筛选。不然模型顺手把一句闲聊也当知识存进去后面会被自己坑死。6. 多智能体协作什么时候真的需要怎么实现6.1 单 Agent 的瓶颈单 Agent 虽然已经能完成不少任务但到了复杂的真实业务里会出现几个绕不开的瓶颈上下文纠缠所有目标、计划、历史、观察都堆在一个上下文里模型要在大量信息中聚焦越来越容易分心。单点疲劳一个模型既要拆解目标、又要选工具、又要评估结果决策负担很重长任务里错误率明显上升。并行受限任务内部如果包含多个互相独立的子任务单 Agent 只能串行执行效率非常低。这些瓶颈出现的时候会有一种很自然的想法拆多个模型一个专门负责拆任务一个专门负责执行一个专门负责质检。这就引出了多 Agent 协作。6.2 三种常见的协作模式多 Agent 的实现方式五花八门但万变不离其宗常见的三种模式是编排-执行模式一个“主管” Agent 负责任务拆解和分配多个“执行者” Agent 各自负责一块最后把结果汇总给主管。适合有明确流水线的大任务。辩论模式多个 Agent 从不同角度分析同一个问题互相质疑最后综合出结论。适合高风险的决策场景比如方案评审、代码审查。层级模式主管下面还有主管形成树状结构。适合任务量大且有父子关系的情况但实现复杂度也最高。我在实际项目里用“编排-执行”模式最多。主管 Agent 本身不一定需要很强的推理能力我甚至用过一个比执行 Agent 更小的模型来当主管它在拆任务时输入是“目标清单”和“可用执行 Agent 目录”输出是“任务分配单”结构清晰效果反而比大模型随意调遣要稳定。6.3 一个可落地的多 Agent 消息协议多 Agent 协作的工程核心不是 Agent 本身而是它们之间的消息协议。最忌讳的设计是把所有 Agent 的上下文全部共享到一个超大消息里那等于回到了单 Agent还更贵。我用的协议非常简单——每个消息是一份 JSON包含task_id、from、to、payload、status五个字段。payload里只放当前子任务需要的最小信息不要带无关背景。Agent 之间不直接传递自然语言聊天记录而是传递结构化产物比如“订单列表”“摘要文本”“错误报告”。这样的好处是每个 Agent 都只面对一小块明确上下文推理质量更稳定消息可以落盘方便追踪和复盘执行 Agent 完全可以并行效率提升明显。多 Agent 的坑在于主管一旦拆错任务错误会在执行链路上放大。所以至少要有一个“质检 Agent”专门检查执行结果或者让主管在汇总时做一次结果校验。7. 落地时最常踩的坑以及我的调优记录7.1 成本失控循环次数是预算的放大器Agent 的 token 消耗不是“一次调用”的量级而是“循环次数 × 每轮上下文”的量级。一个中等复杂度任务跑 10 轮可能消耗普通对话场景 20 倍以上的 token。很多人第一次跑通 Agent 后看到账单直接愣住。我的应对策略有三条。第一系统提示词里写清楚“能用一步完成的事不要绕两步”减少模型不必要的试探。第二工具返回结果必须做截断和摘要特别是搜索类工具返回结果经常有几十 KB我会用一个“摘要过滤器”先把结果压缩成 3-5 行再喂给模型。第三max_steps设小一点默认 6需要更长任务的场景单独放开。这三条加起来实际成本能控制在原来的三分之一左右。7.2 工具输出污染上下文比 cost 更隐蔽的问题是工具输出本身会成为模型的干扰源。比如一个数据库查询工具返回了一张 50 行的大表模型需要的是“汇总后的未支付金额”却被表里各种无关字段干扰回答开始编造数据。解决方法是把工具输出和模型输入分开。工具有两类直接型工具和摘要型工具。直接型工具返回结构化数据比如查询结果、计算结果这类数据通常在 JSON 里摘要型工具返回的是“半成品”我需要先运行一个压缩层把原始输出转成“对当前任务有用的摘要”然后再进入模型上下文。像“搜索网页”这种工具我基本永远把它当摘要型处理。7.3 评测 Agent不测 Prompt要测任务Agent 系统最难受的地方在于它的输出有随机性。同一个任务这次跑通下次可能就翻车。所以必须有评测机制否则改一个系统提示词你都不知道是变好了还是变坏了。我的评测维度有三个层级层级指标说明任务层成功率给定任务集Agent 能正确完成的占比成本层每任务 token 消耗平均跑完一个任务的 token 成本和时长稳定层坏档率出现死循环、无法停止、输出格式错乱的占比每次改动循环逻辑、记忆策略或工具描述都必须先在固定任务集上跑一遍回归测试。任务集不用太大20 个覆盖典型场景的用例就够关键是每次对比必须在同一批用例、同一温度参数下进行。7.4 我的调试技巧最后分享一个屡试不爽的调试方法把 Agent 的完整轨迹按 JSON Lines 格式落盘。每一行记录一步动作包含时间戳、当前目标、模型输出、工具参数、工具返回摘要、累计 token。出现问题后直接翻轨迹文件基本上 5 分钟就能定位是模型决策错、工具输出脏还是状态更新逻辑写错了。再配合一个“调试模式”在系统提示词里加一句“如果某个动作连续失败两次请输出 debug 信息并停止执行”。这个机制在无人值守的环境里特别有用它能避免错误被不断放大同时把关键信息保留在日志里。最后想说的大模型智能体(Agent)这个方向给我最大的体会是大部分失败不是模型不够聪明而是外层工程把模型用坏了。上下文塞得太多模型会迷路工具描述写得含糊模型会乱选没有停止条件模型会空转不做结果校验错误会沿着循环链放大。把这些外部工程做到位你会惊讶地发现一个很普通的模型接口也能稳定完成复杂任务。另外一个值得留意的经验是Agent 的调试周期比普通应用长得多。普通应用改一行代码可以立刻知道对错Agent 改一个提示词可能要跑 20 条用例才看得出趋势。所以一开始就把日志、评测、轨迹回放这些基建搭好后面省下的时间绝对值得。说实话Agent 这个方向还在快速演化今天的“最佳实践”过半年可能就过时了。但底层的控制点——决策、感知、行动、记忆、停止条件、评测——这些不会变。把徒手实现这套最小系统做过一遍再去拥抱任何新框架你都会比别人多一层判断力。