1. 从一个真实痛点说起:为什么AI应用不能只靠模型
做了几年AI应用落地,我最大的体会是:绝大多数翻车项目,翻的都不是模型本身,而是模型外围的那套工程架构。
很多团队拿到一个很强的模型,比如GPT-4、Claude、国产的Qwen、DeepSeek,第一反应是"直接调API不就行了"。结果一上线就发现问题接踵而至——用户问一个问题,上下文稍微长一点,费用狂飙;模型胡编乱造,没法追溯;多个业务方都要接模型,每个人的调用方式五花八门,根本没法统一管理;更别提并发一上来,超时、限流、熔断全乱套。这时候大家才意识到:AI应用架构设计不是把模型包一层HTTP接口那么简单,它是一整套围绕"不确定的模型能力"构建确定性系统的工程活。
这篇文章我想用图解的方式,把我自己搭建AI应用时梳理出来的架构分层、关键模块、实操细节和踩坑经验,完整地拆开讲一遍。内容不是我凭空想的,而是从几个真实项目里沉淀出来的——有面向内部员工的智能问答机器人,有面向客户的售前售后客服助手,也有多Agent协作的自动化工作流平台。适合正在做AI应用落地、想从"能跑通demo"走向"能扛住生产流量"的工程师和技术负责人参考。
为了让你读起来不迷糊,我先给一个总览式的结论:一个能上生产的AI应用架构,至少需要四个层次——接入层、能力层、服务层、数据层。下面我会逐一图解每个层次到底承担什么职责、为什么必须存在、以及不同场景下怎么取舍。
2. 图解AI应用架构的核心分层
2.1 整体架构一图流
先把全景图画出来,后面所有细节都围着这张图展开。
┌─────────────────────────────────────────────┐ │ 接入层:API Gateway / Web / 客户端 SDK │ │ 职责:鉴权、限流、路由、请求校验 │ └─────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────┐ │ 服务层:业务编排 / Agent运行时 │ │ 职责:任务拆解、工具调度、状态管理、结果聚合 │ └─────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────┐ │ 能力层:模型网关 / 提示词引擎 / 工具注册中心 │ │ 职责:模型路由、上下文组装、函数调用、记忆读写 │ └─────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────┐ │ 数据层:向量库 / 缓存 / 日志 / 业务数据库 │ │ 职责:知识检索、运行记录、会话持久化 │ └─────────────────────────────────────────────┘这个分层不是拍脑袋定的,它的核心逻辑是让每一层只干一件事,层与层之间通过明确的接口协议通信。为什么要这么做?因为AI应用的不确定性主要来自模型层,我们不能让这种不确定性顺着代码一路污染到业务层。把模型相关的所有变化收敛在能力层,业务层才能稳定地做编排和控制。
2.2 接入层:AI应用的"门卫"
接入层是你整个AI系统对外的第一道关口。很多人觉得这不就是一个nginx吗?实际上,AI应用的接入层比传统API网关多几个独特职责。
第一个是模型路由前置。用户请求进来之后,接入层需要根据业务类型、用户等级、费用预算,把请求路由到不同的模型。比如普通问答走成本低的模型,复杂推理走能力强的模型。这个动作放在接入层做,是因为它需要在所有业务逻辑之前完成分流,避免每个业务方自己对接模型、选择模型,造成管理混乱。
第二个是流式协议适配。大模型几乎所有响应都是流式的(SSE/WebSocket),接入层要把这种流式能力封装成统一的协议暴露给前端。不然前端要自己处理各种流式解析、断线重连、超时判断,那画面太美我不敢看。
我建议在接入层统一处理以下这些问题,做成一个公共组件:
- 鉴权与配额控制:每个调用方有独立的API Key或Token,配额实时检查。
- 限流与熔断:对每个模型实例做独立的令牌桶限流,模型服务不稳定时快速熔断返回兜底文案。
- 流式响应标准化:统一SSE的字段格式,包含事件类型、增量内容、元数据(token消耗、延迟)。
- 请求上下文注入:把用户ID、租户ID、请求追踪ID自动加到上下文里,方便后续链路追踪。
这里有个很现实的坑:很多团队把限流做成全局的,结果一个业务方的突发流量把另一个业务方的请求全挤掉了。我后来改成按租户+按模型的双维度限流,才真正解决了隔离问题。
2.3 能力层:把模型的"智商"变成可控的服务
能力层是整个架构的灵魂,也是"图解"的重点。它承担三件事:模型网关、提示词引擎、工具注册中心。
模型网关不是一个新鲜概念,本质上就是"模型领域的数据库中间件"。它屏蔽了底层不同模型的API差异(GPT的格式和Qwen的格式不一样,几百个参数配置也完全不同),对外提供统一接口。同时它负责模型实例的生命周期管理——哪些模型实例需要预热、哪些可以冷启动、哪些需要自动扩容,都在这一层处理。
我强调一点:模型网关一定要支持"模型灰度"和"回滚"。我做过一个案例,某个模型发版后有轻微的回归,业务方没发现,结果线上对话质量悄悄下降了三天。后来加了模型灰度机制:每次新模型版本先切5%的流量,跑回归测试和对比评测,没问题再逐步放大。这比任何评测集都管用。
提示词引擎是我觉得最被低估的一个组件。很多团队把提示词写成字符串硬编码在代码里,改一句提示词就得发一次版,评分标准一变就要走发布流程,效率极低。我的做法是把提示词模板化、版本化管理,存到配置中心或专门的提示词管理平台里,运行时不写死在代码中。
提示词引擎的核心接口是:输入一堆"变量"(用户的原始问题、检索到的知识片段、对话历史、业务上下文),输出一条组装好的、完整的大模型请求消息。这个过程中还要处理:上下文压缩、系统提示词注入、few-shot示例注入、安全策略注入。我后面会专门讲上下文管理,这里先按下不表。
工具注册中心是AI Agent架构里最关键的部分。大模型本身只能"聊天",要让它能执行实际操作(查数据库、调接口、发邮件、写文档),就需要把一组工具用明确的Schema描述出来,注册给模型。工具注册中心负责管理这些工具的定义、版本、权限和调用日志。
工具Schema的写法有一套讲究,简单来说要包含:
- 工具的名称和一句话描述(模型靠描述决定什么时候用这个工具)
- 参数列表,每个参数的类型、必填性、描述
- 调用地址和认证方式
- 超时设置和错误码定义
这里有个很经典的教训:工具描述写得差,模型就乱调工具。比如一个"getUserInfo"工具,如果你描述成"获取用户信息",模型在用户问"我订单到哪了"的时候也可能会调它,浪费一次调用还拿不到有用结果。我把描述改成"获取用户基本信息(姓名、注册时间、等级),不含订单物流信息",模型调用准确率立刻提升了一截。
3. 落地方案:一个通用AI应用的架构设计
3.1 基础组件选型思路
选型这个问题,没有标准答案,但我可以分享一套经过验证的组合。我用Java和Python混合栈,举一个典型的技术选型清单:
| 层级 | 组件 | 选择理由 |
|---|---|---|
| 接入层 | Spring Cloud Gateway / APISIX | 流式转发成熟,灰度路由便利 |
| 服务层 | Spring Boot + 状态机 | 业务编排灵活,Agent运行时可控 |
| 能力层 | 自研模型网关 + LangChain4j(部分场景) | 模型路由可控,避免被框架绑架 |
| 数据层 | PostgreSQL + pgvector / Milvus | 兼顾业务数据与向量检索 |
| 缓存 | Redis | 会话上下文缓存、速率限制 |
| 可观测 | OpenTelemetry + Grafana | 全链路追踪,token消耗监控关键 |
这里要说明一下,选LangChain这类框架我是持保守态度的。框架能帮你快速搭出原型,但也容易让你失去对底层细节的控制。我采取的是"框架只用在工具调用和Prompt组装这种标准化环节,核心的模型网关、状态管理、链路追踪全部自研"。原因无他——AI应用还处于快速变化期,公共框架的抽象层往往跟不上需求变化,一旦自定义需求变多,反而被框架束缚。
3.2 请求链路的数据流设计
我用一次用户提问"帮我把上个月的销售数据整理成Excel发给我"来走一遍完整链路。
用户在Web前端输入这句话,接入层校验通过后,请求来到服务层。服务层的Agent运行时拿到这个任务,开始做意图识别和任务拆解——它把"整理销售数据"和"发邮件"拆成两个子任务。然后进入能力层:Agent运行时先调用模型网关,把用户的原始请求和系统提示词组装好,发给大模型。大模型根据工具注册中心里的工具清单,决定需要调用"querySalesData"工具和"sendEmail"工具,并返回结构化的工具调用指令。
关键点来了:Agent运行时并不是直接把所有工具的结果一股脑塞回模型,而是要人工把每一步的中间结果组装成语义清晰的观察结果,再放回上下文。我见过很多失败案例,都是因为工具返回的原始JSON直接丢给模型,模型根本看不懂那堆字段。正确的做法是把原始结果翻译成"自然语言描述",比如把一张销售明细表翻译成"2024年6月华东区销售额为530万元,环比增长12%",这样模型才能准确理解并编排下一步动作。
在数据层层面,这个请求会产生几类数据:会话历史(用户之前问过什么)、检索到的知识片段(如果涉及企业知识库)、工具调用的中间日志、token消耗记录。这些数据要分门别类存储,其中会话历史放Redis做快速读写,工具调用日志和token记录放日志系统用于后续分析和计费,知识库单独走向量库。
3.3 会话级上下文管理
上下文管理是AI应用架构里最容易被低估的环节,我单独拎出来讲。
模型对输入长度有限制(常见的8K、32K、128K),而你不可能把用户所有历史对话都塞进去。上下文管理要做的事情是:在有限的窗口内,保证模型"看得见"关键信息。我实践中用三个策略:
策略一:短期记忆走缓存,长期记忆走检索。当前这轮会话最近几轮对话,原样保留在Redis里,直接拼接进上下文。更早的、跨会话的用户偏好和行为特征,不按原文存,而是提炼成若干结构化标签或摘要,需要时再检索出来注入。
策略二:动态裁剪。我给每类内容设定了优先级:系统提示词 > 用户当前问题 > 工具返回的当前步骤结果 > 检索到的知识片段 > 历史对话摘要。当上下文长度不够的时候,从最低优先级开始裁,优先扔掉历史对话。这个方法被验证比简单截断效果好得多,因为截断通常会砍掉最关键的"当前问题"那一段。
策略三:摘要滚动。当一段对话的token数超过阈值,我不简单丢弃,而是调用一次模型,把这段对话压缩成一份摘要存起来。下一轮对话加入时,用"上一轮摘要 + 最近几轮完整对话"的格式拼接,既保证了连续性,又控制了长度。代价是每过几轮要多花一次模型的调用费用,但对长会话场景来说这笔钱花得值。
4. 三个典型场景的架构取舍
4.1 智能客服:稳定高于一切
智能客服这个场景,我接手过两个项目,最大的体会是:客服系统的第一诉求是稳定兜底,而不是炫技。
用户问"我的订单什么时候送到",模型如果信心十足地答错了时效,比回答"我暂时无法查询"更糟糕。所以在智能客服架构里,我做了两个额外设计:第一是置信度阈值机制——当模型给出的答案置信度低于0.7,系统不直接把答案返回给用户,而是转人工或者返回"礼貌的无法作答"话术;第二是业务规则前置——一些高频问题(退款政策、售后流程)直接走规则引擎回答,根本不经过大模型,既节省成本又绝对准确。
架构上的表现就是,服务层里同时存在两条链路:一条是传统决策树/规则引擎的轻链路,用来回答政策类问题;另一条是大模型链路,用来回答那些需要语义理解的开放问题。两条链路的出口统一封装,前端根本感知不到区别。这种"规则兜底+模型增强"的混合架构,我非常推荐所有客服类场景直接采用。
智能客服场景里还有一个细节经常被忽略:情绪识别与升级策略。用户语气明显不满(连续反问、感叹号大量使用、关键词触发)时,要跳过一切复杂推理流程,优先转人工。这属于最小的安全机制,必须放在架构里而不是依赖模型自觉。
4.2 知识库问答(RAG):检索质量决定上限
RAG(检索增强生成)是目前落地最广泛的AI应用形态,几乎所有企业内部知识库问答都跑这套架构。它由三块组成:离线索引构建、在线检索、生成回答。
离线索引构建这块,我认为核心不在"配置一个向量库",而在文档解析和切片策略。很多人把几千个PDF直接丢进去就完事,结果检索出来的片段根本不成句。我做的时候会额外做一层文档预处理流水线:格式解析(PDF/Word/PPT转纯文本)、标题层级识别(把文档按章节切开)、语义切片(按段落边界和语义完整性切,而不是固定字符数)、元数据标记(来源、页码、作者、时间)。这层工作的优先级最高,因为RAG的答案上限由检索内容的准确率决定,模型再好也救不了垃圾输入。
在线检索链路里,我引入了混合检索策略:同时跑向量相似度检索(语义匹配)和关键词检索(精确匹配),然后把两路结果融合排序。纯向量检索的问题在于处理专业术语和专有名词时容易偏差,比如"KKR"这种缩写,语义向量找不准,但关键词一查一个准。融合排序我建议简单用加权分数,权重根据业务不断调整。
生成阶段的重点在于引用溯源。模型回答的每句话必须能对应到具体的知识片段,前端展示时带上来源引用角标。这不仅是合规要求,也是用户信任感的来源。实现方式是在提示词里强制要求"只根据提供的上下文作答,否则明确拒绝",同时在结果后处理阶段,解析出引用的文档ID,和回答文本一起返回。
4.3 多Agent协作:控制反转和状态管理
多Agent是这两年最热的方向,我实际落地过一套自动化工作流平台,把这方面的坑摸了个遍。
多Agent架构最容易犯的错是:让Agent之间自由对话,互相传递消息,像开座谈会一样。听起来很智能,实际上一旦对话超过三轮,完全失控——Agent A产出的结果不是B想要的格式,B要反复追问,A再重新跑一遍,token烧得飞快,最后得到的还可能是错误结论。
我的做法是引入一个"导演Agent"(Supervisor),把协作模式从自发对话改成中央调度。导演Agent负责任务拆解、分工、进度控制和结果汇总,其他Agent是"执行者",只做自己负责的子任务,把结构化结果回报给导演。说白了,这种架构是把多Agent的"群聊"变成"项目经理指挥下的工作流",稳定性和可控性高好几个量级。
每个执行Agent必需暴露统一的接口:输入Schema、输出Schema、超时时间、重试策略。导演Agent在调度时严格按Schema来,不指望Agent之间自己协商格式。
状态管理也是多Agent架构的隐形难题。整个工作流跑下来,中间会产生一大堆中间产物(子任务结果、上下文摘要、各Agent的思考过程),这些不能全丢模型上下文窗口里,会爆。我在服务层设计了显式的状态存储(Redis + 数据库),用任务ID作为主键,把中间产物结构化落地,模型按需读取,而不是把全部历史都灌给它。这实际上是给Agent加了一个"外部记忆硬盘",只在执行时把需要的那几块装进"工作内存"。
5. 架构设计中的常见坑与避坑心得
5.1 延迟问题:流式是解药,但也带来新问题
大模型推理再怎么优化,单次生成完整回答也要几秒,这在很多交互场景里是不可接受的。流式输出是必然选择,让用户看到"字一个个蹦出来",感知延迟大幅下降。
但流式也带来架构层面的麻烦:你的日志系统、追踪系统、响应校验逻辑都要跟着改。我以前做非流式接口,逻辑很简单——请求进去,拿到完整响应,记录日志。改成流式之后,日志必须记录流式事件的时间线,不然压根没法排查"为什么用户看到一半断流了"。
我的经验是:接入层对流式响应做缓冲分段转发,每攒够一定字节再往客户端推,避免网络包太碎导致前端渲染卡顿。同时在后端对完整响应做异步校验,流式推送归推送,等到生成结束后另起一条异步任务做内容安全校验和答案质量评估,有问题的结果标记进日志,但已经推送的内容不撤回——这是折中方案,因为在流式场景里要中途撤回几乎不可能。
5.2 上下文爆炸:一次对话烧掉几十万token
我接过一个客户的复盘:他们某个会话型应用,用户聊了十几轮长问题之后,单次请求的token数飙到了十几万,一次请求的成本涨了上百倍,而且模型响应速度明显变慢。
问题根源就是我们前面讲的——他们把整个会话历史原封不动地拼进上下文,每轮对话都会累加,越滚越大,最终价格和延迟双双失控。解法就是我前面提到的动态裁剪和摘要滚动。另外还可以加上一个"刷新点"机制:当检测到用户意图发生明显切换时(从聊订单转到聊售后政策),重置对话历史,让模型忘掉前面的话题,只保留最近两三轮。
这里要专门强调:上下文压缩不是简单的丢弃,而是有损摘要压缩。调用一个小模型(比如系统里最便宜的那个)做历史对话的压缩总结,是性价比最高的做法。别用生产级的大模型做这件事,成本高得像用卡车运鸡蛋。
5.3 工具调用失败:模型已经"决定了",但工具报错了
Agent工作流里最头疼的就是这个场景:模型已经规划好了要调用工具A、B、C,结果工具B报错了(比如数据库连接超时、下游API返回500)。这时候怎么处理?
有两个流派。流派一:把错误信息原样返回给模型,让模型自己决定重试还是换策略。流派二:在服务层做好重试和降级策略,工具层出错时先自动重试,重试仍失败就返回一个"工具不可用"的标准化信息,模型收到后可以重新规划。
我实践下来推荐流派二的改良版:工具调用做三层防护——第一层是连接池和超时配置,确保单个工具调用本身稳定;第二层是自动重试(针对瞬时错误,如网络超时,最多重试2次);第三层是失败兜底,如果某个工具不可用,返回结构化错误码给模型,同时在系统提示词里说明"工具B可能临时不可用,如果业务不依赖它请直接跳过,不要让它阻塞主流程"。
这里有个容易踩的坑:错误信息里不要带堆栈或内部IP。大模型会推理你系统的内部结构,你不想让它借一次工具失败的信息,反推出你用的技术栈和部署信息。开发环境还好,生产环境务必把工具错误信息做脱敏处理,只返回业务逻辑层面的错误描述。
5.4 可观测性:AI应用排查问题的差异之处
传统应用的日志是"请求-处理-响应"的固定格式,排查问题靠时间线对齐基本就够。AI应用的日志天生是"多轮、异步、带上下文的",我踩了半年坑才搞明白该怎么设计观测体系。
核心思路是记录三个维度:请求链路(trace)、决策轨迹(chain of thought的调用步骤)、成本与质量(token和答案评分)。光有trace还不够,因为一次问答里会有多次模型调用,每次调用的作用不同(有的是意图识别、有的是生成答案、有的是工具调用的决策),必须把每次模型调用在链路里的位置和目的标记清楚。
我给每个Agent运行时都埋了一个"决策黑匣子",记录每次模型调用的:输入摘要、输出摘要、用掉的token数、消耗的时间、从哪个模块触发的。这些数据不进业务数据库,而是异步写入日志集群。排查问题时,定位到一次会话,就能把这轮的完整决策轨迹一条条拉出来看,一目了然。
另一个比较有效的小工具是提示词版本与响应质量的回归对比。我定期从生产日志里随机抽一批真实用户问题,用历史版本的提示词模板和新版本的提示词模板分别跑一遍,对比答案质量的评分和人眼盲测。这能帮你快速发现"这次改提示词到底改好了还是改坏了",避免闷头优化半天结果回头发现优化了个寂寞。
6. 写在最后,一些无法画在图里的经验
架构图画得再漂亮,落地的时候最终考验的其实是一些画不进图里的东西。
第一是关于"度"的把握。AI应用架构设计特别容易过度设计。我见过有团队给一个内部工具准备了十八个微服务,结果业务没跑起来,光运维成本就把项目拖死了。我的建议是,MVP阶段保留四层架构的主体骨架,但每层只做最关键的一两个组件——接入层先不做灰度,能力层先不做提示词管理平台,能跑通一个端到端闭环就好。架构演进跟着业务增长走,而不是一开始就建造一艘永远不会启航的巨轮。
第二是成本意识要尽早建立。AI应用和传统应用的成本结构完全不同,token费用是长在每次请求上的,流量一涨,成本肉眼可见地涨。我做的每个项目都要在架构层面里内置成本监控维度:哪个业务方烧掉了多少token、哪类问题平均要消耗多少token、哪个用户的会话特别"贵"。没有这些数据,你根本不知道钱花到哪了,更不知道优化从哪里下手。
第三是人的协作模式要跟着变。架构设计得再好,如果产品经理、算法工程师、后端工程师之间没有共同语言,项目照样转不动。我内部推了一套简单的机制:所有AI相关需求必须附带"用户问题样例"和"期望回答示例",接口联调的时候拿真实问题回归,而不是拿编造的假数据。这套机制看起来土,但比任何架构文档都有效,因为它逼着每个角色去面对真实世界的复杂性。
如果你正准备开始搭一个AI应用,我的建议很简单:先把你手头最关键的一个业务场景跑通端到端,时刻问自己"如果模型失效了,我的系统会怎样"——把这个问题想清楚,你的架构就成功了一大半。