ARTICLE DETAIL

资讯详情

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

AI应用架构设计实战:从原型到生产级系统的关键路径

AI应用架构设计实战:从原型到生产级系统的关键路径 1. 先泼一盆冷水为什么很多AI应用上线即崩这几年我看了不少AI项目的架构也亲手推倒重来过好几次最大的感受是大部分AI应用不是死在模型能力不足而是死在架构设计从一开始就是错的。早期团队做AI应用最常见的样子是提示词 SDK 一个后端接口。Demo阶段确实惊艳产品经理拿着手机到处演示客户看了直点头。结果一上生产问题全来了用户多了请求超时、上下文一长费用暴涨、模型一升级回答风格突变、想换个更便宜的模型却发现代码里到处是厂商SDK的调用……这时候再回头改架构成本往往是重写。所以AI应用架构设计这件事本质上不是选哪个框架、用哪个向量库而是先回答五个问题模型在系统里是什么角色是唯一的大脑还是可以被编排、替换、降级的组件用户的一次请求在系统里要经过哪些环节每个环节失败时怎么办上下文和记忆放在哪里是全部塞给模型还是系统自己管一部分并发上来以后模型接口的延迟和成本怎么控制线上出了质量问题你能不能定位到是提示词、检索、还是模型本身的问题这五个问题想不清楚画再漂亮的架构图都是空中楼阁。这篇文章我会用一张全景图打底从上到下逐层拆开讲把我自己在实际项目中验证过的设计思路、关键代码和踩坑经历都放进去适合正在做AI应用架构设计、或者准备从原型走向生产的开发者参考。2. 一张全景图AI应用架构到底该画成什么样我画架构图有个习惯从下往上画。因为AI应用里底层能力决定了上层的可能性从下往上看才能看出依赖关系是否合理。整张图可以分成六层名字不重要重要的是每一层职责单一、边界清晰层级核心职责典型组件交互层承接用户输入、渲染流式输出Web端、客户端、对话窗口、API网关编排层理解用户意图、规划任务、调度工具/知识Agent框架、工作流引擎、对话状态机模型网关层统一路由、限流、重试、降级、计费网关服务、模型路由、A/B策略模型层实际完成推理的模型实例大语言模型、多模态模型、小参数模型数据与记忆层提供知识、历史、结构化记忆向量数据库、关系库、缓存、对象存储基础设施层运行环境、日志、监控、部署K8s、日志系统、链路追踪、CI/CD先别急着卷技术逐层说清楚。交互层很容易被低估。很多人觉得交互层就是聊天框其实AI应用最大的交互特征是流式输出。你的后端有没有从第一天就支持SSE如果没有后面加流式的时候异步任务、超时设计、前端渲染全得跟着改一遍。交互层还承担内容安全相关的输入过滤和输出审核这部分独立做成服务不要在业务代码里到处散落。编排层是AI应用和传统后端最不一样的地方。传统后端是请求-响应的确定逻辑而AI应用里一个请求可能要经历理解意图-拆解任务-调用工具-观察结果-再决策的循环。这就是Agent的雏形。编排层要回答哪些流程是固定写死的工作流哪些流程需要模型动态决策我的建议是能写死的工作流就别让模型自由发挥成本低、可控性强动态Agent留给确实需要开放性的场景。模型网关层是我最坚持要做的哪怕项目再小。后面专门用一章讲它为什么是命门。模型层要思考的不是哪个模型最强而是我有几种模型可以组合使用。日常问答用中等模型复杂推理用小号的强模型或大模型图像理解走多模态专用模型。把模型当成可插拔的资源而不是绑死某一个。数据与记忆层解决的是模型怎么知道用户之前说过什么、系统里有什么知识。这部分的技术选型直接决定应用的上限和账单的厚度。基础设施层没什么特别的但要注意AI应用对显存和GPU调度的需求如果走API调用更多是关注上游的配额和限流。这张图最核心的一句话上层依赖下层但每层之间只能通过定义好的接口通信不能越层。最典型的反面案例就是业务代码里直接拼一个模型请求绕过网关还把向量库连接串在业务循环里——短期快长期全是债。3. 主链路拆解一次请求从进入到返回的全过程架构图只能看静态结构真正检验设计的是请求的流动。我拆两条最典型的主链路普通问答链路和Agent工具调用链路顺带把RAG检索融进去。3.1 普通问答与Agent的区别普通问答链路很简单用户输入 → 应用鉴权 → 读取用户配置/上下文 → 组装Prompt → 调用模型 → 流式返回这里最关键的是上下文从哪来。如果每轮对话都把所有历史一起塞给模型短期内能跑但Token开销会随轮数线性膨胀。正确做法是从记忆层加载最近N轮 长期记忆中的关键信息再交给Prompt组装器。Agent链路就复杂多了多了一个循环用户输入 → 意图识别 → 任务规划 → 选择工具 → 执行工具调用 → 观察工具结果 → 判断是否继续 → 生成最终回复这个循环是模型驱动的也就是说每一步都要交给模型决策。很多人Agent效果不好问题不在于模型笨而在于架构上没做约束没有给Agent设定最大迭代次数模型可能陷入死循环账单先崩了工具调用的结果没有结构化解析模型读不懂JSON里的错误码导致反复重试没有做沙箱隔离模型被诱导调用危险工具时直接接触生产数据。我实际项目里的处理方式是给Agent一个严格的工作流外壳工具白名单、最大步数、每一步超时都在编排层写死。模型只是在允许的范围内做选择而不是完全放开。3.2 模型网关在链路上的角色请求和响应不一定每次都经过全部层级但一定会经过模型网关。网关做的事包括把业务层的请求转成模型需要的格式调用真实模型拿到结果后做统一的后处理再返回给编排层。这一步看似多余但它的价值在高并发时体现得最明显。没有网关时每个业务服务自己直连模型厂商一旦触发限流每个服务的重试策略不一致同时涌向模型接口雪崩就是这么来的。有了网关重试、退避、熔断都收口到一处即使模型上游抖动网关可以快速降级到一个备用模型用户无感知。3.3 RAG检索链路查询改写、召回、重排与上下文组装RAG是让模型用你的知识回答的最主流方案。我见过很多人以为RAG就是用户问什么拿原话去向量库搜搜到就拼进Prompt结果效果一塌糊涂。一个能用的RAG链路至少包含五步查询改写用户口语化的提问先交给小模型改写成适合检索的形式。例如用户问上个月那个退款问题后来怎么处理的改写为2025年3月退款工单处理流程及结果。多路召回向量检索 关键词检索可以并行做保证既有语义匹配又有精确匹配。重排召回的Top 20用重排模型或规则重新打分取Top 5进入上下文。这一步对效果提升非常明显别省。上下文组装把检索结果和对话历史按模板拼进Prompt注意在Prompt里明确哪些是检索到的参考资料哪些是对话历史否则模型会混淆信息来源。引用溯源生成结果时要求模型引用资料编号这样用户可以点击查看来源——不仅能提高可信度出了问题也好追责。3.4 流式响应与并发控制现代AI应用默认都该走流式。流式的好处不只是体验好还能提前释放用户的等待焦虑。架构上要支持流式后端就不能用普通的HTTP同步请求等模型全部返回得用SSE或者WebSocket把模型的增量输出转发给前端。并发控制里最容易踩的坑是背压缺失。模型网关的并发数是有限的如果请求量超过模型接口的吞吐上限排队是正常的但队列要有长度上限、要有超时、要有拒绝策略。我惯用的方案是网关维护一个信号量超过最大并发时直接返回429由编排层决定是重试还是提示用户稍后再试。绝不用无限队列否则一个模型接口抖动整个应用的内存先被打满。4. 模型网关这个中间层为什么是命门单独拿一章讲模型网关因为它直接决定了AI应用在真实环境下的存活率。4.1 网关要解决的不只是切换模型很多团队做网关只是为了多模型切换比如哪天GPT不好用了换别的。但网关真正的价值在四个地方容错与降级主模型超时或报错自动切换到备用模型业务无感成本管控在网关上按维度记录Token消耗按用户、按功能、按模型分别计费不然月底拿到账单都不知道钱花哪了统一安全策略输入输出的合规过滤、敏感信息脱敏在网关统一做一次而不是每个业务都实现一遍流量治理限流、配额、灰度先在小比例流量上验证一个新模型的效果再全量切换。4.2 网关的核心能力清单与最小配置模板一个生产可用的AI模型网关我建议至少包含以下能力多模型路由按规则或权重路由到不同模型自动重试对网络错误、5xx做指数退避重试对429不盲目重试超时控制连接超时、首Token超时、总超时分别设置熔断连续错误率超过阈值直接降级到备用模型限流基于QPS和Token消耗的双重限流审计日志记录请求ID、模型、输入输出Token数、延迟、错误信息。下面是一个我常用的网关配置模板YAML格式可以直接参考models: - name: primary-llm provider: openai-compatible base_url: https://api.example.com/v1 model: deepseek-chat max_tokens: 4096 timeout: connect: 3s first_token: 20s total: 60s retry: max_attempts: 3 backoff: exponential retable_errors: [timeout, 500, 502, 503] - name: fallback-llm provider: openai-compatible base_url: https://api.example.com/v1 model: gpt-4o-mini max_tokens: 4096 timeout: connect: 3s first_token: 15s total: 45s routing: default: primary-llm fallback: fallback-llm rules: - match: user_tier: premium target: primary-llm - match: feature: complex_reasoning target: primary-llm - match: feature: quick_chat target: fallback-llm circuit_breaker: failure_threshold: 0.3 window: 60s min_requests: 20 rate_limit: global_qps: 100 per_user_qps: 10 token_bucket: 1000000提示这类网关现在有开源实现可以直接借鉴核心思路但自己封装一个不一定非要引入重量级框架关键是把路由、重试、熔断、日志这几件事收拢到一个模块里。4.3 多模型路由与成本策略多模型不是炫技是为了在不同场景用不同性价比的模型。我实践中常用的分层策略闲聊/摘要/分类用小参数模型或快速模型成本可能是大模型的十分之一复杂推理/代码/数学用强模型Agent中的工具调用用中等模型做意图识别只有关键决策才用强模型。网关里可以做基于特征的路由。用户画像、场景标签、输入长度都是路由信号。比如一个长文档分析请求输入可能上万Token走贵模型前先让便宜模型做一次压缩和关键信息抽取能省不少钱。5. 上下文、记忆和状态AI应用最重的隐性成本如果说网关是架构的骨架那上下文与记忆管理就是灵魂。5.1 Token窗口不是内存它更像工作台大模型的上下文窗口再大也是有限的而且几乎所有模型对长上下文的注意力都会衰减。我的经验是不要把模型上下文当成无限内存把它看作一张工作台——只放当前任务必需的资料。不相关的东西放得越多回答质量越差费用还越高。5.2 记忆分层的设计我的记忆体系分三层第一层是工作记忆即当前会话最近几轮对话。可以用滑动窗口比如只保留最近10轮超出窗口且重要的压缩成摘要。第二层是摘要记忆。写一个记忆压缩的调用把较长的历史对话提炼成结构化摘要用户偏好偏好简洁回答喜欢用表格 当前任务正在设计订单退款流程 已完成事项已确认退款规则、已通过网关配置限流 待确认退款是否需要人工审批。每一轮结束后用异步任务更新这个摘要而不是每次实时重算。第三层是长期记忆跨会话的知识。比如用户的身份信息、历史订单、常见问题。这部分最适合存进向量库把历史对话、文档切块后向量化每次请求前做一次相关性检索只把命中的片段拉进上下文。三层记忆不是都要做。业务早期只有工作记忆也能跑但做用户画像或者客服类产品长期记忆决定了应用是不是越用越懂你。5.3 上下文组装策略动态裁剪与无关信息隔离组装Prompt时我从不把所有检索结果所有历史一股脑拼进去而是做动态组装先放系统指令明确角色和任务边界再放检索到的参考资料标注来源编号然后放对话历史中与当前问题相关的关键片段最后放用户当前问题。这里容易被忽略的是检索结果可能互相矛盾。比如两个文档对同一流程描述不一致模型会困惑。我会在组装时让检索模块返回每段的可信度分数并把分数写进Prompt提示模型优先采信高分资料。5.4 记忆存储选型存储选型没有银弹我按场景做了个对比方便直接抄存储方案适合场景优点注意点Redis短期会话、热点缓存快、简单容量有限不适合海量向量PostgreSQL pgvector中小规模向量检索复用业务库运维简单数据量大后检索性能下降专用向量库大规模知识库、多租户隔离检索性能强、支持复杂过滤额外运维成本对象存储原始文档、图片、音频便宜、可靠不能直接用于实时检索需结合索引我的建议是起步阶段别直接上专用向量库。业务数据量在百万行以内pgvector完全够用还能省掉一套基础设式的运维负担。等检索延迟真的变成瓶颈了再考虑迁移。6. 并发、缓存与成本让架构既扛得住又烧得起AI应用的成本模型和传统后端完全不同。传统后端一台服务器多少钱是固定的AI应用的钱是跟着请求量线性增长的。我在做架构时一定会同时回答两个问题并发能不能扛、成本能不能烧。6.1 一个真实场景的并发与成本估算假设你做的是一个客服助手日活用户1万每人每天平均20轮对话每轮Prompt平均1500 Token输出平均500 Token。那一天的Token消耗大约是(1500 500) × 20 × 10000 400,000,000 Token如果按一个便宜模型每百万Token输入1元、输出2元计算一天的成本大概在输入1500 × 20 × 10000 300M 输入Token → 300 × 1元 300元 输出500 × 20 × 10000 100M 输出Token → 100 × 2元 200元 合计约500元/天每个月就是1.5万左右。这还只是推理费用不含网关、存储和人力。这个数字必须在动手前就算清楚。我见过太多项目上线前没人算账第一个月账单出来后直接砍需求。6.2 语义缓存比简单KV缓存难但收益巨大对AI应用来说传统KV缓存只在完全相同的问题下命中收益有限。更多时候用户问法不同但语义相同比如怎么退款和退款流程是什么。这就需要用语义缓存把用户问题转成向量在缓存里找语义相似的历史问题命中就直接返回之前的答案。语义缓存的实现不复杂async def get_cached_answer(question): # 1. 对问题做embedding q_vec embed(question) # 2. 在向量缓存中检索相似度最高的历史问题 similar await cache_vector.search(q_vec, top_k1, threshold0.92) if similar: return similar.answer return None相似度阈值要仔细调。阈值太低容易返回驴唇不对马嘴的答案阈值太高缓存命中率就低。我通常从0.9开始调根据业务反馈微调。6.3 性能优化顺序先压TTFT还是先压总时延用户的等待体感主要取决于两个指标TTFT首个Token时间和总时延。大多数情况下TTFT比总时延更影响体验。用户发出问题后如果1秒内看到第一个字出来哪怕后面生成比较慢他的等待焦虑也会大幅降低。优化时我会按这个顺序排查减少Prompt输入长度去掉冗余历史能直接从20秒降到5秒预热长连接让网关和模型服务保持连接池避免每次握手流式输出尽早返回首个Token缓存检索结果和Prompt片段减少网络IO。6.4 模型分流与批处理另外不是所有请求都要实时。像日报摘要周报生成这种非实时任务完全可以走异步队列用便宜的低峰时段批量执行成本能差出一个量级。架构上预留一套任务队列接口实时和异步用同一套编排逻辑只是触发方式不同。7. 不要把AI应用当黑盒可观测性与评估体系模型输出的不确定性让AI应用比传统系统更难排查问题。我始终觉得没有可观测性的AI应用等于在悬崖边开车还不看仪表盘。7.1 链路追踪必须记录哪些字段除了常规的API请求日志AI应用至少还要记录请求的唯一ID和会话ID用的模型名和模型版本Prompt的实际内容合规前提下输入Token数、输出Token数、总Token数TTFT、总延迟重试次数、降级情况检索命中了哪些知识片段及来源ID用户最终反馈点赞/点踩。有了这些字段哪天用户说回答变差了我们可以回溯是换Prompt导致的还是检索内容变了还是模型版本被灰度切换了。7.2 线上评估用户反馈、隐式信号与回归集除了日志还要搭一个评估闭环。我的做法分三层显式反馈在对话后让用户点有帮助/没帮助隐式信号回答后用户是否继续追问、是否复制结果、是否转向人工客服——这些能侧面反映答案质量回归集评测维护一组固定的黄金问题集几百条覆盖核心场景每次改Prompt、换模型、调检索参数都跑一遍这个集合人工或模型打分对比。黄金问题集是个笨办法但真的有用。没有它你可能今天调好了A场景明天又把B场景改坏了还浑然不知。7.3 Prompt与模型的版本管理Prompt不是写在代码里的字符串它是需要版本管理的资产。我建议把每个场景的Prompt模板独立存放带版本号、生效时间、效果指标像管理配置中心一样管理。模型切换也一样灰度比例、回滚开关、A/B分组都要在网关层留好口子。这套机制一旦建立后面优化模型和Prompt就是科学实验而不是玄学调参。8. 从零落地一个人也能搭起来的最小架构讲完原理说说落地。如果你现在手头就一个项目还没上线怎么按最小成本把架构搭起来8.1 技术选型的能不造轮子就不造先别急着自研一套Agent框架和网关。我的选型顺序是模型接入优先选兼容OpenAI接口格式的服务这样网关层可以统一处理编排中小项目直接用代码写工作流比上一套重型Agent框架更可控向量存储直接用业务数据库的向量插件少一套独立服务缓存选Redis理由简单生态成熟可观测性用现有的日志和监控服务先记录关键字段不追求链路追踪产品全覆盖。8.2 最小闭环的实施顺序我建议按下面的顺序做每一步都能独立产生价值先封装模型网关路由超时日志哪怕只接一个模型也要走网关再做会话与上下文管理实现滑动窗口和摘要压缩然后接入RAG链路先保证检索能用再优化效果加流式输出让前端的体验上一个台阶搭评估回归集至少把核心30个问题维护起来。代码层面一个最小网关的核心逻辑差不多是这样class ModelGateway: def __init__(self): self.routes {} async def chat(self, request): model_name self.route(request) try: resp await self.call_model(model_name, request) self.record_usage(model_name, resp) return resp except ModelError as e: fallback self.get_fallback(model_name) self.log_retry(request, e) return await self.call_model(fallback, request)别笑这个几十行的东西就是网关的最小可用版本。真实生产里往里面加熔断、限流、审计但骨架不变。8.3 分阶段演进路线玩具→MVP→生产架构不是一步到位的我的演进路线分三步阶段一玩具原型。不关心架构只要能跑通验证核心价值。这个阶段可以没有网关、没有记忆、没有缓存。阶段二MVP。必须补上模型网关、会话管理和基础的可观测性。这个阶段的目的是让小范围真实用户用起来收集反馈。阶段三生产级。再补RAG、语义缓存、熔断降级、评估回归集、成本看板。这个阶段拼的是稳定性和成本控制。很多团队错在试图从阶段一直接跳到阶段三结果一上来就被架构复杂度拖死。要接受先丑后美把每一步的债控制住就行。9. 最后聊几点我踩过的坑写到最后分享几个我实际项目里反复踩过的坑希望你能绕开。第一个坑是过早引入重型框架。现在Agent框架一个比一个复杂装完光配置就能写上几天。我后来发现很多场景用简单的工作流状态机就够了模型能发挥的空间并没有想象中那么大。框架不是不能用而是要有明确的问题再引入。第二个坑是上下文管理做得太晚。我早期做客服助手时直接把全部对话历史塞给模型一轮轮下去费用肉眼可见地涨回答还越来越差。后来老老实实做滑动窗口摘要压缩成本降了一半效果反而好了。第三个坑是没有给模型设置明确的失败出口。一次工具调用卡住了模型可能傻傻地重试到超时用户干等。后来我所有外部调用都套了超时和最大重试次数并且让模型在超时后大方承认而不是编造一个结果。这个细节对用户体验的提升比想象中大得多。第四个坑是低估了评估的重要性。没有回归集的时候我调整过一个Prompt看起来修复了回答太啰嗦的问题结果第二天用户反馈关键信息经常缺失。后来我才把评估集建起来改任何东西先跑回归再上线。AI应用架构设计没有什么银弹说到底还是工程问题分层清晰、网关收口、记忆分层、成本可控、链路可观测。把这些基本功做扎实了模型换多少个都不怕业务扩展起来也不慌。希望这篇偏实战的拆解能给你一些可以直接用的思路。
返回列表