尧图精选

从外挂到一等公民:Agent原生系统架构设计与落地实践

🕒 发布时间:2026/9/28 17:37:52 📁 来源:尧图网络
1. 从加个Agent功能到原生长出来agent-native到底变了什么先说一个我观察到的现象。去年年中开始身边越来越多团队宣称自己的产品接入大模型上了Agent功能但你把他们的系统拆开看十有八九还是老一套业务系统照旧跑在传统三层架构里只是额外搭了个网关把用户请求转给大模型再塞几个Prompt模板进去。这种思路不是不行但在处理复杂任务时各种别扭会接二连三地冒出来。举个具体场景。假设你要做一个企业服务台助手让它能帮忙查工单、发通知、走审批。传统做法是给它配一堆Function Calling接口系统里原有的用户体系、权限中心、消息推送、工单状态机一概不动Agent只是在这坨系统外面套了个壳。刚开始测几个简单对话还行一旦涉及多轮对话、跨多个子系统协同、长时间任务跟踪问题全来了上下文散落在各个服务里找不齐、状态不同步、Agent无法真正感知业务变化、每轮交互都要重新拼装一堆参数。这就是我一直强调的一个判断Agent不能作为系统的外挂它应该是系统的一等公民。这个判断正好指向这两年圈子里反复提的词——agent-native。agent-native直译就是代理原生。它说的不是哪个框架也不是某个开源项目名称而是一种架构取向在设计系统的第一天就把Agent当作核心参与者纳入建模让业务数据结构、状态流转、并发模型、权限体系甚至UI层都围绕Agent如何工作来组织。换句话说不是传统系统Agent能力而是Agent原生的系统。这也是本文想展开的核心话题agent-native系统到底长什么样为什么值得你认真对待以及从实操角度怎么一步步落地。这篇文章适合正在做Agent应用、被外挂式集成折磨够了的开发者也适合刚准备切入AI应用架构、想少走弯路的同学。我会把关键设计取舍、我实测过的参数和踩坑经历都写出来方便你直接参考。2. 一场被忽略的前提之争状态流与执行流谁说了算在展开agent-native的具体设计之前有必要先把一个最底层的架构分歧摆出来。因为很多人藏在这个分歧里却根本没意识到。2.1 传统系统的状态为王我们传统的后端系统不管微服务还是单体核心资产是稳态数据。用户要下单订单服务先写库状态变成已创建然后经过支付回调改成已支付再经过发货流程变成已发货。每一步都有明确的触发条件和数据落点中间允许失败重试但状态机的转换路径是预先画好的。即便有异步任务、消息队列系统整体上仍然是事件驱动、状态收敛的模型。在这种模型里执行是一件相对机械的事情。系统收到指令按图索骥地改状态它就是为确定性而生的。2.2 Agent系统的执行即状态Agent系统不太一样。一个Agent在执行任务时它可能要自主决定下一步调用哪个工具、在什么时候暂停等待用户输入、如何根据中间结果修正计划。这带来一个本质变化执行过程本身就是State而且这个State是动态的、非预先枚举的。你没法把Agent正在思考要不要调用搜索工具这件事写死成一个业务状态字段。我见过的人最容易在这点上犯迷糊。他们想用一个传统的工作流状态表来跟踪Agent比如建一张表字段叫当前环节结果发现Agent的行为根本不是几个固定环节能描述的。它今天可能走三步就完成任务明天同样的任务要绕五步中间还多出了几次自我纠错。用传统状态机去约束它要么把Agent的自然决策路径掐死要么状态表里塞满了设计时根本没想到的临时状态最后整个表变成了一个垃圾场。2.3 agent-native的调和方式——双重状态模型我现在的做法是明确区分两层状态。一层是业务态比如工单是待分配处理中已完成这部分照旧由业务系统管理确定性很强也是最终让企业放心的审计基准。另一层是执行态Agent规划到了哪一步、调用了什么工具、拿到了什么结果、下一步候选动作有哪些这些信息以执行痕迹的方式独立建模不塞进业务表里。有人会问这不还是两套系统吗区别恰恰在数据归属性上。在agent-native系统里业务状态不关心Agent怎么绕路走它只回答这件事的业务结局是什么执行状态则完整记录Agent每一步的思考与操作它回答Agent是怎么走过来的。两者通过任务ID关联但生命周期完全解耦。这个设计看似简单却解决了我之前遇到的绝大多数Agent状态混乱问题。提示如果你做的东西需要人工审计这个双重状态模型几乎是必须的。业务表里别混入Agent的阶段规划步骤这类动态字段否则审计时会非常被动因为Agent的行为路径不可枚举而审计只认确定性的业务事实。3. 上下文、记忆与工具agent-native的三大核心设计点聊完状态模型这个地基就该看看地面上要盖什么了。一个长得像原生的系统至少要在上下文、记忆、工具接入三个点上有清晰的设计决策。3.1 上下文不是把所有历史消息丢给模型很多人做Agent把上下文等同于对话记录。多轮对话一长就把之前的消息全部拼起来塞进Prompt结果要么超长token爆炸要么模型被大量无关历史干扰。在agent-native设计里上下文应该是一个可裁剪、可索引、可注入的资源层级。我常用的分法是主动维护一份会话摘要关键事实当前任务快照。会话摘要是对过去对话的压缩当前任务快照是Agent正在处理的这件事的全部相关参数关键事实则是这次任务必须遵守的企业约束比如超过两万的审批必须走三级流程。给模型拼Prompt时优先级是当前任务快照大于关键事实大于会话摘要。实测下来这套策略比无脑塞历史好太多不仅省token准确率也更高因为模型不会被十轮前的闲聊带偏。3.2 记忆要区分运营记忆与工作记忆记忆和上下文常被混为一谈但agent-native系统里必须拆开。我习惯这样划分工作记忆指当前任务执行过程中需要随时读写的信息比如一个中间计算结果、一个待确认的参数运营记忆指跨任务沉淀下来的长期知识比如上次给这个客户发方案时对方明确不要PDF只要在线文档。运营记忆如果直接堆在向量库里检索时会面临看似回忆实则幻觉的问题。后来我换了一套做法运营记忆以结构化的事实条目入库每条附带置信度、来源会话ID和更新时间。Agent要查询时先把自然语言问题转成结构化查询再从库里捞候选事实交给模型判断。这样既保留了长期记忆能力又避免了纯向量检索带来的语义相近但事实错误的坑。这个细节是我在实际项目里跌了一跤后才悟出来的后面避坑章节会细说。3.3 工具接入的原生感来自统一契约工具定义这件事理论上大家都懂——给模型描述清楚有什么工具、参数是什么。但实际项目里最大的坑是工具参数与业务数据模型不一致。比如企业通讯录里部门ID是一个四位数编码但Agent生成工具参数时往往给个部门名称传过来还要再转一次一转换就容易出错尤其是存在同名部门的时候。agent-native对工具接入的要求不止是能调而是要在编码层面就防止模型用错。我现在的做法是给每个内部工具定义严格的输入Schema并在Schema里用枚举和正则限定取值。更关键的是工具的描述语必须写明使用前提。比如查询合同工具描述语里要写明仅当用户明确提到合同编号或合同名称时使用否则先调用客户查询工具。这些约束会让模型的行为稳定很多。别以为LLM真的理解了你的系统它只是按照文字提示在做事你的工具描述越具体它的执行就越接近你想要的动作。4. 选型实战从单进程编排到可观测的Agent Runtime说完了设计进入选型和落地的阶段。这部分我会给你一个我自己梳理过的对比框架以及在不同规模下我认为合理的方案。4.1 三种主流的Agent编排模式对比先说我见过的三种模式单进程函数编排、异步队列编排、状态化Runtime编排。单进程函数编排是早期原型最常用的Agent在一个进程里跑完规划-执行-观察循环简单直接适合Demo和内部工具。缺点也很明显一旦Agent需要等待人工审批、或执行时间超过一两分钟进程就卡在那很容易超时。异步队列编排把Agent拆成多个消息处理单元每个单元干完活就往队列丢消息适合和已有事件驱动架构结合。但它的弱点是Agent的主控逻辑被拆碎在多个消费者里出了问题很难完整还原Agent当时的思考链路。状态化Runtime编排是目前我认为最贴合agent-native理念的。它的核心是有一个专门管理Agent执行状态的运行时Agent的每一步都会序列化保存支持暂停、恢复、重试、人工干预。你可以把超时当成状态未更新把审批当成状态挂起一切都在一层统一的执行态里管理。我在自建项目里用的就是这种模式代码会多写一些但长期维护价值非常大。4.2 我最终确定的组件选型清单关注点我采用的方案备选方案选择理由Agent运行时自建状态化Runtime存储用PostgreSQLRedisTemporal、LangGraph、Dify需要深度定制暂停/恢复策略自建透明可控模型接入层统一Provider抽象走OpenAI兼容协议各家SDK直连方便切换模型也方便做成本与限流控制工具执行内部微服务以HTTP接口暴露统一工具网关直接Function Calling网关统一鉴权、审计、限流企业级可管控上下文存储Redis存工作记忆对象存储存会话快照ElasticsearchRedis最快快照用于追溯查询频率不高可观测性OpenTelemetry Trace 自定义Agent日志只打业务日志必须能还原模型输入、工具调用、中间结果全链路这套组合不是最优的但它是让我在快速迭代和生产可用之间找到平衡点的一套。如果你团队小、项目刚起步完全可以从LangGraph起步但记得提前预留执行态外置存储的改造空间不然将来迁移状态模型的时候会很痛苦。4.3 自造Runtime的三个核心接口我自己造Runtime时主要只定义三个核心接口够用且不复杂。第一个是Compensate接口用于Agent执行中发现计划不可行时回退到某个检查点。不分布式事务回滚到检查点就行。第二个是Interrupt接口用于等待用户确认、人工审批或外部条件满足。这个对应了前面说的状态挂起是真实业务里最高频的需求。第三个是Observe接口把Agent每一步的中间结果和决策理由记录成结构化日志。这一步对企业级落地太重要了管理层拍板是否上线一个Agent很大程度上取决于能不能清楚看到它的决策过程。提示这三个接口一定在设计Runtime的第一天就加进去。事后补Interrupt会非常痛苦因为它涉及执行态的序列化格式变更改起来等于推倒一部分状态机。5. 上下文工程、记忆落库与工具网关详细落地步骤有了架构和选型下面进入步骤细节。这节我不讲空话尽量多写可以直接抄作业的内容。5.1 上下文工程的落地步骤第一步设计会话摘要更新策略。我用的触发条件是新消息达到N条或累计token超过阈值两者先到先触发。摘要任务本身也用大模型生成但必须要求它输出固定结构历史目标、已决定事项、待办事项、用户偏好。结构化的摘要比自由文本好用得多因为程序可以直接从JSON里提取字段用于后续决策。第二步定义关键事实的优先级。我会维护一张事实表每行是一个企业约束或用户偏好比如市场部预算审批上限是5000元附上来源与生效时间。给模型拼上下文时先按当前任务类型过滤再按优先级插入确保同一时刻上下文里的关键事实不超过五条。第三步设置上下文隔离。不同任务之间不串话这看起来简单但很多系统因为用了同一个Prompt模板导致一个Agent执行任务A时把任务B的信息一并带上。我处理的方式是每个任务有独立的内存空间会话摘要也按任务ID分割绝不跨任务复用。5.2 记忆体系的落库细节记忆体系这块我直接说说我的表结构和写入逻辑。运营记忆表的核心字段是记忆ID、内容摘要结构化、实体标签比如客户ID、项目ID、置信度、来源会话ID、更新时间、启用状态。写入时机不是每轮对话都存而是当发现模型输出了对当前任务有价值但未来可能再用的信息时才存。这对很多开发者是个反直觉的设计。他们往往把对话记录一股脑全部向量化并丢进向量库结果检索质量越来越差。我更推荐提取-审核-入库三步曲先用模型从对话里抽取候选记忆条目再通过简单规则或少量人工审核过滤掉低置信度内容最后才入库。虽然多了一步计算但记忆库的质量差异非常大。读取侧我坚持一条原则记忆库的读取结果永远只是候选材料最终上下文的内容拼装必须经过一次模型判断。换言之不能让检索结果直接进Prompt而是让模型判断哪几条候选事实与当前任务真正相关。这个细节能够避免语义相近但张冠李戴的问题。5.3 工具网关的落地细节工具网关是agent-native里另一个容易偷懒、后面又不得不补的地方。我建议你把所有Agent可调用的工具统一收敛到一个网关服务由它负责鉴权、限流、风暴抑制和审计。记一次不算冷门的坑我们的工具网关曾经同时给Agent和前端页面共用一批接口。有一次前端疯狂轮询某个接口结果限流策略把Agent的工具调用也掐了Agent任务成批失败。从那次以后我把Agent工具流量和普通业务流量在网关里做了彻底隔离限流桶分开、告警级别分开、Trace链路用不同的服务名标记。这个改动看起来小但直接决定了线上Agent的稳定性。注意不要为了省事让Agent直调内部微服务。一旦工具数量增多你迟早需要一个统一出口做哪些Agent能调哪些工具的权限控制工具网关是agent-native体系里绕不开的基础设施。6. 多Agent协作与事件驱动让系统真正长出协作能力agent-native做得稍微深入之后会面临多Agent协作的问题。这里我讲两个我踩过并解决的问题。6.1 别让Agent直接互调有一种幼稚但很常见的多Agent方案就是让Agent A在工具列表里看到Agent B的接口然后直接互相调用。这看起来灵活实际上灾难。A不知道B的上下文、不知道B的当前状态、不知道B会不会因为某个操作触发一连串副作用整个调用链完全不可控。我在生产系统里用的是事件总线调度器的方案。Agent A不直接调用B而是往总线上发布一个任务事件调度器根据事件类型和路由规则决定投递给哪个Agent。投递后Agent B执行完再把结果以事件形式发回。调度器记录每个事件的来源、目标、状态与耗时整个协作过程可以被审计和追踪。这个方案变通起来也不难本质上就是把Agent之间的直接函数调用改成了异步消息投递。虽然多了一层调度但可观测性和可控性都得到了质的提升。6.2 事件设计要带任务血缘刚开始做事件总线时我犯了一个错误每个事件只带业务ID和内容不带任务血缘。结果多Agent协作时系统里飘着几百个事件却不知道它们属于哪个任务、谁发出的、处理到哪一步了。后来我规定所有Agent协作事件必须携带一组标准Header任务ID、父事件ID、发送Agent ID、接收Agent ID、时间戳、事件类型。这组信息组成了完整的事件血缘关系。任何一个任务出问题我都能顺着血缘链找到哪一步开始跑偏。这个设计与前面说的双重状态模型配合起来非常顺手。提示事件不要直接发送业务大对象只传业务ID和必要参数。其他Agent需要完整数据时通过内部接口按ID拉取。这能避免消息队列包体过大以及数据一致性问题。7. 避坑实录我踩过的三个深水坑与最终方案再好的架构也要在真实环境里接受考验。这一节写三个我在agent-native落地过程中踩得最深的坑每个都不是简单配置能解决的。7.1 运营记忆向量化带来的事实幻觉第一坑来自运营记忆的纯向量化方案。我最初把客户沟通记录切段后全部向量化存入向量库。Agent提问时直接从库里检索Top-K片段并拼入上下文。前期demo阶段没问题因为测试问题比较固定。上了生产环境第一周就出事了Agent答复一个客户的发票抬头时从一位同事的闲聊记录里检索出这家公司可能改名了的文本信心满满地告诉客户贵司已经改名为XX公司。我当时复盘发现向量检索只能判断语义相似不能判断命题为真。从那以后我彻底转向了结构化事实条目置信度方案。凡是进入运营记忆的信息必须能提炼成主体-属性-值结构并记录来源。没有来源、无法结构化的聊天内容宁可丢弃也不让它污染记忆库。这个教训让我心疼了很久但也让记忆体系统成熟了一大截。7.2 超时重试导致的任务爆炸第二坑和超时重试有关。最初我在Agent调用外部工具时设了个普通超时比如5秒。网关超时会触发重试一开始只重试1次。某个第三方服务抖动时也没啥大事。后来有次第三方服务故障了20分钟网关的线程池被重试任务占满消息队列积压了几万条任务事件。调度器重启后积压的任务又同时涌入形成二次冲击。那次我花了大半天才把系统平稳下来。现在的方案是分两层控制。第一层Agent调用外部工具的超时重试策略必须显式配置允许重试次数、退避间隔、是否可降级。第二层网关侧做熔断连续失败超过阈值就快速失败不再重试。调度器侧则限制每个Agent的并发执行数量和队列积压阈值超过就拒绝新任务并告警。这三道闸门缺一不可。7.3 计划与行动之间的校验盲区第三坑是Agent计划了A但执行了B。有一次我们的Agent在计划中写下先查询当前用户所属部门但执行时却把工具参数填成了另一个用户的ID。原因在于Agent拿到上一个上下文的残留内容把它误当成当前参数了。解决这个问题我在计划与执行之间加了一道校验器。Agent生成行动计划后先由校验器检查每个步骤的输入参数是否能在当前上下文中找到可信来源。找不到的强制Agent停下来向用户确认不允许它自作主张猜测。这道校验器本身的规则很简单但效果拔群它把参数幻觉类错误压到了一个很低的比例。这个思路也印证了agent-native的核心主张执行过程中的每一步都应该有迹可循、有据可查而不是完全依赖模型自觉。8. 模型选型与成本控制越原生越要精打细算写到这里如果你已经决定要走agent-native路线那么关于模型与成本的部分必须同步考虑。原生架构意味着模型会被大量调用——不是一次对话调一次而是一个任务执行过程中反复规划、调用工具、自我修复。8.1 多模型分层使用我的基本策略是不同环节用不同模型而不是全流程绑定一个最强模型。简单说规划环节需要一个推理能力强的模型因为它要把复杂任务拆解成一步步动作工具参数生成环节则不一定需要最强模型可用较快且便宜的模型中间结果分析和记忆提炼环节甚至可以用更小的模型只要给足结构化指令。这个策略的实测收益相当可观。曾有一个合同处理任务全流程用同一个大模型单次任务成本大约2.1元改成分层模型后单次成本降到约0.65元而任务成功率反而提升了因为每个环节的模型都更聚焦。成本下降不代表能力下降模型选型越贴近任务整体效果越好。8.2 控制token膨胀的几个开关还有几个非常细节的开关能显著影响成本。第一工具返回结果先做截断。我在工具网关层做了一个结果摘要器把长文本列表压缩成要点而不是原样塞给模型。第二Agent执行状态快照不要每次全量存只存增量。第三上下文拼装时设定按任务类型自动降级比如简单查询任务不全量载入运营记忆只载入当前任务相关的事实。控制和成本从来不是后期优化越早设计进去越能避免Agent上线后被账单吓一跳。9. 最后再分享几个我实测过的小经验按惯例结尾不放虚的。我直接把最近一段时间用得最顺手、也最容易被忽略的几个经验列出来。Agent执行日志请用独立的存储引擎。业务日志和Agent执行日志不要混在一起。Agent日志量非常大而且检索模式完全不同——你往往要按任务ID拉取一段完整执行链独立存储能避免两边互相干扰。给Agent每一次关键决策都记录理由字段。模型输出的决策理由哪怕只是一句话也要一并存下来。这不仅是审计需要也是后续调试的关键依据。模型输出异常时看理由往往能一秒定位问题。统一使用任务执行人-任务发起人双角色概念。Agent系统里发起任务的人和实际执行任务的Agent可能都是参与者但他们权限不同。权限建模时要区分清楚否则会出现Agent能调用的工具比用户本人还多的情况。灰度发布Agent不要只比正确率要比异常路径数量。新旧版本Agent跑同一批任务记录它们触发请求澄清工具报错计划回退的次数这个指标比单纯看完成率更能暴露问题。我个人始终坚持的认知是agent-native不是一场银弹式革命它更像是对系统架构的一种重新审视当Agent从配角变成主角我们为确定性系统发明的很多假设就要重新做一遍。如果你正在做一个有点复杂的AI应用希望这篇文章能帮你省掉一些我走过的弯路。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →