ARTICLE DETAIL

资讯详情

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

AI应用架构设计实战:从白板图到可控生产流程

AI应用架构设计实战:从白板图到可控生产流程 上周有个朋友来找我说要做一个 AI 知识库问答助手开口第一句就是“模型用哪个”。我说你先别急我们先把 AI 应用架构设计图画出来。后来我们在白板上画了一个多小时他中途停下来感慨如果当初先画这张图再动工至少能省三成返工。这不是个例。我见过太多 AI 项目翻车不是模型不行而是架构根本没想清楚。有人把提示词直接写死在业务代码里换个模型要改一堆有人把知识检索和生成逻辑混在一起线上问题没法定位有人一开始就上了 Agent结果编排层乱成一锅粥并发一上来直接雪崩。这些都是典型的“跳过设计直接写代码”的后遗症。图解 AI 应用架构设计的价值就是逼着你在动手之前把用户请求怎么进来、数据处理怎么流转、模型怎么调度、知识怎么检索、失败怎么兜底、成本怎么监控全部在纸面上推演一遍。这篇文章我用自己的实际项目经验拆一拆怎么从零画出一张能指导开发的 AI 应用架构图。1. 先想清楚AI 应用架构设计到底在画什么1.1 它和传统后端架构的根本区别很多人第一次画 AI 应用架构图会下意识套用传统后端的思路用户请求进来经过鉴权、业务逻辑、数据库读写然后返回结果。这套框架本身没错但 AI 应用有一个传统后端没有的变量——模型输出的不确定性。传统后端里接口返回什么字段、状态码是什么、数据从哪张表来都是确定的。你在设计阶段就能把链路的每一个环节钉死。AI 应用不一样模型给你返回什么内容是概率性的同一个问题换一次调用可能措辞就不一样模型上游版本还随时可能更新今天能召回的文档明天可能召回不到了再加上工具调用有副作用、上下文有长度限制、用户多轮对话有状态漂移这些全是传统架构画图时不用考虑的变量。我常用一个生活化类比传统后端像标准化餐厅后厨流程固定下单就能出菜好吃难吃是可预期的。AI 应用更像一个创意厨房同一个订单里有些菜可以预制比如常见问题直接命中缓存有些菜必须现场发挥比如复杂推理、多轮追问而你要做的架构图不只是画清楚烤箱、灶台、备菜区怎么排布还要标清楚“什么菜走预制线”“什么菜现场做”“现场做出来的菜谁来验收合格”。所以 AI 应用架构图本质上画的不只是组件和连线而是决策点。每一个箭头背后都是一个 if/else走缓存还是走模型检索还是直接生成需要工具调用还是纯文本回答这些决策才是 AI 应用架构设计真正要表达的内容。1.2 图解带来的三层实际收益把架构画出来这件事收益不是“文档好看”而是三个非常落地的效果。第一层是让产品经理和非技术同事看懂整个系统。我们研发圈子里经常说“对齐”但对齐的最有效方式不是开会念需求文档而是把一张图贴在墙上告诉产品同事你在这里输入问题系统先去这里查知识库查不到会走这个兜底分支然后再调模型生成答案最后还会在这里做一遍合规校验。对方一听就明白了后续需求变更也会基于这张图来讨论而不是凭空提一些架构上根本不成立的需求。第二层是让研发能按依赖关系拆任务和估工期。架构图画出来以后哪些模块是并行的可以分给不同人做哪些模块有严格的前后依赖必须先做一目了然。我做过一个多 AI 协作的项目如果没有架构图两个工程师会同时改同一个编排模块有了图每个人负责哪一层、接口怎么定义、按什么顺序联调都清晰了整体工期至少缩短了三分之一。第三层是给线上运维和后续升级留好后路。架构图上标了关键路径、监控埋点、失败分支之后一旦线上出问题你能顺着图快速定位是检索挂了、模型网关超时了还是编排状态丢了。甚至模型供应商要升级版本你也能在图上先演练一遍哪个环节受影响、需要准备什么灰度方案、回滚开关在哪里。这张图越往后用越值钱。2. 动手画图前先收集输入与约束2.1 需求五要素把一句话需求翻译成架构输入很多人画架构图习惯从组件开始先画一个模型、画一个向量库、再画一个前端然后开始连线。这个顺序是反的。正确顺序是先从需求里提取架构输入也就是把产品需求“翻译”成技术设计必须响应的条件。我一般会用五个要素来逼自己把需求问透。第一用户是谁。是内部员工还是外部客户是技术背景还是普通用户使用频次是每天高频还是偶尔一问这些决定了你要不要做复杂的会话管理、要不要做用户隔离和权限控制。第二输入是什么形态。纯文本带图片、PDF、表格语音形态决定了你的接入层要做哪些预处理比如 OCR、文档解析、语音转写这些都是架构里独立的一层。第三输出要什么精度。是要一段流畅的自然语言回复还是要结构化 JSON是要带引用来源还是允许模型自由发挥输出要求直接决定了后置校验环节的复杂度。第四数据从哪来。是已有的知识库文档是从数据库实时查询还是模型内部的参数化知识数据源的形态决定了你要不要做 RAG、要不要搭索引、要不要做数据更新管线。第五延迟和成本的预算。用户能接受首字返回时间是多少每次回答的调用成本上限是多少这两个数直接决定能用多大模型、要不要上缓存、要不要做流式输出。拿我最近做的企业内部知识库问答助手来举例这五个要素是这么对应的用户是公司全体员工输入以文本问题为主偶尔粘贴一段报错日志输出需要答案加引用来源方便追溯数据源是分散在 Wiki、产品文档和工单系统里的几百篇文档延迟要求首字小于 3 秒单次问答成本控制在几分钱以内。这五条写下来之后架构的边界其实已经画出来一半了。2.2 从数据流反推架构边界需求五要素齐了之后我会接着画一张最粗的数据流草图用箭头把“输入→中间处理→输出”串起来。这一步不需要任何组件细节只需要回答六个问题用户输入进来后要不要做意图分类数据需不需要清洗和切分检索用关键词还是向量检索结果要不要重排上下文怎么拼装输出要不要校验下面是我画知识库问答助手时最开始的那版数据流草图可以给大家做个参考用户输入 → 意图识别 → 知识检索 → 结果重排 → 上下文拼装 → 模型生成 → 输出校验 → 返回用户 ↓ ↓ ↓ ↓ ↓ 会话历史 向量库 Rerank Prompt模板 引用溯源这张图看起来很朴素但它帮我回答了几个关键的架构问题第一不需要单独做 Agent 规划回答问题这个场景用固定流程就行不需要动态拆解任务这省掉了一大半编排复杂度第二知识检索是最核心的链路向量库和重排模型是刚需检索质量直接影响回答质量第三需要在生成之后加校验环节因为要保证答案里的引用来源真实存在不能模型自己编一个文档编号出来。数据流图画完之后我会再做一步分层把这些数据流按在线数据、离线数据、会话数据分个类。在线数据是每次请求都要访问的比如向量索引、业务数据库离线数据是用于评估和迭代的比如历史请求日志、人工标注样本、线上反馈会话数据是多轮对话的状态一般放 Redis 或带 TTL 的数据库表里。分完这三类整个系统对存储的需求就清楚了哪些要高性能、哪些要低成本、哪些要能快速过期后续选型就顺理成章了。3. 核心图解一页纸画清楚 AI 应用主干3.1 五层架构一页纸画法需求捋清楚、数据流走完一遍之后就可以开始画正式的架构图了。我习惯把 AI 应用架构的主干拆成五层每一层只做一件事层与层之间通过明确的接口通信。这样画的好处是每一层都可以独立扩展和替换换模型不影响接入层换向量库不影响编排层。下面是我通常使用的一页纸五层架构模板你可以直接拿过去根据自己的场景改┌─────────────────────────────────────────────────────┐ │ 接入层 Web端 / App端 / IM机器人 / API网关 │ ├─────────────────────────────────────────────────────┤ │ 理解与编排层 意图识别 / 任务规划 / Agent编排 / 会话管理 │ ├─────────────────────────────────────────────────────┤ │ 模型与工具层 模型网关 / 大模型 / Rerank / 外部工具API │ ├─────────────────────────────────────────────────────┤ │ 记忆与存储层 向量库 / 会话缓存 / 业务数据库 / 文档索引 │ ├─────────────────────────────────────────────────────┤ │ 治理与观测层 评估集 / Trace链路 / 监控告警 / 成本统计 │ └─────────────────────────────────────────────────────┘每一层的一句话职责我通常这样定义。接入层负责把用户的输入变成标准化的内部请求无论你是从网页来的还是从企业微信机器人来的到编排层手里都应该是同一个结构体里面至少包含用户 ID、会话 ID、消息内容、附带的上下文元数据。理解与编排层是大脑它决定这次请求走哪条链路直接检索回答、多轮追问还是需要拆解成多个子任务执行。模型与工具层是被调用方所有模型调用都通过模型网关统一进出外部工具在这里做权限校验和格式转换。记忆与存储层提供状态和数据向量库存知识、缓存库存会话和临时结果、数据库存业务实体的最新状态。治理与观测层横跨所有层负责给每一层打点、记录 trace_id、采集评估样本。画图的时候我有一个非常固执的原则每一条线都必须标注数据流向而且必须画出失败分支。比如用户输入到编排层正常流向是往下走但编排层调用模型超时了怎么办这条失败路径要画出来哪怕只是个小的分支箭头也要说明是走缓存兜底还是返回友好错误提示。很多人的架构图看着整齐实际没法用就是因为所有线都是从上往下、整整齐齐没有一条失败的线。真实系统里失败才是常态架构图不画失败分支等于没画。3.2 主流程图与关键路径图两张必画的辅助图除了五层架构图我还会针对核心链路再画两张辅助图一张是主流程图一张是关键路径图。主流程图把一次请求从进来到返回的每一步展开表达的是逻辑时序关键路径图标注的是每一步的真实耗时预算表达的是性能规划。主流程图我用一个具体的知识库问答请求来说明用户提问 → 查询会话上下文 → 判断知识类型 → 向量检索 Top20 → Rerank 取 Top5 → 拼装 Prompt → 模型流式生成 → 抽取引用来源 → 校验来源可用 → 返回答案和引用这张图每次画都会帮我发现不少问题。有一次我看到流程里“模型流式生成”后面直接接了“返回答案”当时就意识到漏了一个关键步骤用户如果追问“你刚才说的那个指标是哪个季度的”系统需要能追溯到当前会话里已经检索过的上下文而不是重新检索一遍。于是我在会话管理环节补了一个“会话内引用索引”的存储设计。如果没有这张主流程图这个细节要等联调时才能发现返工成本就高了。关键路径图则是给性能优化用的。我会在每个环节后面标上预期的耗时预算然后去线上实测把实际耗时和预算做对比找出超预算的环节。比如我们预期检索 300ms、模型首字 1500ms实测发现检索到了 800ms那就去查向量库的索引参数、并发连接数、是否需要加缓存。如果模型首字到了 3 秒就要考虑是不是历史对话太长导致 prefill 变慢是否需要做历史压缩。没有这张关键路径图性能优化就是无头苍蝇这里调一下那里调一下最后可能把正常链路调坏了。4. 架构图背后的关键选型决策4.1 检索选型RAG 的边界与向量库选择架构图画到检索层的时候一定会面对一个问题要不要做 RAG向量库选哪个。先把结论放在前面不是所有 AI 应用都需要 RAGRAG 解决的是“模型不知道、数据会更新、答案要可溯源”这三类问题。如果你的场景是让模型做文案润色、代码解释、头脑风暴就不需要硬塞一个检索链路进去徒增延迟和故障面。如果确认需要 RAG接下来就是向量库选型。我见过不少团队一开始就上分布式向量库运维成本和复杂度远高于实际收益。选型的逻辑其实就三条数据量多大、并发多高、团队有没有能力维护一个额外组件。根据这三条我做了一个简单的对照表方案适用规模优点注意点PostgreSQL pgvector百万级向量以内不需要额外组件事务一致性好运维成本低高并发下性能一般需要调索引参数Elasticsearch千万级以内支持关键词与向量混合检索生态成熟内存占用高索引调优有门槛Milvus千万级以上性能强支持大规模向量检索和标量过滤独立部署运维复杂前期调研成本高云托管向量库不确定规模免运维按量付费上手快数据出网合规要确认长期成本偏高我自己的项目规模在几万到几十万篇文档直接用了 PostgreSQL 加 pgvector实测下来完全够用。RAG 效果遇到瓶颈先不要急着换向量库而是先检查切分策略和重排模型。很多检索质量差的问题不是向量数据库慢而是文档切分得太粗或者太碎导致召回的内容噪声太大。重排Rerank模型往往比换一个更贵的向量库对效果的提升更直接。4.2 模型网关与多模型协作架构图里模型这一层我建议所有模型调用都通过一个模型网关统一进出不要在业务代码里直接拼各家模型的 API。模型网关在这个架构里的角色相当于机房里的统一配电箱各家模型像不同的供电线路业务侧只需要知道我有一个稳定的电源接口就行。模型网关至少要做好四件事。第一是统一接口对外暴露一个标准格式内部再适配各家模型。这样切换模型供应商时业务代码零改动。第二是降级策略比如主力模型超时或报错时自动切换到备选模型或者降级到一个较小的快速模型。第三是预算控制给每个业务线、每个用户维度设置 token 或调用次数的配额防止个别用户把成本打爆。第四是日志与成本统计每次调用都记录模型版本、输入输出 token 数、延迟和费用。多 AI 协作的场景下模型网关还有个额外的重要职责协议约束。多个子 Agent 协作时每个 Agent 的输入输出必须定义成结构化协议而不是靠提示词里写“你是一个……请把结果传给下一个”这种软约束。我踩过这个坑两个子 Agent 采用同样的提示词模板但各自返回的字段格式不一致下游解析直接报错。后来我改成在模型网关层强制校验每个子 Agent 输出必须是 JSON Schema 定义的格式解析不合法就重试一次重试仍然不合法就走失败分支。从架构图上看多 Agent 之间的每条线都变成了有协议约束的接口而不是模糊的“传一段文本”。4.3 上下文管理与提示词工程提示词很容易被当成“写几段话”来对待但在架构设计里提示词和上下文管理是正儿八经的工程组件。提示词本质上是一段有版本的程序逻辑应该像代码一样管理起来而不是被复制粘贴在每个人的本地文档里。我在架构里会把提示词模板单独拎出来一层放在编排层和模型层之间的“上下文组装”环节。模板按用途分成几类系统提示词、检索结果格式化提示词、工具执行说明、多轮对话润色提示词每一类都有版本号。发布新提示词时走和代码一样的流程先在评估集上跑一遍对比效果再灰度上线。线上如果效果异常可以一键回滚到上一个版本。这样一个提示词版本切换跟切一个配置开关一样简单而不是去改代码再发版。跟提示词紧密相关的是上下文预算管理。模型上下文窗口是有限的不可能把用户所有历史对话、所有检索结果一股脑全塞进去。我习惯在架构图上直接标出上下文预算分配比如一个 8K 窗口的分配比例系统提示词留 10%检索命中结果留 30%历史对话摘要留 40%当前问题留 10%生成输出预留 10%。这个比例不用很精确但要有预算意识。一旦上下文超预算就必须做取舍优先压缩历史对话用摘要替代原文其次减少检索结果的条数最后才考虑升级到更大窗口的模型。这样排查“回答质量下降”时第一件事就是看上下文拼装是否超预算把关键信息挤掉了。4.4 评估与防漂移架构图上的闭环评估环节在产品经理眼里可能是“抽几个人看看效果”但在架构设计里评估是防漂移的闭环必须提前设计好。漂移指的是模型升级、提示词改动、知识库更新之后线上回答质量发生变化可能是变好也可能是变坏没有评估机制就无从感知。我建议在架构图上把评估体系画成一个环线上请求日志 → 定期抽样本 → 人工标注质量 → 加入评估集 → 跑回归测试 → 决定是否放量或回滚。这个环至少要有三个关键元素。第一是评估集也就是一组固定的、带标准答案的测试问题。不用多二三十条就够起步但要覆盖典型场景和边界场景比如知识库里有明确答案的问题、跨文档才能答出来的问题、知识库里没有答案的话应该明确说不知道的问题。第二是 A/B 对比任何提示词或模型版本的变更都要和线上旧版本跑同一批评估集对比正确率、完整度、引用命中率三个指标。第三是线上抽检评估集覆盖不了线上的长尾问题需要定期从真实日志里抽一批对话做人工或模型辅助的质量评价发现问题再补进评估集。现在做 AI 应用不缺模型缺的是把一次性的“能用”变成长期的“稳定”。评估这个闭环就是架构图上那条把线上反馈重新引回开发流程的回流管道。没有它每一次模型版本更新都是一次冒险。5. 上量之后并发、成本与可观测性5.1 AI Agent 怎么扛并发说到“AI Agent 怎么扛并发”这个话题很多人第一反应是加服务器、上负载均衡。但 AI Agent 的并发瓶颈和传统 Web 服务不一样。传统服务并发瓶颈在数据库连接数和 CPU 计算能力Agent 场景的瓶颈在编排层和外部工具的等待时间。一个 Agent 请求进来往往要串行调用好几次模型中间还可能穿插检索、调工具、读数据库一次请求的总耗时可能长达几十秒甚至分钟级。如果所有请求都直接同步处理线程池很快就会被占满系统就假死了。我处理 Agent 并发的核心思路是把编排器做成无状态把会话状态拿出来单独存。编排器本身不保存任何会话数据只负责接收任务、按流程调度、记录日志这样任何一台实例都能处理任何一个请求水平扩容没有任何障碍。会话状态、子任务执行进度、中间结果全部放到 Redis 或数据库里带 TTL 自动过期。无状态化不只是解并发问题还顺便解决了发布时的优雅重启问题。另一个关键设计是给外部工具调用加超时和队列。Agent 调外部 API 时外部服务可能很慢甚至无响应如果没有超时控制一个慢请求会把后面所有请求都堵住。我在架构里给外部工具调用单独加了一层统一做这三件事设置超时比如 5 秒没响应直接中断、失败走重试队列重试次数上限两次、连续失败触发熔断短时间内不再调用该工具。此外同一会话的任务并发限制也很重要防止同一个用户的两个轮次任务乱序执行混淆会话状态。不太复杂但不是特别耗时的 Agent 任务可以用同步方式处理真正耗时的长任务就丢到消息队列里异步处理前端通过轮询或 WebSocket 推送结果。上面两种方式混用是我实测下来成本最低、效果最稳定的方案。下面是我在项目里用的一个简化版并发模型示意用户请求 → API网关 → 请求入队 → Worker Pool 消费 ↓ Agent编排器无状态 ↓ 模型网关调用 工具调用超时/熔断 ↓ 结果写回会话存储Redis ↓ WebSocket / 轮询 推送结果给用户5.2 成本模型与监控指标AI 应用的成本结构比传统应用复杂得多。传统应用成本主要在服务器和带宽比较稳定AI 应用的成本大头是模型调用费而模型调用费和你的上下文管理、缓存命中率、检索设计全都有关系。同样是知识库问答有的团队一次请求消耗 1 万 token有的团队只消耗 3 千 token回答质量还差不多这中间的差价就是一个架构设计问题。我算成本时用这个公式单次请求成本 系统提示词 token 检索结果 token 历史对话 token 当前问题 token 工具返回 token* 输入单价 生成输出 token * 输出单价。注意这里的系统提示词和检索结果每次请求都会重新拼一遍几乎是不变的固定开销。如果你的知识库文档很长切分后检索结果动辄几千 token每次请求成本就会很可观。成本优化上我试过两个非常有效的方案。第一是语义缓存把高频问题的回答缓存起来用提问的向量相似度来命中缓存相似度超过阈值的直接返回缓存结果不再调用模型。这个方案特别适合“同样的问题反复被问”的企业内部场景实测能把模型调用量砍掉三四成。第二是历史对话压缩多轮对话到第五轮以后不再把完整历史拼进上下文而是用模型对前面的对话做一个摘要把摘要作为后续轮次的上下文。这样既保留了大意又把每轮成本控制住了。监控指标方面我建议至少盯住五个数P95 首字延迟、端到端回答耗时、检索召回率、请求失败率、单次会话成本。再搭上 Token 消耗的总量和缓存命中率基本就能看全系统的健康状况。这里有个容易忽略的坑只盯 P95 延迟是不够的流式输出场景下用户感知的是首字延迟而成本统计看的是总 token 数这两个指标一个代表体验一个代表成本必须分开观测。可观测性三件套日志、Trace、指标里对 AI 应用最重要的是 Trace。因为一次 AI 请求会跨接入、编排、检索、模型、工具好几个环节如果没有一个贯穿全链路的 trace_id排查问题时只能逐段翻日志效率极低。我在项目里给每个请求分配一个 trace_id从头到尾透传每个环节都往同一个 trace 里写 span耗时、入参、出参、错误信息这样一次请求的完整链路包括模型调了几次、每个工具花费多久、哪一步最慢全部一目了然。Agent 场景尤其重要它经常会走到你没想到的分支没有 trace 几乎没法复现。6. 架构落地后的常见问题与排查套路6.1 高频故障排查速查表架构落地以后线上不会一帆风顺。我把实践中遇到的高频问题整理成一个速查表希望能帮你少走一些弯路。现象可能原因排查方法常用解法回答质量突然下降上游模型版本更新、提示词被改动、知识库数据变更对比新旧输出、检查模型版本变更记录、跑评估集回归回滚模型版本或提示词重建知识索引检索结果总为空embedding 模型维度不一致、切分粒度太粗、向量库集合选错检查索引配置、测试单独检索请求、打印切分结果重建索引调整切分策略换更强的 embedding 模型Agent 陷入死循环工具返回重复结果、编排缺少终止条件看 trace 里工具调用次数、分析循环路径限制最大迭代次数、增加工具结果去重、加循环检测并发一上来就超时编排层同步等待、外部工具缓慢、模型调用串行压测全链路、打点各环节耗时接入队列异步化、工具调用加超时和熔断、必要时并行调用成本暴涨历史对话无限制累积、缓存命中率低、检索结果过多查看 token 消耗分布、分析命中率压缩历史、加语义缓存、限制上下文上限这五个问题里前三个是效果类的后两个是性能和成本类的。它们的共同点是如果不靠架构图去定位单凭猜测很可能一天都找不到根因。有了分层架构和 trace 链路每个问题都能直接收窄到某一层排查效率完全不同。6.2 排查实操套路分层二选一永远保存快照最后分享一个我在排查 AI 应用问题时固定使用的实操套路可以概括为“分层二分法”。不管线上报什么错先把链路按架构图的五层断开逐段测试定位问题出在哪一层。比如用户反馈回答答案不对。第一步看接入层确认用户输入有没有被正确解析多轮会话有没有拿错上下文第二步看检索层单独把用户问题拿去跑一次检索看返回的 Top5 文档是否相关第三步看上下文拼装把最终发给模型的 Prompt 导出来看确认检索结果有没有被正确嵌入、有没有超预算被截断第四步看模型层用同样的 Prompt 单独调一次模型确认是模型本身的问题还是上游链路的问题。这样二分法走下来90% 的问题能定位到具体环节。另一个必须要养成的习惯是保存请求快照。每一个线上请求除了标准的 trace 日志之外我还建议把以下信息完整记录原始用户输入、会话历史摘要、检索命中的文档 ID 和相关性分数、最终发给模型的完整 Prompt、模型返回的完整输出、如果走了重试和失败分支也要记录。这个快照在排查的时候价值极大——你可以完整回放一次请求看到底是哪一步出了问题。我反复强调要“先怀疑数据再怀疑模型”。很多团队一看到回答不对就认为模型能力不行急着换更大的模型。实际上我遇到的大量问题都出在检索数据和上下文拼装上要么是切分时把关键段落截断了要么是知识库里有多个自相矛盾的历史版本要么是检索命中的内容相关性不够。这些问题的解法都不是换模型而是优化数据和流程。每次想“是模型的问题”之前先问自己一句喂给模型的信息正确吗我自己画架构图有个习惯先画一版最丑最粗的然后每次踩了坑就往图上补标记。比如某个外部工具经常超时我就把它和编排器之间画一条粗虚线旁边写“必须设置超时”某个检索分支经常命中过期文档我就在存储层画一个“版本标记”的标记。这样一张图越用越厚后来新同事入职我给的不是文档和 PPT就是这张图再配合线上 trace 系统演示一遍比讲一小时的文档都管用。说到底AI 应用架构设计这件事本质上就是把模型的不确定性管理成一个可控的生产流程。画图只是手段真正值钱的是每个箭头背后的取舍和约束。希望这篇分享能帮你迈过“先画图再写代码”这道坎下次接到 AI 项目别急着问“模型选哪个”先拿块白板把架构想明白再动手。
返回列表