ARTICLE DETAIL

资讯详情

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

AI应用架构设计实战:模型网关、Agent编排与上下文工程全拆解

AI应用架构设计实战:模型网关、Agent编排与上下文工程全拆解 最近在做AI应用架构设计评审时我发现一个特别普遍的现象很多团队把大模型应用想得过于简单觉得只要封装一个API、把Prompt拼好、把返回结果丢给前端就算做完了。可一旦用户量上来或者业务需要接入多个模型、引入Agent编排、处理长对话记忆原本一个接口一把梭的代码就会变成一团乱麻。真正成熟的AI应用从来不是调用大模型这一个动作而是从入口到数据再到模型之间的一系列架构决策。这篇文章我想用画图的思路带你把AI应用架构设计拆开揉碎。会先讲清楚AI应用到底在架构什么再逐个分析模型网关、向量库、Agent编排这些核心组件接着聊并发流量怎么扛上下文工程怎么做最后从单Agent走向多Agent协作时架构会发生什么变化。无论你是刚开始做AI应用开发还是正在负责技术选型这篇都能给到你一份可以直接落地的参考框架。1. 从调API到建架构AI应用到底在架构什么1.1 一次最简单的调用背后藏着哪些模块我们先看一个最朴素的大模型聊天机器人。用户在网页里敲了一句帮我总结这份合同前端把这句话发给后端后端往大模型API里一丢模型返回总结页面渲染出来。就这么一个流程看起来五步搞定但真正到了生产环境你至少还需要考虑这五件事之外的十几个隐藏模块。我在刚入行时踩过一个坑第一个AI应用上线后服务端突然收到一堆重复请求因为前端做了重试后端又没有做幂等结果同一条用户消息被模型处理了两遍用户收到了两条重复回复。这就是典型的架构缺失——没有请求去重没有超时控制。一个完整的AI应用调用链路在业务逻辑之前应该先有API网关、身份认证、限流、审计日志、内容安全审核、Prompt模板管理在业务逻辑之后还要有结果缓存、成本统计、可观测性埋点。如果你把这条链路画成一张时序图会发现用户和模型之间隔着一大堆中间层。这些中间层不是可有可无的装饰而是让AI应用具备生产可用性的骨架。早期很多团队直接让前端调模型API省事是省事但密钥会暴露成本失控模型一限流整个系统全挂。所以架构的第一步就是把这些看不见的模块显式化。1.2 用一张图拆开AI应用的四层结构我平时习惯把AI应用架构画成四层自上而下分别是接入层、编排层、模型层、数据层。下面用表格列出每层的职责和典型组件层级核心职责典型组件/技术接入层对外暴露接口处理认证、限流、安全、协议转换API Gateway、Nginx、Auth Service编排层组装Prompt、决定调用顺序、管理Agent循环、处理工具调用LangGraph、CrewAI、自研Orchestrator模型层对接一个或多个大模型控制路由、降级、缓存OpenAI兼容网关、vLLM、TensorRT-LLM数据层提供外部记忆、检索增强、业务数据库访问向量库、Redis、PostgreSQL、对象存储为什么要分成四层核心目的是隔离变化。模型层是最容易变的地方你可能今天用A模型明天因为成本换成B模型如果业务代码里到处是from openai import OpenAI换模型就成了一场灾难。有了模型网关上层只面对一个统一接口模型怎么换是下面的事。数据层也一样今天用向量库做RAG明天想换成图数据库增强关系推理只要编排层通过数据服务接口访问底层替换就不会炸到业务逻辑。画完这张图你还能直观看出每一层之间的接口定义。比如编排层和模型层之间到底传递的是纯文本还是结构化的消息数组数据层返回的检索片段是直接塞进Prompt还是先经过一个重排模块这些问题都属于架构设计的核心决策图一画出来哪里模糊哪里缺接口一目了然。2. 核心组件选型模型网关、向量库和Agent编排2.1 为什么不能绕过模型网关很多中小项目一开始只接一家模型厂商觉得模型网关是过度设计。我的看法恰恰相反模型网关不是可有可无的中间层而是AI应用架构里的断路器。它至少承担四件关键事统一接口、密钥托管、负载均衡和质量开关。统一接口很好理解无论你接的是字节的模型还是阿里的网关都把它包装成一个标准的Completion接口业务侧不感知厂商差异。密钥托管则解决安全问题直接在前端调用模型接口最大的风险是密钥泄漏网关把密钥锁在后端前端只跟网关打交道。负载均衡更实在同一个模型请求可以按权重打到不同厂商的同级别模型上或者按用户维度做路由。我印象最深的一个案例是某家做客服助手的团队把模型网关配成了主备模式主用旗舰模型当旗舰模型因限流返回429时网关自动把请求降级到备用的成本更低的模型。结果某天晚高峰主模型排队严重他们的系统靠着网关自动降级硬是撑住了两个小时的流量高峰业务成功率只下降了不到3%。没有网关这种容灾几乎不可能一个接口全局实现。2.2 向量数据库不是可选项取决于场景AI应用一定要上RAGRAG一定要上向量库这是我在社区里听到最多的错误直觉。实际上向量库是否必要取决于你的应用是否需要语义相似度检索这种能力。如果你的AI应用只是做纯生成、总结、翻译不依赖私有知识库那引入一个独立的向量数据库大概率是给自己找运维负担。但一旦你遇到这些场景——让AI基于企业内部文档回答、让AI从几千条聊天记录里找到相似问题、给用户做语义搜索——向量库就是不可绕过的组件。选型时我习惯先把需求摁到两种类型里嵌入式向量索引比如FAISS适合单机数据量小、离线索引可接受、不需要复杂过滤的场景。优点是部署简单丢进应用进程里就能跑缺点是数据量上来后内存压力大多副本同步也麻烦。独立向量数据库比如Milvus、Qdrant、pgvector适合数据量大、需要实时写入、需要按业务字段过滤、需要高并发查询的场景。好处是弹性扩展、带持久化和权限控制缺点是代价是一个额外的分布式系统需要监控运维。我曾经在一个项目里先用了FAISS后来业务要按用户ID过滤结果还要支持每天百万级记录更新FAISS单机内存完全扛不住才不得不迁到独立向量库。如果前期就画清楚数据流的图这个返工完全可以避免。数据量、过滤条件、更新频率三大要素决定了向量库选型的走向。2.3 Agent编排决定应用具备多少自主性Agent是当前AI应用架构里热度最高的词但很多团队把Agent等同于多轮对话。真正的Agent编排核心是让模型在一个循环里自主决定下一步动作当前输入要不要调用工具调用哪个工具需要什么样的参数如果工具返回异常是不是该换一条路径重试把这个循环画出来就是经典的ReAct模式模型观察用户请求结合当前状态推理决定采取动作执行工具工具返回结果模型再观察直到得出最终答案。这个循环必须由编排层控制而不是让模型自己无止境地跑下去。所以编排层至少要维护两个东西一个是状态记录当前Agent走到了哪一步、已经收集了哪些信息另一个是路由表定义什么条件下该用哪个工具、什么条件下该结束循环。市面上LenangGraph、CrewAI这些框架本质上都是帮你管理节点、状态和路由的。但我的经验是框架可以解决80%的通用编排问题剩下的20%比如工具返回异常后的重试策略、Agent步骤的持久化、超时后的降级应答往往还是要自研。架构设计时不能只画一个Agent框就完事要把这个框内部的状态机画出来才能准确评估复杂度和风险。3. 架构中的流量与并发Agent怎么扛住真实压力3.1 请求链路中的每个环节都可能成为瓶颈在大模型应用里一个用户请求往往不只是调用一次模型。尤其Agent场景可能先做一次意图识别然后检索向量库再调用一次外部工具最后再让模型汇总答案。整条链路下来可能触发三到五次模型调用。这意味着你看到的在线用户数和背后模型API的实际调用量中间可能隔着好几倍的系数。我自己画链路图时会给每个节点标注它可能出现的瓶颈。用户一多最先扛不住的往往不是模型API而是前面这些看似轻量的环节环节可能瓶颈常用应对手段API网关连接数上限、限流误伤水平扩容、按用户/按IP分级限流会话存储Redis连接/内存瓶颈集群化、冷热分层Prompt组装模板渲染耗时缓存编译后的模板模型调用API限流、排队延迟并发池、队列削峰、多路降级热点数据缓存缓存失效击穿本地缓存分布式锁外部工具第三方API限流熔断、退避重试这些瓶颈不是等线上报警了才去加而是在画架构图时就要标出来。我习惯在每条链路旁边写一行假设模型响应3秒Agent最多调用5次则用户最长体验是15秒如果这个数字超过产品预期就要考虑并行调用工具、提前预取检索结果甚至改异步交互模式。3.2 状态管理无状态化与外部化会话Agent应用最容易被忽视的架构问题就是状态放哪。如果你把对话历史、Agent的中间思考、工具调用结果都放在服务进程的内存里那么一旦服务实例重启、扩容或缩容用户会话就全丢了。更要命的是负载均衡很难做——同一用户的请求必须一直打回同一个实例。解决办法是让服务无状态把状态全部外部化。最常见的手段是用Redis存会话状态键通常是session:{userId}值是一个对象包含消息列表、Agent当前阶段、已调用工具的结果、剩余步数等。每次请求进来编排层从Redis读取状态执行完一步再把新的状态写回去。这里的细节是状态粒度。粒度太粗整个对话历史塞成一个对象更新频繁时Redis网络开销很大粒度太细每次要串行读好几份Key反而变慢。我的经验是把高频变化的部分比如当前step、pending tool call和低频变化的部分比如消息列表分开存或者用Hash结构一个Key下多个Field按需更新。架构图上要明确标出状态读写路径和状态失效策略不然代码写着写着就会变成内存缓存和Redis之间互相打架。3.3 队列与批处理从同步到异步的取舍并非所有AI应用请求都必须实时同步返回。如果你让用户在一个界面里等待Agent跑完五轮工具调用体验大概率是崩溃的。架构上一个经典解法是引入任务队列把重计算和轻响应分离开。可以这样想象同步链路只负责接收用户请求、创建任务、立刻返回一个任务ID然后由后台Worker异步处理Agent循环处理完成后通过WebSocket或轮询通知前端。这种模式特别适合分析报告生成、批量文档审核、自动化工作流这类耗时任务。但在做异步化之前要分清场景。用户和机器人聊天这种强交互场景异步会破坏对话连续性但如果任务本身就要跑几十秒异步几乎是唯一选择。我的取舍原则是预期耗时大于5秒就考虑异步化大于30秒必须异步化需要用户等待且可能排队就上队列加优先级。画架构图时我会在接入层和编排层之间加一个任务分发器再在编排层旁边画一个结果存储这就是异步化的标准画法。3.4 弹性伸缩模型推理的并发控制即便你做好了网关和队列模型本身的并发能力仍然是致命的约束。大模型推理不像普通HTTP接口它有时间很长的占用过程GPU显存和算力有限并发一旦超过阈值排队时间指数上升最终表现为整体服务的P99延迟变得不可接受。这里有三个词大家容易混淆并发请求数、吞吐量和响应时间。模型服务能承载的并发是有限的假设它每秒钟能完整推理4个请求平均耗时2秒并不意味着同时并发8个请求也没问题——因为模型推理是分批的超出的请求会在队列里等待可能从2秒飙到4秒。所以在接入层和模型网关之间一定要有一层并发控制用信号量限制同时发给模型服务的请求数宁可让请求在队列里等也不要把后端打爆。如果你自建模型服务还可以用连续批处理continuous batching和动态批大小来提高吞吐。如果是调用外部API没有这个控制权就只能在网关层做请求合并、多级缓存和主动退避。架构图上要给并发控制器一个独立的位置并写明最大并发数和队列长度这些参数必须经过压测不能拍脑袋。4. 数据流与上下文工程喂给模型的内容决定天花板4.1 上下文窗口是硬约束架构要为它服务大模型的能力边界和上下文窗口强相关。哪怕最新的模型支持超长上下文你也不可能把整个业务数据库都塞进一次请求里。上下文就是AI应用架构中的数据总线什么数据能进入Prompt以什么顺序进入如何控制token预算直接决定了模型输出的质量。在架构设计时我需要一个专门的上下文组装器模块。它负责三件事从外部存储取回会话历史通过RAG检索取回相关知识片段把当前用户意图和候选工具定义拼装成最终发送给模型的Prompt。这个模块要能动态裁剪比如历史太长时自动保留最近的几轮再加一个压缩后的摘要知识片段太多时按相关性排序后只取Top K。很多人忽略的一点是上下文组装器是纯逻辑模块但它必须缓存。模型调用结果、检索结果、Prompt模板的编译结果都可以缓存避免同一份数据反复去做向量检索也避免重复调用模型。画架构图时我会把上下文组装器画在编排层和模型层之间并在它内部标注输入过滤器和输出解析器两个子模块一个防止脏数据进Prompt一个防止非JSON结果崩掉业务解析。4.2 RAG检索增强从参数记忆到外部记忆大模型本身就像一个压缩过的记忆体参数里存了海量知识但它是静态的不知道你最新的产品文档、客户沟通记录和内部政策。RAG检索增强生成就是用外部数据源给模型补充临时记忆让它在回答时能基于最新资料。RAG架构画出来并不复杂离线环节把文档切块、向量化、写入向量库在线环节把用户问题转成向量去向量库召回相关片段再拼进Prompt。但真正考架构经验的是细节。文档切分chunk尤其折磨人切太碎语义不完整切太大召回噪音高。切好后还要做清洗、去重、权限过滤否则模型可能把不该透露的内部信息回答给用户。我建议在数据层里增加一个文档处理管道它不是一个简单的脚本而是一个可重放、可追踪的任务队列。原始文档进来经过去重、切分、向量化、写库每一步都要记录状态这样文档重复上传也能增量更新。检索端也不要只用一个向量相似度可以加上关键词权重、业务过滤条件、时间排序甚至再接一个重排模型做二次精排。这些都叫架构不只是调一个向量库的API。4.3 上下文管理策略截断、压缩与摘要记忆长对话是AI应用最常见的场景但聊着聊着历史越长成本越高响应也越慢模型还可能被遥远的早期信息干扰。架构上最常见的三种策略是截断、压缩和摘要记忆。截断最简单保留最近N轮对话超过的部分直接丢弃。代价是模型可能忘掉开头用户说过的关键需求。压缩是让模型把旧对话改写成更精简的表达保留关键信息的同时降低token占用。摘要记忆更进一步维护一个长期摘要每次对话结束就把新信息合并进摘要下次请求时把摘要放在对话最前面后面跟随最近几轮原始消息。我实际做过的方案是滚动窗口加摘要混合模式系统维护一个全局摘要始终放进Prompt再维护最近十轮原始消息按时间正序排列如果近十轮的信息量和摘要冲突以原始消息为准。这个模式在多数客服、助手类应用里表现相当稳定。而且摘要本身是异步更新的不需要每轮对话都重新生成可以等用户停顿几秒后再触发一次后台摘要更新避免用户等待时间翻倍。4.4 工具调用后的数据回写闭环当AI应用开始调用外部工具数据流就从一个简单的人→模型→人变成了人→模型→工具→模型→人的闭环。工具返回的数据往往不能原样塞进上下文。一个查询金融数据库的工具可能返回几千条记录直接塞进Prompttoken瞬间爆炸且模型会被无关字段干扰。架构上应在工具调用服务和上下文组装器之间加一层结果处理器它的任务是按业务规则裁剪字段只保留模型需要的结果把结构化数据转成自然语言摘要如果结果太多再做一级聚合统计。比如查销售订单不返回300行明细而是返回总订单数、总金额、TOP3客户、同比变化这样的精简摘要。工具调用的另一个坑是幂等与重试。很多外部工具不支持天然幂等你重试一次可能就下了两个订单。AI Agent在工具超时时很容易下意识重试架构上必须给每次工具调用生成一个唯一的traceId并且在调外部接口时把traceId透传过去配合外部系统的幂等键。这个细节不画在架构图上等到线上出了重复扣款再回头补就晚了。5. 从单Agent到多Agent协作架构复杂度的跃迁5.1 单Agent架构的简化模型我们先看看单个Agent的架构是什么样子。画成状态图它就是一个循环初始状态接收用户输入 → 推理阶段决定下一步动作 → 如果动作是调用工具执行工具并返回结果 → 更新上下文 → 重新推理 → 如果动作是生成最终回答结束循环。这个模型能覆盖很多业务比如客服助手、文档问答、代码生成助手。单Agent的关键优势是链路短问题定位简单资源消耗可控。我在项目里有一个原则能用单Agent解决的绝不轻易上多Agent。因为多Agent不是免费的性能升级而是实打实的架构复杂度。但单Agent有一个天然上限一个模型循环里的工具选择、判断条件、状态控制都堆在一起业务规则稍微复杂一点Prompt就变得臃肿模型经常在多个工具之间犹豫甚至把不该调的工具调了。当你发现单个Agent的角色太多任务类型差异太大一个循环已经难以稳定控制时就该考虑拆分。5.2 多Agent协作模式与通信协议多Agent协作本质上是在AI应用里引入了多角色和消息传递。我见过最朴素的做法是让几个Agent函数互相调用最后把结果拼到一个主Prompt里。这种假多Agent做得多了会发现一个严重问题没有统一的Agent间通信协议任务状态、错误处理、超时全部靠参数硬传代码根本不可维护。真正要做多Agent第一步是定义Agent之间的消息结构。我的建议是每条消息至少包含任务ID、源Agent、目标Agent、任务类型、Payload、状态、错误信息、时间戳。目标Agent是可以路由过去的如果采用订阅或事件驱动还要有事件主题。协议定清楚之后Agent之间就不再是函数调用而更像服务之间发送消息这也让日志追踪变得可行。另一个问题是任务分配和结果回收。主管Agent分下去的任务执行Agent完成后结果要按任务ID回收到正确的位置一旦某个子任务失败主管要决定是重试还是换一种路径。这背后是有状态的状态机管理建议放在编排层统一维护不要让每个Agent各自维护我是谁、我该找谁。5.3 编排者-工作者、管道、图谱三种拓扑多Agent协作不是只有一个模式画图时我常用三种拓扑编排者-工作者Orchestrator-Workers一个主导Agent负责分析整体目标、拆分任务、派发给多个工作Agent再收集结果并汇总成最终输出。适合需要拆解多个独立子任务的场景比如写一份行业分析报告可以拆成数据收集、政策解读、竞品分析、图表生成等多个子任务。优点是控制集中劣势是主导Agent可能成为瓶颈如果任务拆得太多编排者自己就乱了。管道PipelineAgent按固定顺序执行前一个的输出是后一个的输入。比如先做意图识别再做实体抽取再生成回复。这种拓扑适合流水线式的固定流程延迟可控但灵活性差无法应对分叉和回溯。图谱Graph把各个Agent节点按条件路由连接起来允许分支、循环、并行而且支持条件判断。LangGraph就是这种思路。它最灵活也最复杂需要单独的运行时和状态管理。拓扑优点缺点适用场景编排者-工作者控制集中、易于审计编排者易成瓶颈、任务拆分难度大子任务相互独立的复杂任务管道简单、延迟低固定流程、难扩展处理步骤固定且顺序确定图谱高度灵活、支持分支循环状态管理复杂、调试门槛高决策路径多且条件多变的业务我用得比较多的组合是管道 图谱主流程用明确的链路但链路在某个关键节点上分叉用图谱的条件路由选出不同分支。纯图谱模式对于大部分中小团队来说维护成本太高容易画得好看落地上却变成一团乱麻。5.4 多Agent场景下的可观测性与容错多Agent系统最怕的是什么不是某个Agent答得不好而是整条链路黑盒。用户说我要退款主管Agent分给客服Agent客服Agent调了订单系统结果订单系统超时客服Agent又尝试了一次最后主管Agent汇总了一个错误的结论说退款已发起。如果没有链路追踪你根本不知道是哪一步出了问题。可观测性在多Agent架构里不是可选项而是基础设施。我给每个Agent调用链都设计一个统一的traceId贯穿用户请求进入、编排器决策、工作Agent执行、工具调用、模型返回的每一个环节。每个环节记录输入输出摘要、token消耗、延迟、状态码。这套东西可以用OpenTelemetry标准做但真正重要的是日志里要有语义化的字段能支持你回答这个Agent当时为什么调用那个工具。容错机制同样要前置。在架构图上我会给每个Agent节点周围画上重试、超时、熔断、降级四道保险。比如子Agent连续失败两次就不要再盲目重试而是让主管Agent换一种表达或换一个工具路径整体链路超时就返回一个预设的兜底回答而不是让用户无限等待。没有这些保险多Agent系统上线后大概率每天都要靠人工背锅。6. 架构落地时的隐藏成本与决策清单6.1 延迟、成本、准确率的三难权衡AI应用架构到最后很多决策都不是能不能做而是值不值得做。在架构评审时我最常抛出的三难问题是延迟低、成本低、准确率高你要哪个答案往往是全都要但现实必须取舍。一个典型场景是RAG检索。多加两路检索、再过一个重排模型准确率大概率上升但延迟会增加200到500毫秒成本也会增加。另一个典型场景是模型选型旗舰模型效果最好但贵轻量模型便宜但复杂推理容易翻车。架构设计可以引入模型路由来缓解简单意图走轻量模型复杂推理走旗舰模型。但模型路由本身也要计算成本你需要一个统计平台来估算不同策略的总体成本。我做得最多的一件事就是对线上请求做标签化分析。把所有请求按业务类型、模型消耗、token数量、响应延迟打上标签定期复盘哪些请求其实不需要那么大模型、哪些检索可以加缓存。架构不是静态图它应该是一个会根据数据持续演化的动态系统。6.2 评测体系没有指标架构就无从迭代很多团队在AI应用架构上折腾了半天最后连效果变好了还是变坏了都说不清。没有评测体系的架构设计就像没有测试的代码重构随时可能倒退。所以我建议在架构设计一开始就搭一套离线评测集。把典型用户问题、期望回答、各类边界场景整理成几十到几百条测试用例每次架构调整后跑一遍评测对比通过率和输出质量。更进一步还要有在线监控统计用户点赞、点踩、对话放弃率、回答被修改率。没有这些指标你真不知道该把成本投入在更复杂的Agent编排还是更优秀的Prompt。在评测集里我特别强调对抗样本。比如用户故意问和知识库无关的问题、给出模棱两可的指令、或者要求模型执行超出权限的动作。这类样本在架构评审时能暴露很多设计缺陷。一个Agent架构如果连对抗样本都过不了上线之后必然被真实用户折磨。6.3 一张架构决策检查清单最后分享一张我常用的架构决策检查清单每做一个AI应用我都会对着过一遍决策点检查问题关键考量接入方式用户请求如何进系统是否有统一API网关认证、限流、审计、幂等模型接入是否通过模型网关统一接多个模型密钥管理、模型路由、降级会话状态状态放在服务内存还是外部存储扩展性、容灾、跨实例一致性上下文管理是否有独立的上下文组装器token预算、历史截断、摘要策略外部记忆是否需要RAG用向量库还是普通数据库数据规模、过滤需求、更新频率Agent编排单Agent够用还是需要多Agent用哪种拓扑任务复杂度、调试成本、可观测性并发控制是否限制了模型层并发有没有队列削峰延迟SLA、API限流、成本容错机制超时、重试、熔断、降级是否都到位错误恢复、用户体验评测监控是否有离线评测集和在线监控效果可度量、回归可发现这张清单不一定覆盖所有业务但至少能帮你把架构图里的空白补齐。每你对着它画一遍通常就能发现一两个之前没考虑到的风险点。我个人的体会是AI应用架构设计最大的难点不是技术选型多酷而是能不能在复杂度和业务价值之间找到平衡。一张架构画得好不好不在于线条多漂亮而在于它能不能让你一眼看出系统的薄弱环节在哪。从模型网关到上下文管理从单Agent到多Agent每一步都是取舍。先把图画清楚再动手写代码这个习惯帮我省过太多了线上救火的时间。
返回列表