ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent框架整体架构设计:从状态管理到多Agent协作的工程实践

Agent框架整体架构设计:从状态管理到多Agent协作的工程实践 我记得自己第一次正经写Agent是在一个自动化运营工具的项目里。需求很简单——让AI根据用户输入自动查数据库、调接口、回邮件。一开始我想得特别天真不就是循环调LLM吗给它一个system prompt加几个function让模型自己决定怎么调用完事。结果真正接到生产环境里才发现问题远没有那么简单长时间运行时上下文越塞越满模型开始答非所问两三个工具还行几十个工具注册进去后准确率直线崩塌重试、超时、并发限制每一件事都在等着你去踩一遍坑。所以那之后我开始认真思考一个问题Agent开发需不需要一个自己的架构答案当然是要的。这也是我写构建你的Agent框架这一系列内容的初衷——不是鼓励你去造重复的轮子而是希望你在动手写任何Agent之前脑子里先有一张完整的设计图。本文是第七章7.1节聚焦整个框架的总纲整体架构设计。它决定了你后续所有模块模型接入、推理循环、工具注册、记忆管理、编排模式的边界和关系也直接关系到这个Agent是能跑通Demo还是能扛住生产。这章面向的读者是已经跑通过最简单的LLMFunction CallingDemo正准备从脚本式代码往结构化框架演进的人。1. Agent框架到底在解决什么问题1.1 从调模型到跑完一个任务的距离先说结论Agent框架不是为了让模型调用更花哨而是为了把单次模型调用升级为可靠的任务执行系统。单次LLM调用是这样的输入Prompt → 模型生成 → 拿到文本完结。Agent执行是这样的输入目标 → 模型规划 → 调用工具 → 观察结果 → 调整计划 → 再调用工具……直到达成目标或主动放弃。这两者之间的差距就是Agent框架的价值空间。说白了框架就是一套执行骨架它帮你处理好哪些事呢我列一下核心职责管理Agent执行时的状态包括当前目标的进度、步骤、中间产物。维护模型对话的上下文让模型始终知道现在在哪一步、刚才干了什么、接下来可以做什么。编排规划-行动-观察的循环处理工具调用结果的解析、异常归类、重试策略。提供统一的资源边界如并发控制、token预算、工具权限、沙盒隔离。把每个环节做成可插拔的这才叫框架而不是一个写死的脚本。现实世界里很多人把Agent直接理解为LLM工具循环。这句话不算错但太粗了。它只描述了跑起来的最小闭环没有回答怎么跑得好、扛得住、出问题时怎么收敛。1.2 框架的三大核心义务状态、流程、边界我在设计Agent框架时习惯把问题收敛为三件事状态管理、流程编排、边界控制。状态State是很多初版实现最先出问题的地方。Agent在跑一个复杂任务的时候它需要知道自己已经完成了什么接下来要做什么当前这个环节卡在哪个工具上。这些状态如果散落在各种局部变量里一旦出现并发或重试逻辑很快会乱成一团。正规点的做法是引入一个执行状态机把Agent的每个阶段定义清楚初始化、规划中、执行中、等待工具结果、异常处理、完成、终止。流程Flow描述的是Agent怎么从一个状态迁到另一个状态。最基础的是ReAct式的循环进阶一点有Plan-and-Execute、反射机制Self-Refine等。流程设计直接决定了Agent的稳定性和可调试性。边界Boundary则是很多人会忽略的部分Agent能访问什么工具能使用多少token预算怎么限流怎么在出问题时安全熔断框架层面的边界设计决定了Agent在生产环境中能不能被信任。提示设计框架的第一件事不是写代码而是把这三大义务用文档画清楚。哪怕只在白纸上画一张图也会让后续效率提升数倍。2. 分层架构Agent框架的基本骨架2.1 模型接入层让LLM调用变成可替换的抽象很多人设计Agent框架时第一步就把所有代码和某一个模型的API强耦合了。这在大模型迭代飞快的当下是很危险的。我建议在底层抽象一个模型接入层所有上层逻辑只和抽象接口打交道不直接碰具体模型。模型接入层的核心接口大概是这样chat(messages, tools, **kwargs) - model_response输入统一格式的消息列表和工具定义。输出统一的响应结构包括文本、工具调用请求、token用量等。在这个抽象设计里需要考虑什么请求与响应的归一化。不同厂商的接口格式有差异特别是工具调用的表达方式。有的模型用function call字段有的用tool_calls字段有的走XML协议。接入层要把这些差异吃掉对外输出统一结构。重试与流式处理。LLM接口经常超时或返回限流接入层统一提供重试策略、退避算法、流式聚合。模型路由。生产环境里不同的任务可能由不同模型处理比如简单分类用小模型、复杂推理用大模型、长文档用长上下文模型。接入层应该支持一种路由机制让上层按任务类型选择模型。有人可能会问一个Demo真的需要这么精细的模型接入层吗我的经验是如果只是为了跑通Demo确实不需要。但只要你打算把Agent放进业务流程就早晚要面对换模型、加模型、分配模型的需求。先抽象出来成本很低收益却很高。2.2 推理与规划层核心循环的几种范式Agent区别于普通LLM应用的核心是它拥有推理—行动的循环。推理规划层就是实现这一循环的地方。目前业界常见的循环模式有几种ReAct每轮让模型先思考Reasoning再决定采取什么行动Action执行工具后观察结果Observation不断循环。实现简单、可控性好适合大多数任务。Plan-and-Execute先把大目标拆解为多个子任务计划再逐个执行。相比ReAct它把规划和执行分开避免每一轮都重复规划效率更高但对规划的准确性要求也更高。Reflection模式在循环中加入自我反思环节让模型评估自己之前的结果是否合理再决定继续还是修正。它会增加token消耗但对复杂任务的正确率有提升。框架的推理层在设计上要注意什么循环终止条件必须是显式的包括达成目标模型显式声明完成、达到最大轮数、触发异常熔断。必须支持人工介入。生产环境里的Agent不应该完全自主架构上要留出中断点让人可以观察、修正、批准工具调用。循环状态要外部可见、可序列化。这样即便进程崩溃了也能从某一步恢复而不是从零重来。注意不要一上来就搞花哨的多阶段复杂循环。能把标准的ReAct循环写得干净、可观测再去加Plan-and-Execute等模式一步一个脚印会更省心。2.3 工具层工具注册与调度工具层是整个Agent和外部世界交互的桥梁。模型接入层解决的是怎么和LLM说话工具层解决的是LLM打算做什么框架怎么做。设计工具层时我主要考虑这几个点工具注册表一个中心化的工具注册表。一个工具至少包含函数名、描述、参数SchemaJSON Schema格式、权限等级、执行入口。注册表负责校验工具定义是否合法、去重、索引。工具调用的路由与执行模型返回用户想调用工具A参数是xxx之后框架要校验参数、执行函数、捕获执行结果再以消息形式注入模型上下文。工具执行的错误处理工具调用不像LLM生成那样容错。一次真实的HTTP请求失败、数据库超时、文件不存在都需要框架统一处理并反馈给模型让模型可以调整策略而不是直接让整个Agent崩溃。这里有个经验之谈工具的可发现性设计非常重要。当工具数量超过几十个时模型常常会选错工具或编造工具名。一个常见缓解手段是给工具做分组或者命名空间描述信息写清楚使用场景和边界条件必要时还可以用子Agent做工具检索。2.4 记忆层短时、长期与工作记忆说到Agent记忆很多人一开始容易忽略但后期不得不回来补的模块。我在设计框架时会把它拆成两个层面来考虑。第一层是对话上下文记忆本质是和模型的短时交互记录。它的设计重点是上下文管理不用的内容及时裁剪、关键信息做总结压缩、保险起见保留原始日志。否则Agent跑了几轮tool调用之后prompt会膨胀到模型无法有效聚焦。第二层是跨会话的长期记忆它依赖于外部存储。常见的做法是把用户信息、项目历史、领域知识等转成向量后存入向量数据库需要时语义检索再放回上下文。金融、医疗、企业知识库等场景里长期记忆往往是核心卖点之一但前提是要做好权限与数据隔离否则会把不该泄露的信息带进推理。在设计记忆层时我还有一个自己的做法引入类似工作记忆working memory的概念专门存放当前任务产生的中间状态比如检索到的文档片段、工具返回结果、推演中的候选方案。它和长期记忆的分工很明确工作记忆随任务的推进而不断更新和清理任务结束后可以不再保留或按需沉淀进长期记忆库。这样Agent既不会失忆也不会被过时信息拖拽住。3. 编排层设计从单Agent循环到多Agent协作3.1 单Agent循环的可靠设计在说多Agent之前先把单Agent设计稳固。单Agent的循环是所有框架的底座。我把它拆成三个核心组件Agent对象暴露run(task)入口内部维护状态机统领循环。上下文管理器负责所有消息的增删改查决定什么信息进模型、什么信息不进模型。工具路由器接收模型输出的工具调用经过权限校验之后分发给对应执行器。这三个组件在代码层面相互独立通过数据解耦可以让调试变得特别顺。比如上下文出问题了只动上下文管理器不需要动Agent主体。这也是框架的价值——它逼着你把职责分离而不是把所有逻辑堆在一个大函数里。还有一个特别容易被忽视的点日志与可观测性。Agent循环是多轮次的每一轮里模型看到了什么、模型输出了什么、工具返回了什么、为什么Agent决定终止这些都应该有结构化日志。没有可观测性的Agent框架在排障时就是一场灾难。我在实际项目里始终会在每个循环周期打印一条标准格式的轨迹日志包含轮次编号、动作类型、耗时、token消耗排障时按时间轴回放比拿着Prompt猜快了不是一点。3.2 多Agent协作模式主从、流水线与黑板模式任务复杂到一定程度单Agent会出现两个瓶颈上下文窗口不够用以及单一角色能力不够用。这时就要考虑多Agent架构。多Agent框架的本质不是多个Agent一起跑而是设计一套Agent之间的通信协议和协作模式。业界实践中常见的模式主从模式Orchestrator-Workers一个主Agent负责拆解任务、调度分发、整合结果多个Worker Agent各司其职。这是最通用、最容易实现的一种模式。主Agent可以说就是总编导Worker是执行者。流水线模式Pipeline任务被拆成多个阶段每个阶段由专门的Agent处理前一个Agent的输出作为后一个Agent的输入。适合结构固定的流程比如分析需求 → 生成代码 → 测试执行 → 结果汇报。黑板模式Blackboard多个Agent共享一块黑板公共状态区各自读取、更新自己负责的部分最终汇总成型。它在需要多个Agent交叉协作、共享中间结果的场景中很有效但对同步和一致性要求更高。在设计多Agent编排层时有一个原则我认为最重要多Agent模式只应在收益 复杂度成本时使用。如果单Agent能完成任务就不要硬拆。多Agent带来的通信开销、状态同步问题、调试难度都是指数级上升的。另外关于harness和agent的区别这类问题在编排层面其实有对应的答案。Harness更偏底层的一套执行与控制机制可以简单理解为Agent运行的环境与控制器Agent则是在这个环境上运行的智能主体通过循环调用模型和工具完成目标。设计框架时harness和agent往往是在不同层级上落地的——harness提供通用执行能力agent在其上表达业务语义。3.3 并发与治理让Agent扛住真实流量AI agent怎么扛并发是个热门话题本质上这是个架构问题不是模型问题。单Agent内部的并发瓶颈通常是LLM接口限流、工具执行阻塞、状态冲突。框架层面要提供分级处理。我的经验是按三层治理并发请求层所有LLM调用统一走异步队列控制消费者的并发上限实现令牌桶限流。我在实际项目里会把并发上限配成模型供应商允许速率的一半留出余量应对突发。任务层每个业务任务对应一个独立的Agent实例或会话不共享上下文状态从根上避免状态污染。资源层工具调用要单独做信号量控制尤其是外部API和数据库操作避免Agent把后端系统打挂。外部服务没有降级预案的话宁可任务排队也不要在高峰期硬闯。同时要处理超时与熔断。框架里我习惯给每个循环周期设置硬超时比如单轮规划工具执行的预算时间是30秒超过就中断本轮连续失败超过阈值就触发熔断把坏Agent停掉并上报。4. 安全边界与生产落地4.1 权限最小化与工具防护Agent再强也必须被装在安全的笼子里。这里的安全不仅是防止外部攻击更是防止Agent自身因为幻觉或误判而执行危险操作。在框架层面可以做这些安全措施工具级鉴权不同敏感度的工具需要不同级别的授权。比如只读查询自动放行写操作必须人工确认高权限操作实施双人审核。参数校验模型传给工具的参数不可信必须按JSON Schema做强校验与类型检查杜绝注入和越界参数。沙盒执行对于可脚本化或可执行代码的工具尽量跑在隔离的沙箱里限制网络访问与文件系统权限。Docker容器是一种常见方案配置时需要关掉不必要的capabilities。敏感信息脱敏工具返回结果和模型提示词都不应泄露密钥、个人隐私、内部数据。日志系统里也要做脱敏处理防止trace里明文出现密钥。这部分的思路和agent安全热搜词高度相关。安全边界不能等出了问题再补必须在架构设计阶段就把它作为一等公民考虑进去。上线前给Agent做一轮红队测试专门用诱导性提示词试探权限边界往往能发现意想不到的漏洞。4.2 会话与状态隔离多租户数据不能串如果你做的Agent平台不止服务一个用户或一个租户那数据隔离就是红线。一个用户A的长期记忆和私有资料绝不能出现在用户B的Agent上下文中。实现要点是会话绑定所有Agent实例在初始化时绑定租户ID上下文管理器在读取任何历史或记忆时都要带上租户过滤。存储层隔离长期记忆库的向量集合按租户建立命名空间检索时强制限定命名空间。审计日志记录谁在什么时间让Agent执行了什么操作尤其是工具调用这对追责和合规来说必不可少。我在一个企业知识库项目里就因为没做存储层隔离出现过一次不同部门的数据串查询虽然只发生在测试环境但也足够让人后怕。从那之后所有检索操作必须携带租户上下文就成了我框架里的一条硬约束。5. 从架构图到第一步代码落地时的优先级建议5.1 演进式设计比一步到位更现实最后想说的是不要指望第一章就把图里所有组件一次写完。架构图是终点不是起点。我在实操中推荐这样演进第一版只写Agent 上下文管理器 工具注册表的最小闭环能让模型调用2-3个工具跑通一个场景。这一版的目标是验证循环转得起来。第二版加入状态机和可观测性把对话日志、工具日志、状态迁移记录全部接出来。这一版的目标是问题看得见。第三版补上记忆模块先做上下文压缩再做向量检索。这一版的目标是跑得长。第四版做并发和限流再上多Agent编排。这一版的目标是扛得住。每一版都保持可运行、可验证而不是等框架完美了再开始用。很多团队死在架构设计完美主义上画了三个月图一行代码没跑最后业务根本不买单。5.2 框架好用的检验标准改动的边际成本框架设计里还有一个判断标准你的框架能不能快速适应变化。LLM底座的迭代、工具系统的调整、新业务场景的接入如果每一次变化都要动框架主干说明你的抽象层级搞错了。健康的Agent框架变化应该发生在边缘模块——换模型只改接入层加工具只注册表加一条多Agent只增编排配置。我把这当作架构设计最终的检验标准大部分改动都应该是增量而不是重写。以我自己的经验判断某个模块要不要抽象成框架就看它在6个月内会不会变更三次。会就值得抽象不会就先写死。等需求降临时再重构成本通常比想象中低因为你真正理解了它的输入输出而不是靠猜。最后说点个人体会吧。Agent框架整体架构设计这一节内容是个总纲后续章节再展开讲每一层里的设计和代码实现。Agent框架最难的往往不是某一个技术点而是整套体系的权衡什么时候该做记忆、什么时候该上多Agent、怎么在灵活和可控之间取平衡。我个人的建议还是那句话从一个极简可运行的循环开始让架构图慢慢长出来比一次写完更靠谱。手里有多个Agent项目跑过几轮之后你会自然知道哪个模块值得投入哪个模块可以继续轻量。
返回列表