
Agent 这个词最近被聊得很多但真要动手做一个能用的Agent不少人其实都卡在同一个地方看了一堆概念什么ReAct、Plan-and-Execute、多智能体协作真到自己设计系统时还是不知道模块怎么摆、数据怎么流、记忆放哪、工具怎么接。我自己刚接触那会儿也是这样后来把几个项目翻来覆去拆了几遍才慢慢摸出一条主线。这篇文章就是围绕“Agent通用架构”这个主题把我踩过的坑、总结出的模块划分方式和最小可复现的骨架逻辑整理出来。这篇内容不是框架文档的翻译也不是某个产品的功能介绍。它围绕的是“通用架构”这四个字——不管你用哪个底层模型、哪个开发框架背后的设计思路基本一致。如果你正准备从零入门Agent开发或者已经写过一些Demo但总觉得结构混乱、改起来很痛苦这篇文章会比较对口。我会把架构拆成感知、记忆、规划、行动四层来讲再给出一套可以直接抄作业的最小实现骨架最后聊聊实际运行中最容易翻车的几个问题。1. 为什么叫“通用架构”LLM时代的工作重心转移1.1 从“写逻辑”到“写协议”传统软件开发的核心是逻辑——if else、状态机、复杂的算法流程开发者把“如果发生什么就执行什么”逐条写清楚。但到了Agent这里核心逻辑交给了大语言模型去理解、推理和决策开发者真正要做的变成了另一件事定义模型和外部环境之间如何交互。打个比方传统开发像给员工写一份极其详细的操作手册连鼠标先点哪里、输入框里填什么都写清楚而Agent开发更像给一个聪明但缺乏常识的新实习生划出工作边界告诉他有哪些部门可以对接、每个部门需要什么材料、遇到什么情况必须停下来汇报。你不需要教他每一步怎么做但要确保他在正确的地方拿正确的信息、正确地把指令传递出去。这就引出了“通用架构”的本质它不是一套固定的代码结构而是一组描述Agent如何感知外部世界、如何保存中间结果、如何选择下一步行动、如何调用外部能力的交互协议。只要这四件事被定义清楚了不管任务类型怎么变Agent都能运转起来。1.2 通用架构的四个核心模块我拆解过不少Agent系统最后发现不管项目大还是小都绕不开四个模块。模块作用对应传统架构概念感知层把环境信息转成模型能理解的文本或结构化数据输入适配器、消息网关记忆层保存任务上下文、历史结果、用户偏好数据库、缓存规划层决定“下一步该做什么”拆解任务、选择策略调度器、流程引擎行动层实际影响外部世界调用API、操作文件、发消息RPC调用、命令执行器这四个模块看似简单但绝大多数没做好的项目问题都出在它们之间的接口上。比如感知层的输出格式不统一导致规划层每次都要花大量token去理解“上一轮到底发生了什么”再比如记忆层把所有历史全塞进去没有区分工作记忆和长期记忆结果上下文越来越臃肿模型越来越“笨”。所以理解Agent通用架构的关键不是背下这四层叫什么而是要理解它们之间传递数据的契约是什么。感知层输出的是“观察”规划层输出的是“决策”行动层输出的是“结果”记忆层存储的是“经历”。这四类数据在循环里不断流动构成了Agent最核心的运作方式。2. 核心模块逐个拆解感知、记忆、规划、行动2.1 感知层连接世界的接口感知层是Agent和外部世界的边界。它的职责不是“获取数据”而是“把不同来源的异构输入统一成模型能理解的表示”。举个例子。一个客服Agent可能需要同时接收来自网页表单、邮件、IM消息甚至语音转写文本的输入。这些源格式完全不同有的是JSON有的是HTML有的是自由文本。感知层要做的是保留下所有关键信息同时去掉对任务无用的噪音再统一转成一段结构化的上下文。实操中我建议给每次感知加上字段标注来源渠道、时间戳、用户意图标签、实体抽取结果。这会让规划的输入质量显著提高。很多入门项目把原始信息直接拼进prompt虽然也能跑通但只要任务复杂度一上来模型就会在无关细节上浪费大量注意力。一个容易被忽略的细节是“感知不是一次性完成”的。Agent运行过程中可能需要多次获取信息——先收到用户请求然后查数据库得到用户历史订单再调第三方接口确认物流状态。每一次获取信息本质上都是一次感知动作都要走统一的感知管道而不是散落在代码里到处fetch。2.2 记忆层短期记忆与长期记忆记忆层是所有模块里最容易被做坏的。先说一个最常见的错误把全部历史对话记录都塞进上下文。这会导致两个后果——Token消耗急速飙升以及模型在过量的历史信息中丢失对当前目标的注意力俗称“上下文淹没”。我习惯把Agent的记忆机制拆成三个层次。第一层是瞬时记忆就是当前这轮任务中模型正在处理的上下文窗口。它对应的是“现在正在发生什么”。比如用户说“帮我订一张后天早上去上海的票”瞬时记忆就应该包含用户的需求、当前时间、可选航班列表。这一层不需要持久化任务结束就释放。第二层是工作记忆横跨一个多步骤任务的整个生命周期。比如这个订票任务过程中Agent先查了航班又向用户确认了预算范围最终选择了某个航班。这些中间状态需要被记录且需要在每一步被重新放入上下文。工作记忆通常存为结构化状态——JSON或者数据库记录。第三层是长期记忆对应Agent跨任务保留的用户画像、历史偏好、领域知识库。它不会每次全量加载而是通过检索的方式只拉取当前任务相关的片段。比如用户这次又提到“去上海”Agent可以自动检索到用户上次订的是靠窗座位这个偏好作为建议项被注入规划层。记忆层设计要记住一条核心原则每个写入记忆的数据都要带上“何时、何场景、对后续有什么用”的元信息。否则记忆就只是堆垃圾检索出来的东西连自己都不知道该不该信。2.3 规划层选择策略的手段规划层是Agent最核心的决策部分。它接收感知层的观察和记忆层的上下文输出下一步行动方案。主流做法大致可以归为三类按复杂程度递增排列。第一类是单步决策模型根据当前状态直接决定调用哪个工具、生成什么回复。这种模式适合任务明确、步骤短的场景比如“把用户消息翻译成英文”。优点是快、少出错缺点是没有长程推演能力复杂任务容易拆不干净。第二类是动态规划也就是常说的ReAct模式Reason Act。模型在每一步先思考“当前状况是什么、我该用什么方法”再决定行动观察行动结果后再次思考循环往复直到任务完成。这种模式适合需要试探、信息不足的任务比如“帮我查一下这个产品的竞品定价”。缺点是循环次数不可控可能绕弯子。第三类是任务分解即Plan-and-Execute模式。先让模型把大目标拆成一串有序的子任务清单再逐步执行。适合流程明确、可预见的任务比如“生成一份市场调研报告并导出为PDF”。优点是结构清晰、便于人为干预审计缺点是对突发状态的处理能力弱中间一旦出现计划外偏差整个计划可能需要重新生成。实际的通用架构不会只用其中一种。我现在比较推荐的做法是混合式先让模型评估任务复杂度——如果一步能搞定就直接做如果明显需要多步骤先产出计划执行过程中每完成一步就审视计划是否仍然有效产生偏差就动态调整。这个方案比单独用任何一种都稳定。2.4 行动层对世界的真实影响行动层回答的问题很朴素模型说“我要调用支付接口”然后呢谁去真正发起这次HTTP请求谁解析返回值谁处理异常如果通过代码硬编码每个工具那每接一个新API就要写一遍适配函数Agent的能力扩展成本会非常高。所以我强烈建议把工具注册机制做成声明式的——每一个工具就是一份元数据描述包括工具名称、用途说明、入参结构、出参结构、调用地址或函数指针。模型通过阅读这些描述来决定调用路径系统再通过统一的执行器去实际运行。这里有个很关键的细节工具描述文本的写法直接影响调用准确率。模型不是程序员它不知道你这个接口内部怎么处理它只通过你的描述来判断“什么时候该用这个工具”。描述写得太泛模型会在不该调用的时候乱调写得太窄该用的时候又想不到。我一般要求工具描述的写法遵循“触发条件 输入要求 输出说明 边界限制”的结构能显著提高调用命中率。行动层还必须有统一的超时与重试机制。外部接口可能挂、可能慢、可能返回垃圾数据如果Agent把异常返回当作正常结果继续往下走错误会被逐级放大。我的经验是行动层必须区分两类结果正常结果和异常情况。异常情况要明确告知规划层“这件事没办成、原因是某接口超时”规划层才能决定是重试、换方案还是让用户介入。3. 架构怎么串起来控制流与数据流设计3.1 单智能体的主循环通用架构的模块拆完之后要琢磨的是它们怎么协调运转。单智能体的标准流程可以概括成一个循环观察-思考-行动-观察。我画过很多次这个流程图真正落地时其实就是一段主循环逻辑。Agent收到一条新输入后先走感知层清洗和标准化输入然后从记忆层加载当前任务的工作记忆和相关的长期记忆片段把“当前观察 相关记忆 可用工具列表”一起交给规划层让模型产出行动方案行动层执行方案并返回执行结果结果被写入工作记忆同时回到观察阶段判断任务是否已经完成。这个循环的终止条件需要单独定义。我见过很多入门项目只设置了最大循环次数一旦超过就强制结束并返回错误。这样很粗暴但至少能防止死循环。更好的做法是让模型在每一轮输出中显式标注“任务完成”状态只有当模型自己认为所有子目标都达成时循环才自然结束。循环过程中“上下文如何组织”是决定成败的一个细节点。一般我会把当前轮的系统提示结构设为五段角色设定、任务目标、背景信息、执行进度、下一步待办。前四段是由感知层和记忆层生成的最后一段交给模型自由推理。这种结构让模型每一轮都知道“我已经做到了哪、还剩哪些没做”不会因为上下文太长而忘记初衷。3.2 多智能体协作的基本模式当你需要处理一个足够复杂的任务单智能体已经hold不住——要么上下文过长、要么单个模型角色无法兼顾多个视角——这时候就需要考虑多智能体架构。多智能体通用架构在四层之上还要增加一层“通信编排层”。最常见的协作模式是“单主管-多专员”。一个控制型Agent负责理解总目标把子任务分派给不同角色的专业Agent收集它们的产出并汇总成果。这种模式结构清晰容易追踪问题。缺点是控制型Agent容易成为瓶颈任务一多它的上下文会巨大。另一种模式是“同行评审”。几个Agent针对同一个任务各做一版结果再互相审查、指出问题由最终汇总Agent整合。适合文本创作、方案设计这类质量要求高、主观性强的任务。缺点是Token消耗成倍增加执行时间更长。还有一种是“流水线接力”。每个Agent只处理一个环节输出直接交给下一环节。适合任务边界清晰的流程比如数据采集Agent把结果交给分析Agent分析Agent再把报告交给撰写Agent最后汇总输出。效率高但灵活性差前序Agent一旦出错错误会一路向下传导。我在实际项目里多采用混合编排主体流程用流水线但每个环节内部嵌入一个同行评审或单主管结构。多智能体架构的设计要诀是“角色边界清晰”每个Agent只做一件事不做多余的事。任何模糊地带最终都会变成概率性出错。3.3 状态、上下文与可观测性多模块、多循环、多Agent协同的系统中最怕的是“黑盒化”。不知道自己当前处于哪个阶段、工作记忆里存了什么、上一轮到底执行到哪一步。所以好的Agent架构从第一天起就必须把状态管理当作一等公民来设计。状态管理的核心是维护一份可序列化的运行记录。每一轮循环结束后系统应把以下信息同步到外部存储或日志中当前任务ID、已完成步骤列表、最新观察结果、最新决策内容、工具执行结果摘要、当前待办事项。这份记录能让你在任务异常中断时快速恢复也能用于回放调试。可观测性方面我建议至少做到三个维度的日志。第一是决策日志记录每一轮模型收到的提示词摘要和产出的决策信息用于分析模型的推理质量。第二是工具有效性日志记录哪个工具被调用了、耗时多久、返回了多少内容、是否成功。第三是性能成本日志统计每轮循环调用了多少Token、完成了多少有效工作用来评估架构效率。这三类日志缺一不可。很多项目出问题后无从排查就是因为在关键时刻没有记录“当时为什么执行了这个动作”。有了日志诊断问题就像看回放一样而不是猜谜。4. 从零实现一个迷你Agent框架的实操过程4.1 最小骨架LLM调用封装讲完概念直接上手写框架。这里用Python做一个极简Agent框架的实现重点是把四层架构跑通不依赖任何重量级第三方框架。核心依赖只需要一个LLM API客户端和一份工具注册表定义。from typing import Callable, Any, Optional class LLMClient: def __init__(self, api_key: str, model: str gpt-4o): self.api_key api_key self.model model def chat(self, system_prompt: str, user_prompt: str) - str: # 这里需要根据你使用的模型API适配 # 将system_prompt和user_prompt发送给模型返回文本响应 # 实际项目中注意超时与重试 import time time.sleep(1) return 这是模型返回的文本这一步没什么魔法。注意两点第一LLM调用必须有超时和重试机制外部依赖不稳定是常态第二每一轮调用的Token消耗要能够被统计后面做成本控制要用。我习惯在这层直接返回并记录调用次数和token数。4.2 记忆与工具注册的设计记忆管理在一个Minimal设计里我倾向于直接用字典加一个简单的持久化接口来模拟。工作记忆的本质是当前任务状态的结构化表达。长期记忆则应该做成检索式接口哪怕一开始用简单的列表加关键词匹配都比什么都做强。工具注册表是行动层的基础。每个工具通过装饰器或者注册函数声明框架自动收集所有工具的描述信息供规划层读取。class ToolRegistry: def __init__(self): self.tools: dict[str, dict] {} def register(self, name: str, description: str, parameters: dict, func: Callable): self.tools[name] { description: description, parameters: parameters, func: func, } def list_tool_meta(self) - list[dict]: result [] for name, meta in self.tools.items(): result.append({ name: name, description: meta[description], parameters: meta[parameters], }) return result def execute(self, name: str, arguments: dict) - Any: if name not in self.tools: return {status: error, message: f工具 {name} 不存在} try: return self.tools[name][func](**arguments) except Exception as e: return {status: error, message: str(e)} registry ToolRegistry() def tool(name: str, description: str, parameters: dict): def decorator(func): registry.register(name, description, parameters, func) return func return decorator tool( namesearch_flight, description查询出发地和目的地之间的航班信息输入出发城市、到达城市和日期返回航班列表, parameters{from_city: string, to_city: string, date: string}, ) def search_flight(from_city: str, to_city: str, date: str) - str: return f从{from_city}到{to_city}在{date}的航班值飞航班A0808:00起飞1200元这里有一个必须重视的细节工具注册时填写的description和parameters一定要站在模型视角撰写。模型不读代码实现它只凭这些文字判断工具用途。如果description写的是“函数入口”模型大概率会在不该调用的时候乱调。长期记忆的记录我习惯用一个独立接口最小实现就是到一个SQLite表里按关键字存取进阶再换成向量检索。在入门阶段别急着上向量数据库先用简单的检索策略跑通逻辑后面再升级。class MemoryStore: def __init__(self): self.store {} def save(self, key: str, value: Any, tags: list[str] | None None): self.store[key] {value: value, tags: tags or []} def search(self, query: str) - list[Any]: matched [] for key, item in self.store.items(): # 简洁起见用tag匹配真实实现可以换向量检索 if query in key or any(query in tag for tag in item[tags]): matched.append(item[value]) return matched上面的MemoryStore本质上就是一个字典只适合做演示。真实系统中记忆层应该对接真正的持久化数据库每条记忆要有时间戳、来源、衰减策略。但核心的接口设计可以沿用——保存时附带检索标签查询时按语义匹配取回。4.3 主循环与任务执行示例现在把四层串起来。这个主循环的关键点在于每轮的提示词必须包含工具清单和工作记忆摘要让模型“知道自己有哪些牌可以打、现在打到哪里了”。同时一定要定义终止条件我采用模型显式输出{status: done, result: ...}的约定。class Agent: def __init__(self, llm: LLMClient, tools: ToolRegistry, memory: MemoryStore): self.llm llm self.tools tools self.memory memory self.max_iterations 10 def build_prompt( self, user_input: str, run_state: dict, tool_meta: list[dict], ) - tuple[str, str]: system_prompt f 你是一个通用的任务执行助手围绕用户目标逐步行动。 当前任务目标{user_input} 当前执行进度 {run_state.get(progress, 尚未开始)} 可用工具清单 {tool_meta} 使用工具时请严格输出如下JSON格式不要输出其他内容 {{ thought: 你的判断理由, tool_name: 要调用的工具名若不调用则为空, tool_arguments: {{...}}, status: working 或 done, result: 任务完成时的最终结果 }} return system_prompt, user_input def run(self, user_input: str) - str: run_state {progress: [], feedback: []} for i in range(self.max_iterations): tool_meta self.tools.list_tool_meta() system_prompt, user_prompt self.build_prompt(user_input, run_state, tool_meta) response self.llm.chat(system_prompt, user_prompt) # 简易解析模型的JSON输出——这里只是为了演示思路 import json parsed json.loads(response) tool_name parsed.get(tool_name, ) if tool_name: tool_result self.tools.execute(tool_name, parsed.get(tool_arguments, {})) run_state[progress].append(f调用 {tool_name}结果{tool_result}) run_state[feedback].append(tool_result) continue status parsed.get(status, working) if status done: return parsed.get(result, 无结果) return 已达到最大迭代次数任务未能完成以上代码是一个高度简化的骨架但它体现了Agent架构的关键流程感知层在build_prompt中承载了用户原始输入、当前进度、工具清单记忆层在run_state中维护工作记忆你可以进一步把MemoryStore的检索结果也注入其中规划层交由LLM完成决策行动层由ToolRegistry统一执行。注意这段代码没有做错误处理、也没有处理模型输出非法JSON的情况真实项目中这两个坑逃不掉。我建议至少做两层防护一层是要求模型严格按JSON输出并捕获解析失败后的重试另一层是设置正则表达式解析兜底即使模型输出夹带文字也能取出JSON片段。别嫌麻烦模型输出格式不稳定是常态不是例外。4.4 用实际场景验证架构流程骨架搭好后用一个最简单的场景验证用户输入“帮我查明天从北京到上海最早的航班”。这时框架的运转过程如下第一轮模型看到可用工具只有search_flight并了解任务目标和参数要求返回调用search_flight、参数{from_city: “北京”, to_city: “上海”, date: “明天”}status为working。框架执行工具返回航班列表将其写入run_state进度。第二轮模型看到工作记忆中有航班A08信息认为目标已达返回status为done、result为“明天北京到上海最早的航班是A0808:00起飞”。框架收到done后返回结果主循环结束。这个最简单的流程验证了四层架构的完整联动。之后你再扩展无非是加更多工具、更丰富的记忆检索策略、更多Agent角色但主循环控制逻辑可以一直沿用下去。这也是为什么我强调先把通用架构跑通再去往一个具体场景里填肉——顺序反了项目就会变成一堆散落的函数改一个功能牵一发动全身。5. 常见问题与排查技巧实录我在实际学习和落地Agent架构的过程中踩过一些坑也帮别人排查过一些。下面这些问题是反复出现的代表性问题把它们记下来能省很多Debug时间。5.1 上下文爆炸与记忆内容失控这是Agent开发中几乎必然遇到的问题。随着循环次数增加历史记录越积越多你可能选择把所有内容都塞进提示词因为“模型应该知道所有信息”。结果模型开始变得迟钝明明是最新的一条工具结果它却依据早期内容做出决策甚至忽略当前任务目标。原因是上下文过长后模型对关键信息的注意力被稀释了。这和人类在大段资料里找重点很相似——不是信息不在而是噪音太多。排查思路先看日志中每一轮的输入token量。如果发现从第3轮开始输入token翻了好几倍大概率就是记忆没有做加工一直在全量拼接。解决办法是给记忆层加摘要机制每完成一步用模型把步骤摘要压缩成三行以内的要点下一轮只带摘要和最新观察结果而不是所有原文。虽然多花一次摘要的token但能保住模型后续的决策质量。5.2 工具调用“假成功”另一种极其常见的隐蔽问题工具调用显示成功实际上逻辑执行是错误的。例如模型填错了参数类型导致接口返回了空列表但请求本身没有报错或某个工具返回的字段映射到了另一层结构模型看到“status: ok”就直接认为任务已完成。这类问题最坑因为日志里一切都是绿色的结果却不对。对策是两管齐下。第一行动层在工具返回中增加一个统一包装结构至少包含状态码、业务状态、数据摘要、异常信息让模型能明确判断“这次调用到底有没有真正拿到有意义的数据”。第二在规划层提示词中强调“工具返回的内容必须经过可信度检查后才能作为最终结论”并且要求模型在做最终结论时引用工具结果里的具体字段而不是笼统地说“查询成功”。5.3 循环空转与成本失控最让人头疼的问题之一Agent在某一步反复调用同一个工具拿到的结果也一样却始终不认为自己完成了任务。它在原地打转Token却不断被消耗。这类空转的深层原因是规划层没有“状态对比”能力——它不记得上一次调用这个工具时看到的结果是什么所以每次都当新鲜事处理。我的解决方案比较暴力在主循环里加一个检测逻辑如果同一工具、相同参数、返回结果哈希一致且连续出现N次就强制中断并提示模型“你正在重复执行相同步骤请换一条思路或宣告失败”。如果模型宣告失败就返回工具不可用或让用户介入。成本控制方面建议从一开始就做一个“步骤数-有效动作比”指标。有效动作是指能够改变工作记忆或推进任务进程的调用比如查询到了新信息、执行了一个写操作。如果这个比值长期低于50%说明规划的路径太绕需要优化提示词或改用Plan-and-Execute模式来结构化拆解步骤。5.4 几个独家避坑建议这里分享几个我在项目里沉淀下来的习惯做法不一定能在官方文档里找到但对真实开发很有帮助。第一个是每条工具调用记录都加追踪ID。无论是单Agent还是多Agent系统给每一轮行动分配一个全局唯一的trace_id并把决策日志、工具入参出参、Token消耗全部绑到这个ID上。排查问题时你不再需要猜“这个结果是哪一轮哪个Agent产生的”直接看追踪链就行。第二个是工具调用前做参数校验。不要让模型任意字符串就往函数里传。比如日期参数一定要解析为标准格式枚举类型的参数要在提示词里给出可选列表。很多“模型乱传参”的抱怨其实是因为你在注册工具时没把参数边界写清楚。第三个是给Agent加“临时停靠点”。就是当模型在自己尝试连续失败超过一次后主动进入“向用户确认状态”的流程——暂停行动、说明当前处境、让用户选择方向。这个设计能大幅降低失控风险。很多Agent系统设计时默认“自主执行到底”但真实世界里没有足够的上下文时停下来问一句往往比乱撞要好。下面把几个最高频的问题和应对方案汇总成一张速查表。症状可能原因首选排查动作根治方案上下文越长决策越差记忆层未做压缩全量拼接看日志中input token变化曲线引入工作记忆摘要机制工具返回成功但结果不对模型误判返回内容、参数错配检查该轮工具入参和原始返回统一返回包装结论引用校验循环空转、不推进规划层缺少状态对比检索连续轮次的重复动作加重复检测强制终止模型反复调用错误工具工具描述写得不清晰检查该工具的meta描述文本按“触发条件边界”重写描述Token消耗远超预期循环次数过多或上下文膨胀统计每轮token消耗分布增加步骤成本上限摘要裁剪多Agent之间互相覆盖结果角色边界没设清楚查看各Agent的输出日志严格定义单一职责输出格式隔离6. 下一步的学习路线和扩展方向如果前面的骨架你已经看懂并且动手跑通过了接下来可以往几个方向继续深入。这里我按建议优先级说一下。优先做的是把记忆层替换成真正的向量检索方案。当前骨架里的MemoryStore是字典模拟只适合验证逻辑。真实任务中长期记忆需要根据语义相似度拉取相关片段这时候可以用嵌入模型把记忆文本向量化存进向量检索库查询时按相似度取TopK。这一步做完Agent的跨任务连续工作能力会有一个质的提升。其次建议实现可插拔的人机确认机制。也就是Agent在执行风险操作删除数据、发邮件、支付、修改配置前先输出一个待确认请求等用户批准后再继续。这个功能在生产环境几乎是必需品。从架构上看只需要在主循环中增加一个“风险操作拦截”阶段当工具注册表标记某工具为高风险时执行前必须经过一个确认状态。另一个值得投入的方向是多智能体协作框架。不要把多Agent想得太神秘它本质上还是四层架构只是把不同角色Agent的规划层和记忆层隔离开用统一的通信协议在它们之间传递任务和结果。你可以先从“控制-执行”两种角色做起再把执行Agent扩展成多个功能不同的专员。最后还有一块容易被新手忽略评估。Agent不是一次写完就完事的它的行为具有概率性同样输入可能得到不同输出。所以你要设计一套可重复的评测集合记录多种输入下Agent是否完成任务、调用了几次工具、花了多少Token、中途有没有走偏。评测是Agent能持续迭代的基础也是在架构层检验优化效果的最终裁判。我个人在实际操作中的体会是Agent通用架构学习最快的路径从来不是看完某一篇文章而是手头有一个真实到必须修修补补的项目。当你亲眼看到上下文爆炸把模型变得迟钝、看到空转把电费烧上去之后再去回看这里提到的模块划分与接口设计才会真正理解每条规则背后解决的问题。这篇文章给的骨架和避坑清单不是终点只是一个可以让你站在上面继续试错的地基。