1. 为什么AI应用架构不能照搬传统后端
1.1 传统后端与AI应用的核心差异
先说结论:传统后端架构追求的是“确定性”,AI应用架构要解决的是“在不确定性的前提下保证可用性”。过去十年我们熟悉的那套后端设计思路——请求-响应、事务、数据库约束、面向接口编程——在AI应用里依然有用,但多了一个关键变量:模型本身是概率引擎。
传统Web接口的输入输出是可枚举的。你传商品ID和数量,返回订单号,哪怕业务再复杂,状态总是可跟踪的。AI应用完全不同:同一个Prompt,模型可能给出完全不同的回答;你今天部署的模型,明天可能因为供应商升级SDK、调整限流策略、下线某个版本而行为突变。更麻烦的是,模型消费的Token直接和成本挂钩。传统接口几百毫秒返回,压测时每秒几百上千并发都不慌;AI应用一个请求十几秒,中间还穿插多次模型调用和工具调用,瞬间就可能烧掉大量预算。
所以AI应用架构设计的本质,是把不确定性隔离在可控范围内,同时统一管理模型能力、上下文和成本。这不是在传统后端架构上“加一个AI模块”,而是从分层、并发、监控到部署,都需要重新考虑。
1.2 不确定性带来的具体设计约束
这个约束渗透到每一层。
第一,输出格式不稳定。模型即使被要求返回JSON,也有可能夹杂解释文字或输出非法字符。所以架构里必须有“解析-校验-修复重试”这条链路,而不是直接信任模型输出。很多线上事故本质都是“默认模型输出合法”导致的。
第二,上下文窗口有限。大模型的输入窗口虽然越做越大,但依然有上限,而且塞得越多越贵、越慢。架构必须在每次请求前决定:这段对话历史该怎么压缩、截断、摘要、检索,而不是无脑把所有消息都塞给模型。可以类比人脑的工作记忆——你不可能把整本《红楼梦》放在脑子里再回答问题,只能记住情节梗概和关键细节。模型的短期记忆就是上下文窗口,长期记忆就得靠外部存储。
第三,模型供应商是外部依赖。外部API会限流、会故障、会调整计费。你的架构不能假设某个模型永远可用,必须有路由、降级、重试机制。这里要特别提醒:模型供应商的“服务等级协议”和传统云服务不是一个概念,大模型经常出现你完全无法控制的抖动,要在设计初期就给“模型不可用”留好预案。
第四,任务时长。Agent任务不是一次HTTP请求能解决的,它可能包含多轮工具调用、多步推理。传统请求-响应模型承载不了这种长任务,需要引入任务队列、异步执行、状态存储。一个任务从开始到结束可能跨分钟级,客户端和服务器之间怎么保持连接、怎么恢复状态,都需要重新设计。
1.3 架构师面对的新问题清单
我把实际做AI应用时绕不开的问题列一下,你可以当checklist用,看看自己的架构是否已经有答案:
- 多个模型如何统一接入?切换供应商时接口要改多少?
- 同一个问题能不能命中缓存?语义缓存怎么设计?
- 用户在对话里的历史信息,存在哪里?用向量库还是Redis还是数据库?
- Agent调用工具失败后怎么办?重试还是放弃?如何保证不重复扣费?
- 模型输出格式不对时怎么处理?重试一次还是直接交给用户?
- 大量用户在同一时段发起任务,怎么限流而不影响核心体验?
- 每次调用的Token归到哪个用户、哪个场景?成本怎么分摊?
- 模型升级后行为变化,如何让架构不受波及?
- 一个Agent任务被中断,如何恢复?中间状态存在哪里?
这些问题不是某个中间件能单独解决的,需要从整体架构层面回答。这也是“AI应用架构设计”这个领域和普通后端架构分道扬镳的地方。你如果发现自己在代码里到处处理这些问题,说明该停下来做一次系统性的分层了。
2. 核心架构拆解:从模型接入到应用编排的分层设计
看别人的架构方案时,我的习惯是先找它的分层边界。AI应用架构经过这一年多的发展,基本收敛出四个清晰层次:应用接入层、应用编排层、推理调度层、模型接入层。下面按从外到内的顺序拆。
2.1 模型接入层:统一封装多个大模型供应商
模型接入层是离模型最近的一层。它的目标非常简单:上层只和你的SDK打交道,不直接依赖某个供应商的SDK。这一层暴露的方法通常只有几个:
- chat(messages, options)
- embed(texts)
- tool_call(messages, tools)
- file_parse(content)
对外部的差异统一屏蔽。比如OpenAI的消息结构和Anthropic的格式不完全一致,模型公司A的tool call字段名是function_call,模型公司B叫tool_calls,接入层要把这些差异消化掉。另一个很重要的职责是统一错误码:把上游的限流错误、超时错误、鉴权错误、余额不足错误,映射成自己系统内部的错误类型,上层才能做统一的容错处理。
内部要做的事包括:兼容不同供应商的接口差异、统一重试策略、统一Token计数。我见过很多项目在早期直接调用某个大模型SDK,等想换成更便宜或性能更好的模型时,发现代码里散落了大量厂商细节,改起来牵一发动全身。模型接入层就是为了避免这个局面。有很多企业级框架(如LangChain等)也提供了类似的抽象,但我个人更倾向于自己做一层轻封装——框架更新频繁、依赖重,而且很多时候你只需要其中20%的能力。
实测经验:接入层最好在构建请求时就把Token预算算好,超过预算直接拒绝或截断,不要等模型那边报错。还要注意不同模型的temperature、max_tokens等参数语义不完全一致,最好在接入层做参数映射,而不是交给业务代码。
2.2 推理调度层:模型路由、上下文管理、语义缓存
如果说接入层是“翻译官”,调度层就是“指挥官”。它负责三层核心能力。
第一,模型路由。简单指令任务(如分类、改写)用小模型,复杂推理任务(如写代码、多步分析)用大模型。路由规则可以放在配置中心,例如按意图分类、按Token预算、按用户等级。实现时要注意:路由判定要快,不能为了路由多等一次模型调用,否则延迟得不偿失。现在的做法通常是用一个小模型或规则引擎做意图识别,把请求判断个大概方向,然后再决定调用哪个大模型。这一步能明显省钱,因为小模型的成本可能只有大模型的五分之一到十分之一。
第二,上下文管理。传统后端没有这个字段,AI应用里却最致命。每次对话都携带全部历史是懒人做法,既贵又慢。调度层要负责把消息列表压缩成符合模型窗口的形态。常用策略包括:滑动窗口、重要性评分、摘要记忆、向量库检索。后面第3节详细展开。这里只强调一点:上下文管理是架构的“核心决策”,不是一处改完就完,它需要和路由策略联动。比如你准备调用小模型时,可能需要把上下文压得更短,因为小模型的窗口通常更小。
第三,语义缓存。传统缓存按key精确命中,AI场景里“语义接近”的请求也可以复用。实现上需要用embedding把用户请求向量化,再在向量库做相似度检索,命中后直接用缓存结果,可以大幅节省成本。这里要注意相似度阈值要压准,太松会答非所问,太紧命中率低。我的经验是0.90到0.95之间起步,结合业务场景调参。缓存还要设置过期时间——不是所有知识都永久有效,比如天气、新闻、时效性强的信息,缓存的意义就不大,反而会输出过时信息。
2.3 应用编排层:Agent运行时与工作流引擎
再往上就是和业务强相关的编排层。这里有两种形态。
第一种是Agent运行时。系统让模型自己决定调用什么工具、按什么顺序执行。典型结构是一个循环:感知当前状态 -> 模型决定下一步动作 -> 执行工具 -> 观察结果 -> 循环直到完成。这个循环需要一个运行时容器来承载状态、控制步数上限、处理异常。在没有现成框架时,可以用一个状态机实现,把每个步骤的输入输出都记录在案,方便后面调试和审计。
第二种是工作流引擎。如果业务路径相对固定,比如“先抽取信息,再查知识库,再生成回复”,就不需要模型天马行空编排,用工作流引擎把步骤固定下来反而更稳。工作流的好处是每一步都是人肉可控的,出问题时你知道卡在哪个环节。我建议把工作流和自由Agent同时保留,简单业务走工作流,复杂业务走Agent。还有一个折中模式:用工作流定义主流程,在主流程的某些节点上允许Agent自主选择工具或策略。这种“半自由半受控”的形态,在落地时比纯自由Agent稳定得多。
编排层还需要提供统一的任务模型:每个任务有生命周期(排队、执行、等待工具、成功、失败、超时),状态存哪里、并发怎么控制,都是这一层的事。任务状态适合放到Redis或数据库中,配合异步队列做并发控制,而不是交给网关层处理。
2.4 一个最小可用架构的文字化图解
我不画复杂架构图,给你一个可以抄的分层示意:
[接入层] Web / App / 内部系统 / 消息机器人 | [编排层] Agent运行时 / 工作流引擎 / 多Agent调度器 | [调度层] 模型路由 / 上下文管理 / 语义缓存 / Prompt模板库 | [接入层] 统一模型SDK(超时/重试/限流/Token计量) | [模型服务] OpenAI / Claude / 国产大模型 / 开源私有化模型 [旁路依赖] 向量数据库(记忆/检索) / 任务队列(长任务) / 工具服务(内部API) / 可观测平台这个结构里的每一条竖线都是模块边界,也是未来的扩展点。模型接入层和调度层可以复用到所有业务场景;编排层按业务定制;接入层的形态最灵活。只要守住分层边界,替换模型、调整Prompt、修改工作流都不会波及其他部分。很多人一上来就把全部逻辑堆在一个“AI网关”里,短期看省事,长期看所有变更都挤在一起,每一步都会让你心惊胆战。
3. 多Agent协作架构的设计支点:上下文、记忆与工具调用
关于AI Agent的问题非常多,我单独开一节讲多Agent协作架构,因为这是当前AI应用架构里最容易被忽视又最容易翻车的部分。
3.1 单Agent还是多Agent
先泼一盆冷水:不是所有系统都应该上多Agent。单Agent加一个强大的工具集能解决大多数问题。多Agent的本质是“分工”——把一个大目标拆成子任务,让不同Agent各管一段,最后汇总。好处是每个Agent的提示词更聚焦、上下文更短、可靠性更高;代价是通信开销、状态同步和失败传播。
我的判断标准是:如果任务可以被自然拆成不同专业领域,比如“分析数据”和“生成报告”是两个独立能力,并且子任务之间边界清晰,才值得多Agent。如果只是复杂但线性的流程,工作流引擎比多Agent更合适。举个例子:一个客服机器人,检索订单、生成回答、安抚情绪,这些步骤有依赖关系,放一个Agent里串行执行就行;而一个“行业研究助手”,需要同时搜政策、看财报、读新闻、做交叉验证,这种并行任务才需要多个Agent各管一条线。
还要考虑团队维护成本。每个Agent本质上都是一套独立的Prompt加工具集,意味着需要单独调优、单独测试。Agent数量一多,你管理的就不再是代码,而是“一群性格各异的小人”。没有足够的工程投入,不要轻易上多Agent。
3.2 上下文与记忆:多Agent场景下的头号难点
多Agent协作时,每个Agent看到什么上下文,直接决定输出质量。这里要区分四类记忆:
- 会话短期记忆:本次任务中的对话轮次。适合放在运行时变量里,任务结束就释放。
- 工作记忆:Agent执行过程中的中间状态,例如已经查过的数据、已经生成的草稿。适合用结构化对象存储,每个Agent可以从共享状态中取出需要的部分。
- 长期记忆:用户的历史偏好、领域知识。需要持久化,通常用向量库或关系数据库。
- 全局记忆:多个Agent之间的共享结论。例如研究任务中“已经确认的事实”。需要写入一个共享黑板或事件流,避免每个Agent重复查询。
实际工程里,我建议把“全局记忆”做成一个独立的存储服务,而不是让Agent拿着整个上下文副本到处传。这样既省Token,也能避免并发写冲突。所谓“黑板模式”在这里很适用:多个Agent往一块公共黑板上写信息、读信息,各取所需。架构上可以是一个Redis实例、一个数据库表,或者一个事件流,关键是明确这个黑板的读写权限和数据结构,否则几个Agent同时更新同一字段,会出现互相覆盖。
3.3 工具调用的架构实现:从自定义协议到MCP
工具调用是Agent能力的放大器。架构上,工具必须被抽象成“可以被模型以JSON方式调用”的接口。你需要为每个工具提供:功能描述、入参schema、出参schema、错误信息。模型读了这些定义后,生成一次函数调用请求,运行时校验参数、执行工具、返回结构化结果。
这里要提一下MCP(Model Context Protocol)。它解决的问题是:如果每个工具都要自己定义一套协议,每接一个新模型就要重写一次工具适配器,成本极高。MCP统一了模型与工具之间的交互格式,相当于给工具调用装了一个标准插座。现在很多主流模型平台和工具生态都在往这个方向靠,新项目值得从一开始就按类似思路设计工具接入层,至少把工具定义和协议保持中立,不要和某个具体框架耦合。
我的经验是:工具返回结果要给模型留“旁白”字段。比如一个订单查询工具,除了返回数据,最好附带一句人类可读的摘要“用户近三个月消费总额是xx,同比增长xx%”,模型直接引用摘要,比让它从原始JSON里自己找结论更稳。这个细节看似简单,实际能显著减少模型瞎猜的概率。
3.4 Agent之间的通信协议设计
多Agent协作最少不了通信问题。直接用一个共享内存字典是最容易想到的方案,但在分布式场景下会变成单点或竞态地狱。更稳的模式是事件驱动:每个Agent订阅自己关心的主题,发布事件时带上结构化负载。例如:检索Agent完成后发布“retrieval.done”事件,生成Agent订阅该事件获取结果。
通信协议要定义清楚负载格式、消息幂等性和过期时间。Agent可能因为超时或异常重复发布结果,接收方要做去重。事件流可以用Redis Stream或消息队列承载,轻量场景用数据库任务表轮询也能跑,重点是别把Agent之间的通信和业务数据库混在一起。要有一套统一的事件Schema注册中心,否则每个Agent各定义各的,线上排查时你会非常痛苦。
另外一个关键设计是步数上限。无论Agent多想继续执行,架构上要设硬上限,比如单个任务最多30步、最长执行5分钟。没有硬上限的Agent系统,迟早会在某个奇怪输入下陷入死循环。这个上限本身要可配置,不同业务场景要求不一样。比如一个代码生成Agent可能需要更多步来修复编译错误,而一个简单问答Agent可能5步就够。步数上限不只是保护系统资源,也是控制成本的手段——每多跑一步,就多消耗一次Token。
4. 并发场景下的架构治理:限流、降级、超时与成本控制
热词里有人问“AI Agent怎么扛并发”,我把这个问题的答案拆成四块:并发模型、限流、降级、成本规划。这部分是AI应用架构里和传统后端差异最大、也最容易出事故的地方。
4.1 AI应用并发为什么棘手
传统后端一个请求通常几十毫秒到几百毫秒返回,线程池模型够用。AI应用一个请求可能十几秒到几十秒,期间还可能发起多次模型调用和工具调用。如果你用同步线程去扛,线程池很快被打满,后续请求全部排队,用户体验变成“转圈圈”。更麻烦的是,模型供应商的API有并发限制(比如每分钟请求数、每分钟Token数),你内部再快,出口被限住也是白搭。这有点像水管出口细,你家里面再大的水压,外面还是会慢慢滴。
所以并发设计要从两端入手:对外,用请求队列接纳大量用户请求,让任务慢慢消耗模型额度;对内,按模型供应商的配额做流量整形,避免突发流量打爆上游。整体上AI应用更适合用“异步任务+流式输出”的模式,而不是同步等待结果。用户端收到SSE流式输出后,延迟感会明显降低,哪怕模型推理要用20秒,用户也在持续看到内容变化,而不是盯着空白页面等。
4.2 限流:API层与业务层的双层保护
我常用的方案是双层限流。第一层在API网关,按用户/租户维度限流,例如每个用户每秒最多发起2个新任务,防止单个用户刷爆额度。第二层在模型接入层,按模型供应商的配额做令牌桶限流,比如每分钟最多调用1000次,或每分钟最多消耗100万Token。
第二层是很多人会漏的。你的网关限了用户流量,但模型接入层没有针对上游配额的整形,一旦某个爆款活动推高流量,先挂的往往是供应商接口,报429之后你的服务反而被重试风暴拖垮。实现时可以用Redis做分布式令牌桶,把每个模型的配额独立维护。注意令牌桶的容量和速率要分别配置,容量应对突发,速率保证长期稳定。
限流后返回什么也很关键。对用户友好的做法不是直接拒绝,而是返回“当前请求量过大,请稍后再试”,并提示可以排队。对内部系统则可以返回一个特定的错误码,让上层决定是降级还是延迟重试。这里要谨慎对待“重试风暴”:一旦上游限流,下游大量重试只会加重拥堵。使用指数退避加抖动(jitter)是标准做法,不要使用固定间隔的激进重试。
4.3 超时与降级:模型不可用时的容错设计
AI应用的服务降级链路比传统后端多好几级。我按模型调用的失败场景排列:
- 模型A超时或不可用:路由到模型B,比如从大模型降到中小模型。
- 全部模型不可用:尝试语义缓存命中,返回最近相似问题的答案。
- 缓存也没有:返回兜底话术,同时记录告警,让用户知道“暂时无法回答”而不是死循环。
- 工具调用失败:区分可重试错误(网络超时、临时故障)和不可重试错误(参数错误、权限不足)。可重试的做指数退避重试,最多2到3次;不可重试的直接回传错误给模型,让模型调整策略。
超时值参考:单次模型调用15到30秒比较合理,复杂Agent任务整体超时建议120到180秒,但用户端看到的是流式输出,不会觉得离线。如果采用同步HTTP暴露接口,建议把超时和任务队列解耦,不要让客户端一直挂着等。可以用“提交任务-绑定任务ID-异步轮询/WebSocket推送结果”的模式,这更符合AI应用的执行特征。
4.4 Token怎么纳入容量规划
这是AI应用架构独有的问题。容量规划不能只看QPS,要把Token消耗作为一等公民。我举一个实际估算例子:
假设一个问答任务平均消耗:输入2000 tokens,输出800 tokens。单用户平均并发2个任务,业务高峰期在线用户100人,其中20%同时活跃。
峰值任务速率 = 100 × 20% × 2 = 40个任务/分钟。
每分钟Token消耗 = 40 × (2000 + 800) = 112,000 tokens/分钟。
如果按小时算就是672万tokens。再乘你用的模型单价,就能算出这个功能一个月成本。然后你可以在模型接入层设置Token预算告警:单日消耗超过预估120%就通知,超过150%自动降级到便宜模型。没有这套计量,等月底账单出来才发现成本失控,就晚了。
Token计量的粒度至少要细到“场景”级别,比如“智能客服问答”“文档总结”“代码生成助手”各自消耗多少Token。这样才能知道哪个功能是烧钱大户。有些场景实际使用频率低、输出长,单价却很高,优化时优先处理这些高消耗场景。
5. 可观测性设计:链路追踪、Token消耗与输出质量评估
AI应用比传统后端更难排查问题,因为“为什么模型这么回答”是个黑盒。可观测性设计的目标就是把这个黑盒拆成可追踪的阶段。你不可能让每一个模型输出都解释得清,但你可以记录每个阶段的输入输出和关键指标,让复盘有据可查。
5.1 需要观测哪些独特指标
传统监控看延迟、错误率、饱和度,AI应用还要加几项:
- 模型调用次数与Token消耗:单任务、单用户的消耗。
- 缓存命中率:语义缓存命中率高说明大量重复问题,架构效果好且成本低。
- 工具调用成功率:Agent的核心风险点。
- 重试次数与失败原因:模型超时、限流、输出校验失败要分类。
- 输出质量分:通过自动评估或用户反馈得到。
其中工具调用成功率是Agent系统的命门。一个Agent任务里,工具调用失败可能导致后续步骤完全跑偏。不要只统计“调用失败/成功”,还要记录失败发生在哪个工具、错误类型是什么,这样才能推动工具服务方优化。
5.2 链路追踪:把Prompt、模型调用和工具调用串起来
最简单的做法是给每个业务请求生成一个trace_id,然后在所有关键节点埋点。每个span至少记录:阶段名称(如“模型调用:claude-3.5-sonnet”)、输入Token数、输出Token数、耗时、状态。关键trace_id要跟随用户在对话中的每次请求,这样多个轮次也可以串成一条完整链路。
埋点数据建议统一落一份到日志系统,同时抽样聚合到监控面板。不要把所有Trace都做完整采样,成本高且噪音大;我一般对线上请求做10%到20%抽样,对异常请求(有告警的、输出结构反复解析失败的)全量采样。全量采样不仅成本高,而且排障时信息过载,反而妨碍定位。关键是要有“按trace_id即时检索”的能力,这样出现线上问题时能快速拉出完整链路。可以用OpenTelemetry等开源工具做基础采集,再配合自己的业务埋点。
5.3 Token消耗监控与成本归因
Token监控要做到“可归因”:从哪个产品、哪个功能、哪个用户、哪个模型消耗了多少Token。成本归因的意义不只是算账,更重要的是告诉你优化方向。比如发现某个Agent的Prompt模板特别长、命中率低,就可以针对性地缩短模板或加缓存。很多团队优化成本时盲人摸象,就是因为缺乏Token维度的可视化。
预算告警按天和按月设两级。我习惯在模型接入层统一计量,而不是在业务代码里各处手动上报,避免漏统计。不同模型的价格差异极大,计量时要带上模型名,成本汇聚时才不会失真。
还有一个容易被忽略的点:输入Token和输出Token的计费价格不同,很多模型厂商输出Token比输入Token贵好几倍。所以监控面板上要分开看“输入Token消耗”和“输出Token消耗”,优化策略也不同。输入侧靠缓存和上下文压缩来省,输出侧靠控制生成长度和路由到便宜模型来压。
5.4 输出质量与安全策略的评估机制
架构层面要留出一层“输出评估”。最简单的方式是用另一个模型评估当前输出(AI-as-Judge):给评估模型几个维度——相关性、格式合规、幻觉程度、安全性,让它返回分数。这个分数用于灰度发布和模型路由。如果新版模型的输出分明显低于旧版,可以考虑自动回滚路由。
安全方面,无论什么应用,接入层都要设置内容安全过滤与格式校验。我自己在架构里会放一道“输出验证器”,规则包括:必须用UTF-8、必须是合法JSON或Markdown片段、禁止包含不符合要求的敏感规则命中。这属于纯工程层面的防线,和业务无关。安全策略不能只靠模型自身,要在应用层做可配置的过滤规则和人工复核入口。对于一个面向用户的AI产品来说,输出验证器是最后一道保险,宁可在这里多花一点时间,也不要让明显有问题的内容流到用户面前。
6. 落地AI应用架构时最容易踩的坑
最后分享几个我在真实项目里踩过的坑,也算是给前面那些理论补上一些“血泪教训”。这些都是常规文档里不会写的细节,但实际影响非常大。
6.1 坑一:把Prompt和代码写死在一起
项目早期,Prompt字符串直接写在业务代码里,改一个字都要发版。后来Prompt越调越多,不同场景的Prompt散落在各个服务里,版本根本没法定。建议把Prompt模板放到独立的配置中心,按场景和版本管理,代码里只引用模板ID和参数。这样调整Prompt可以走配置发布流程,不需要重新部署应用,且回滚也是秒级。
还要注意Prompt模板的“可测试性”。我见过太多团队调整了一个Prompt后,效果变差了却不知道是哪里引起的。解决方案是为每个Prompt模板建立对应的评测集,改动后跑一遍回归。即使只是加了一句“请用简洁的语言回答”,也可能会对输出风格产生很大影响。没有评测集的Prompt修改,等于在盲飞。
6.2 坑二:忽略模型输出的非结构化问题
我见过不止一次,系统假设模型一定会返回合法JSON,结果某一天模型升级后输出里多了一行说明文字,整个解析链路全挂。架构上一定要有“解析-校验-修复重试”三步:先尝试标准解析,失败就用修复提示让模型重新输出一次,再失败才放弃。这条链路比任何参数调优都值钱。
修复重试也有很多细节。修复提示要包含具体的错误信息和当前输出片段,让模型知道哪里错了。比如“你的输出没有通过JSON格式校验,错误是:Unexpected token,请只输出合法JSON”,比笼统的“请重新输出”有效得多。重试次数建议1到2次就够,再多既费钱效率也低。
6.3 坑三:工具调用没有重试和幂等
Agent调用支付、发消息、改状态这类工具时,如果超时无响应,直接重试可能导致重复执行。要求所有工具开发者实现幂等键(idempotency key),Agent运行时在重试时带上同一个幂等键。这个约束必须在工具接入层强制,不能指望业务自觉。比如一个“发送邮件”工具,如果第一次调用实际已经发出去,但响应超时了,你重试一次用户就会收到两封邮件。解决方法是每次任务开始时生成一个幂等键,工具服务端保存已处理过的幂等键,重复请求直接返回上次结果。
6.4 坑四:并发预估完全照搬传统Web
传统Web架构的并发预估通常基于页面点击量,AI应用则要看“任务复杂度”和“Token预算”。同一批用户,任务简单和任务复杂时的系统压力可能差两个数量级。压测时也要用真实的Prompt和工具调用组合,不要用空Prompt去压模型接入层,结果完全失真。
我见过一个项目根据用户量预估出每秒20个并发,结果上线后一个复杂的文档分析任务把每次请求的Token消耗拉高了几十倍,模型接入层的成本直接翻了四倍。后来他们才在架构里加入“任务复杂度预估”模块,在路由时根据任务类型选择不同的模型和额度策略,才把成本压回来。
6.5 架构收敛的优先级
做AI应用架构没必要一口气上齐所有组件。我的落地顺序建议是:第一,先把模型接入层做出来,所有模型调用走统一入口;第二,把上下文管理和语义缓存加上,这一步能立刻降低成本和延迟;第三,做链路追踪和Token计量;第四,再上多Agent、工作流引擎这些上游编排能力。先把地基打好,后面的扩展都是自然生长,不用推倒重来。
有些团队一上来就引入一个庞大的Agent框架,结果发现框架本身难以理解、排查问题困难,反而阻碍了业务迭代。框架能用,但不要贪大求全。从一个最小的“模型调用入口加路由”开始,跑通一条真实业务链路,再逐步添加组件,这样每一步的风险都可控。
我自己做AI应用架构最大的体会是:AI应用架构设计不是选一个漂亮的技术栈,而是围绕“不确定性、上下文、成本”这三个主题不断做取舍。你把这三件事在架构层面安排明白了,模型换哪个、Agent怎么搭,都不是问题。模型更新换代很快,但架构的底层逻辑——怎么隔离不确定性、怎么管理上下文、怎么控制成本——会在很长一段时间内约束着整个系统的上限。