1. 一张AI应用架构图,到底在画什么
前阵子帮一个团队做架构评审,对方把一张图投到屏幕上,标题写着"AI应用架构设计"。图里有用户、有一个画着大脑图标的服务、下面接着向量数据库和API网关,看起来该有的都有了。可我问了几个问题之后,大家都沉默了:模型的能力边界在哪一层被兜底?上下文窗口由谁管理?工具调用失败之后,流程是回退还是重试?异常情况下用户看到的是"系统繁忙"还是降级回答?这些,图上一个都看不出来。
这不是个别现象。我见过太多所谓的AI架构图,本质上是把传统微服务架构图里的图标换成了"大模型""向量库""LangChain",连接关系还是那几条线,但AI应用真正的复杂度——状态管理、上下文生命周期、不确定性处理——全被省略了。这就像画一张城市交通图,只画了路网,不画红绿灯、不画事故处理流程、不画公交车调度。图看着完整,真按图施工,第一天下班高峰就得瘫痪。
所以我想换一个角度来讲"图解AI应用架构设计"这件事。不是教你怎么用画图工具画一张漂亮的展示图,而是把架构设计过程中那些必须想清楚、必须画出来的关键决策点,一个一个掰开讲透。你拿去画图也好,拿去写技术方案也好,拿去给团队做对齐也好,都能直接用。
1.1 架构图不是系统拓扑图
先区分一个概念:很多人画的AI应用架构图,其实是"部署拓扑图"。哪个服务部署在哪台机器上,中间走的什么协议,缓存用Redis还是Memcached,这些是运维视角的信息,不是架构设计的核心。
架构设计关注的是另一件事:系统的各个组件分别承担什么职责,它们之间以什么契约协作,数据如何流转,每个环节在什么条件下会发生什么样的行为变化。
放到AI应用里,这句话具体化之后就是:用户输入的请求,从进入系统到返回最终结果,中间经过了哪些环节?每个环节是确定性的逻辑还是模型推理?推理的结果凭什么可信?出错时谁说了算?
举个例子。一个典型的客服问答机器人,最简单的架构可以只画两个框:用户—大模型。真这么做项目,上线第一天就会发现问题:模型偶尔乱说,用户问昨天订单状态,模型编了个"已发货"。于是你开始加知识库检索,变成了用户—检索器—大模型。可是检索出的片段太多超过了上下文限制怎么办?于是你加了一个重排模块。模型答非所问怎么办?你加了一个提示词模板层。模板里的关键信息需要动态填充怎么办?你又加了一个状态管理模块。等到这个系统真的能稳定运行,里面的组件至少是起步阶段的四五倍。
图解的意义,就是把"为什么会有这四五倍的组件"这个过程本身记录下来。每个组件都有它存在的理由——要么响应一个真实的失败案例,要么支撑一个具体的业务约束。架构图的每一根连线,背后都应该有一个"如果这里断了会怎样"的答案。
1.2 可现在大多教你的AI架构,都画错了地方
现在网上一搜"AI应用架构",大量文章一上来就是:第一层应用层,第二层模型层,第三层基础设施层,然后配一张三层金字塔的图。这种图不能说错,但它的抽象层级太高了,高到对实际开发没有任何指导意义。
知道"要有模型层"和知道"模型层里要放一个模型路由网关,并在网关里做供应商故障转移和超时控制"是两种完全不同的信息密度。前者是给投资人看的,后者是给工程师照着干活用的。
做架构设计,图解的颗粒度应该落在可决策、可实现、可验证的层面。一个组件画出来,你要能回答:这个组件在什么代码仓库里?它和上下游之间传什么格式的数据?模型输出不符合预期时,它做什么兜底动作?这些问题的答案,才是架构设计的真正产出物。
本文的讨论,全部围绕这种"可落地颗粒度"展开。下面我会按自己的习惯,先把一个AI应用从整体上拆成几个核心模块,再针对三个最常见的架构决策点做推演,然后分享一些踩坑记录和一套画图方法论。全程不谈空泛的概念,只谈组件、数据流和决策理由。
2. 拆开一个AI应用:五个你必须画清楚的模块
我做过的AI应用项目,从智能客服到内容生成工具,形态差别很大,但把表面那层业务剥掉之后,底下重复出现的模块大致是五类:模型接入层、上下文与记忆层、工具编排层、评测护栏层,以及贯穿始终的可观测性。架构设计的首要工作,就是把这五类模块在图上画清楚,并且明确各自的边界。
2.1 模型接入层:你的系统不该直接绑死某个模型
第一个要画清楚的模块是模型接入层。它的职责不是"调用大模型API"这么简单,而是把上游业务逻辑和具体模型解耦。
我在项目里见过最危险的一种写法,是把OpenAI的API调用直接散落在业务代码的各个角落。业务逻辑里直接拼好系统提示词,调SDK,拿到response.text就往上传给用户。这在你只有一个模型、一个供应商的时候,跑得飞快,看起来一切正常。
问题出在变化发生的时候。可能是成本原因想换成另一个模型,可能是供应商某天接口变得不稳定,也可能是同一个请求在需要长上下文时要用A模型、在需要快速响应时用B模型。这时候你会发现自己要改的不是一两个文件,而是所有调用过模型的业务代码。更麻烦的是,每个地方对超时、重试、错误码的处理方式都不一样,有的地方可能根本没处理。
架构图上的模型接入层,应该是一个独立的网关组件。它对外给上层业务提供统一接口:输入一个请求(包含系统提示词、用户消息、工具定义等),输出一个标准化的响应对象。内部再去处理具体的模型路由、供应商切换、超时重试、格式转换。
提示:这和我们熟悉的数据库访问层、消息队列封装层是同一个思路。变化的源头不止一个,就把变化收敛到一个地方。
2.2 上下文与记忆层:数据流的核心枢纽
第二个模块是上下文与记忆层。这一层负责的是什么?是管理每一次模型调用的输入上下文,以及跨越多次调用、多个会话的记忆。
很多AI应用在一开始只考虑单轮对话:用户问一句,系统答一句,上下文就是用户当前这句话加上系统的提示词模板。但真实业务几乎都是多轮的。用户先说"我要查一下订单",你给了回应,他又说"不看了,帮我退掉",这里的指代关系如果脱离上一轮对话,根本解析不了。于是你需要维护一个会话上下文窗口。
这个上下文窗口里放什么、不放什么,是一个需要刻意设计的架构决策,而不是随手把前面几轮对话拼起来就行。对话历史往往混杂大量噪声:用户输入过一些无关内容、系统回复被后续操作推翻、中间穿插着多轮工具调用记录。如果全部塞进上下文,模型被噪声干扰是一方面,更直接的影响是token消耗膨胀,成本和延迟同时上升。
我在一个客服项目里做过统计,不加处理地累积对话历史,用户的第10轮请求,上下文里光历史记录就占了四五千个token,其中跟当前问题相关的信息经常只剩几百个token。后来我们改成了滑动窗口加关键信息抽取:只保留最近两轮完整对话,更早的内容只抽取结构化的事实(比如用户ID、订单号、退款状态)放进去。
记忆层比上下文层更复杂。它分短期记忆和长期记忆:短期记忆是当前会话里产生的中间状态(比如用户在表单填写过程中的所有字段值和校验状态);长期记忆是跨会话沉淀的用户画像、业务规则、历史偏好,通常存在外部存储里,在必要时被检索出来注入上下文。
画架构图的时候,我习惯把上下文层画成所有业务处理共享的中心枢纽。UI层发来的消息、工具调用的结果、记忆检索的结果,都汇聚到这一层做统一编排,再合成最终的模型输入。一旦中心化,你后续想优化上下文管理、做token压缩、加语义缓存,都有了明确的改造位置。
2.3 工具编排层:从"调API"到"选工具"
第三个模块,我会叫它工具编排层。这是AI应用区别于传统Web应用最明显的地方,也是最容易画混乱的一层。
在传统系统里,一个请求进来,路由到某个Controller,Controller调用一个写死的Service方法,这就是确定的。但在AI Agent类的应用里,系统常常需要由模型来决定下一步调用哪个工具。这就把架构从"确定的执行流"变成了"动态的决策流"。
工具编排层要解决三类问题。
第一,工具的定义与注册。每个可被模型调用的能力(查数据库、发邮件、调第三方API),要用模型能理解的格式描述清楚:功能是什么、参数有哪些、参数格式怎么约定。这个描述质量直接决定模型能不能正确调用,属于工具层的核心资产。
第二,工具调用的执行与结果回收。模型输出一个"我想调用查询订单工具,参数是12345"的动作,系统要把它解析成真正的API调用,拿到结果后再以合适的格式回填给模型。这个环节里,同步调用和异步任务的处理方式不同,失败重试的策略也在这里实现。
第三,工具的筛选与安全边界。给模型挂上十个工具之后,每次请求把所有工具定义都塞进去,token消耗大不说,还会让模型选择困难。工具编排层可以按上下文动态筛选相关工具。同时,哪些工具不允许模型擅自调用(比如"删除生产数据"),必须有硬性限制——不能只靠提示词约束"你别乱删",要在系统层面直接拦截。
2.4 评测与护栏层:上线前必须画的一环
第五个我坚持要画进架构图里的模块,是评测与护栏层。很多人觉得这是测试做的事情,跟架构无关。实际恰恰相反,AI应用的不确定性决定了它必须有专门的架构位置来容纳"评价"和"兜底"逻辑。
先说评价。传统软件上线前要做功能测试,输入输出是确定性的,用例写完就能自动回归。AI应用不一样,同一个输入,模型两次输出可能完全不同。所以架构上需要有一个离线评测模块:维护一批覆盖典型场景的测试用例集,每次更换模型、修改提示词模板、调整RAG参数之后,都跑一遍评测集,用规则或另一个模型来打分判断输出质量是变好还是变差。
再说护栏。护栏解决的是运行时的问题,比如:用户输入涉敏内容,要识别并拦截;模型输出格式不符合结构定义,要检测并修复;回答可能引用了不存在的知识,要加置信度校验。这些东西不能散落在业务代码里东一处西一处,应该作为请求处理链路上的一个独立过滤环节存在。
画图的时候,我习惯把评测护栏层画成一个"围绕主流程"的环状组件。主流程是用户—上下文—模型—输出,环上挂着输入审核、输出校验、成本统计、异常兜底。这样读者一看就明白:这是贯穿全链路的能力,而不是某一个节点的功能。
3. 三个关键架构决策,用图解思维推演一遍
架构图不只是画出来给谁看的,更是用来推演的。我把几个实际项目里反复遇到的决策点拿出来,演示一下怎么用图解的方式想清楚问题。
3.1 同步调用还是异步流式:先看用户的等待模型
这个决策大多数人会后悔。我见过不止一个团队,上线前图省事,用同步HTTP调用模型API,等完整响应生成完再一次性返给前端。产品演示阶段完全没问题,因为演示数据量小、响应快。上线后用户量一大,问题全来了:响应超过5秒用户开始流失,后端线程被长耗时调用占满,整体吞吐上不去。
问题根源在于没有画数据流的时间维度。你在架构图上加一条时间轴去看:一个用户请求从点击到看到第一个文字,中间经过了哪些环节,每个环节的耗时是多少。这样你立刻会发现,模型生成一段长文本可能要花5到10秒,如果等全部生成完再返回,用户体验就是"白屏等十秒"。
解决思路是改用流式响应。前端和后端之间走SSE,后端一边收到模型生成的token一边推送。架构图上的变化是:模型接入层的接口从返回一个完整response,改成返回一个Stream;上游业务的处理逻辑也必须跟着调整,不能等拿到全部结果才开始做后续处理,而是在流式过程中逐段透传。
但流式化往往牵一发动全身。你要想清楚:如果后续环节需要基于完整响应做格式校验或内容过滤,它必须等流结束才能执行,那错误怎么处理?已经推给用户的流式结果要如何撤回?这些异常路径都得在图上画出来,否则架构上埋的雷迟早踩上。
3.2 单Agent还是多Agent:把"对话流"换成"任务流"再判断
第二个高频决策是:一个全能Agent打天下,还是拆成多个专职Agent协作?市面上所有鼓吹"多Agent"的文章都没说清楚一个问题:系统复杂度上升之后,调试难度是指数级增加的。
我的判断方法是回到数据流本身。假设你做一个PPT生成工具的需求:用户在对话框里发一句"帮我做一个关于二季度营收分析的PPT"。单Agent的做法是一个Agent完成所有事:拆分大纲、搜索数据、生成每页内容、排版。多Agent的做法是多个角色协作,各自承担一部分。
当我把两者的任务流画在同一张图上,决策标准立刻变得清晰:主流程明确、信息依赖固定时,单Agent简单可靠;核心工作在多个完全异质的子任务间切换、且需要不同上下文时,拆开更值。
举个例子。我做过一个项目,帮用户根据关键词生成一张配图,再配上文案。这两个子任务分别用到文生图模型和文本模型,调用的工具完全不同,需要的上下文也几乎没有交集。这种情况下,拆成两个Agent,让调度器决定分派给谁,比让一个Agent同时持有两套工具和全部上下文要清晰得多。上下文窗口消耗更低,工具冲突概率更小,某个子任务升级迭代时也互不影响。
反过来,一个简单的"查天气并给出穿衣建议"任务,硬拆成天气Agent和穿衣Agent,只会增加额外的编排成本和失败点。任务流对信息共享的要求那么高,拆完之后每个Agent都缺关键信息,你反而得做一个更重的记忆同步机制。
3.3 RAG放在哪一层:检索结果的位置决定了系统上限
第三个决策点关于RAG(检索增强生成)在架构中的位置。这个点太常被画错了。很多人的第一版架构图是这样的:用户查询进来后,先调向量数据库检索,把结果拼进提示词,再调模型。图上看起来没问题,实际用起来会发现:检索质量上不去。
我碰到的典型情况是,检索出来的文档块和用户问题之间只有字面相似度,没有语义正确性。系统推荐的文档在关键词上高度匹配,但内容根本回答不了用户的问题。问题出在哪里?出在检索环节没有"理解"用户意图的能力。
改进的思路是把RAG拆成两层:先路由,后检索。路由层接收用户的自然语言问题,先判断这个问题属于哪个业务领域、需要查哪种类型的知识库。然后,针对路由结果去执行更精确的检索策略。这一步是基于规则还是用模型,取决于你的成本预算,但架构上的位置一定是在检索之前。
第二个容易被忽略的是检索后的重排。向量检索topK的结果里,前几个不一定是最相关的。架构图里加一个重排器:限制向量库返回更宽的候选范围,用重排模型对候选做细粒度排序,取真正相关的topN喂给生成模型。多付出一次模型调用的成本,换回落地的回答质量,这笔账在很多场景下很划算。
4. 我踩过的架构坑:图解思维为什么没救住我
聊完正确的画法,我反而想说一说那些"图看着没问题、代码写起来翻车"的经历。这些坑比方法论更有借鉴意义。
4.1 提示词散落在业务代码里
第一个坑是提示词管理混乱。项目早期,我们所有提示词模板直接写在业务代码里:拼字符串、做变量替换,一切都很自然。当模板数量从5个涨到50个之后,问题就出来了:产品想调一句话的语气,要去代码里定位对应文件;同一个环节在不同接口里用的提示词出现了细微的版本差异;某些提示词上下文互相耦合,改A模板导致B功能异常。
架构图当时画得再清楚,也挽救不了一个缺失的模块。后来我们补上的方案是搭建一个企业内部提示词管理平台:模板版本化、支持多环境(development/staging/production)、可以灰度对比率生效。业务代码里不再直接写提示词内容,而是引用模板ID加参数映射。
如果你不想一步到位做平台,至少要在架构里划定一个"提示词层"的边界——所有提示词模板必须集中在某几个文件中,绝不允许散落到业务逻辑中。这是架构约束,不能靠代码review时人工提醒。
4.2 没有网关层的裸奔接法
第二个坑是模型接入没有做网关。早期项目为了快,直接封装了一个统一调用类,内部去调用模型API。后来这个"统一调用类"越来越大,融入了越来越多的判断逻辑:这个客户用这个模型,那个功能要用更高配的模型,高峰期限制一下普通用户的调用频率。
直到某天供应商的API出现大规模超时,我们不得不紧急把流量切到另一个模型时,才发现切换根本不是改一个配置项的事:部分历史代码直接依赖原返回结构,新模型返回的字段命名和值域都不一样。那一次切换,维护成本高到我想抽自己。
正确的做法是,架构图上明确画出一层模型网关,它承担的职责包括:
- 把上游对模型的选择抽象成一个逻辑模型名(如"通用对话模型""摘要模型"),上层完全不知道背后是哪个供应商
- 统一处理所有供应商的API鉴权、超时、重试、限流
- 将不同模型的输出格式标准化成一个统一Schema
- 记录每个请求的模型调用明细,成本单独核算
4.3 上下文无脑堆积:成本与延迟双炸
第三个坑来自上下文管理。我们曾经做一个长对话场景,为了让模型"记住所有信息",把所有历史消息、工具调用结果、中间分析都塞进上下文。效果确实好,模型记得很清楚,但代价是:对话进行到中期时,每次请求的输入token已经上万,单个请求的模型处理延迟从2秒飙到了8秒,月度API成本涨了将近一个数量级。
那次之后我彻底养成了一个习惯:在架构图上标注上下文的生命周期。每个数据源在什么阶段被注入上下文、什么时候可以被清除,都要在设计阶段规定好。比如工具调用的中间结果,用完即抛;过去对话中沉淀的结构化事实,可以放到记忆库里,按需检索再注入。上下文是系统的核心资源,它的管理策略值得单独画一张生命周期图。
5. 一套可以照着画的架构草图方法论
讲了这么多,最后给一套我自己实际使用的画图方法论。不说那些玄乎的"架构即代码",只说说怎么从无到有,画出一张能指导开发的架构图。
5.1 从用户旅程反推组件
第一步不要从技术组件出发,从用户旅程出发。把用户使用你的AI应用完成一次任务的完整路径写下来。比如一次"智能合同审查"任务,用户旅程是:上传合同文档—系统识别文档类型—按合同类型抽取关键条款—匹配我方业务规则—生成风险报告—用户查看报告并提出修改。
这个旅程里的每一步,都是一个独立的功能需求。接下来要做的是判断:这一步用确定性程序实现,还是用模型来实现?判断标准是规则是否稳定、异常是否可穷举。合同文档类型识别这种场景,规则很难穷举,用模型更合适;而"关键条款抽取后和业务规则比较"这种步骤,如果业务规则是可枚举的,用确定性代码更可靠。
这样你得到的第一版组件清单,就是围绕用户旅程的实实在在的功能模块,而不是凭空想象的技术栈。
5.2 三视图法:输入、处理、输出
第二步,为每个关键组件画三张视图:输入视图、处理视图、输出视图。这不是形式主义,是为了逼自己确认每个组件的边界。
比如检索模块。输入视图要写清楚:上游传来的是什么?是用户原始问题还是经过路由分类以后的意图?处理视图要写清楚:用什么模型嵌向量、用什么方式做召回、topK是多少、阈值在哪。输出视图要写清楚:返回的是原始文档块、还是带元数据的结构化对象?
这三个视图一旦画完,组件与组件之间的数据契约就定死了。后续并行开发时,上游下游拿着同样的契约做事,对接成本大幅下降。
5.3 给不确定性留出接口
最后一步,我会在图上专门画出"不确定性处理"的组件。传统架构图很少画这个,但AI应用必须画,因为模型的输出本质上是不确定的。
我一般会在图里标注三类不确定性:
- 模型选择正确的工具了吗?如果选错了,系统有什么机制纠正?
- 模型输出的格式符合预期吗?解析失败有没有自动修复/重试链路?
- 模型的答案有事实依据吗?在哪一步做事实校验?
这三种不确定性如果没有在架构图上对应到具体的处理组件,那么它最终一定会在线上以一种随机的方式爆发。
6. 画完之后,还要做的一件事
架构图画完、代码也写完、系统上线跑了一段时间,很多人以为这事就结束了。我自己的看法不一样:架构图最大的价值,是在系统上线之后才开始体现的。
6.1 把架构图变成监控指标
图上的每个模块、每条连线,都应该能对应到一组监控指标。上下文管理模块是否正常,看token消耗分布、上下文截断率;工具编排层是否可靠,看工具调用成功率、失败重试次数;模型接入层是否稳定,看作坊(供应商)超时率和降级触发次数。
当线上出了问题时,你是从监控面板反推回来,而不是从头翻阅架构文档。如果一张架构图在排查问题时帮不上忙,那它就不是设计文档,只是一张贴墙上的装饰画。
6.2 写在最后的小建议
回到标题里的"图解"二字。我认为图解AI应用架构的价值,从来不在于画出多么精致的方框和箭头,而在于迫使你把抽象的技术概念转化为具体的组件边界和数据流,并在这个过程中发现那些藏在角落里的决策问题。
如果你现在正准备设计一个AI应用,我的建议很简单:先别急着打开画图工具。去找一支笔,一张白纸,从用户旅程开始画起。每画一个组件,就问自己一句:"这个组件存在的理由是什么?它和上下游的契约是什么?它失败时会发生什么?"把这三个问题都回答清楚,这张图就真正属于你了。
我至今保留着团队第一张AI应用架构草图的照片。那张图很丑,线条歪歪扭扭,标注里还有一条后来删掉的错误连接的划痕。但每次看到它,我都会想起那个下午我们围绕"上下文到底放哪一层"争论了三个小时的场景——那张草图才是架构设计的真正载体。