ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI应用底座微服务架构设计与落地实践

AI应用底座微服务架构设计与落地实践 企业里做 AI 落地的人这两年应该都有同感模型能力不是瓶颈真正的麻烦在于把模型塞进业务系统的那一公里。我见过太多团队Demo 阶段用几十行脚本调个接口就能跑通一旦要上线、要接权限、要控成本、要审计日志整个东西就散架了。QuickBlue 这类AI 应用底座就是冲着这个断层来的。它不是一个模型也不是一个聊天窗口而是一层把 AI 能力工程化、服务化、可治理化的基础设施。这篇就围绕 QuickBlue 到底是什么、它内部大概怎么搭、企业为什么非得要这么一层东西把我自己趟过的路和踩过的坑摊开讲清楚尤其适合正在做 AI 中台选型、或者被AI 功能上线难折磨的开发和架构同学。1. 先把AI 应用底座这个词拆开看1.1 底座不是模型是模型和业务之间的那层承重墙很多人第一次听到AI 应用底座下意识以为又是一个套壳的模型聚合平台。其实不是。你可以把整个 AI 应用想象成一栋楼大模型是发电机业务系统是住户而底座就是配电房、管道井、消防系统这一整套中间设施。发电机再强没有配电和管道电和水也送不到每家每户。QuickBlue 扮演的就是这个角色。它对外提供统一的模型调用入口对内管理提示词、上下文、工具调用、权限、配额、日志。业务方不需要知道背后接的是哪家模型、走的是哪条链路只需要按底座约定的方式发起一次AI 请求剩下的路由、降级、计费、审计都由底座兜住。这个定位决定了它的技术形态它天然是一个微服务系统而不是一个单体应用。因为模型调用、提示词管理、会话状态、权限校验、计费统计这些能力的伸缩性和变更频率完全不同硬塞进一个进程里后期维护会非常痛苦。1.2 为什么关键词里全是微服务相关的东西你注意到热搜词里密集出现了微服务架构、Spring Cloud、Sentinel、Redis 集群、微服务拆分这些词这不是巧合。AI 应用底座本质上是一个高并发、多租户、强治理的后端系统它要同时扛住大量并发的模型调用请求且每个请求耗时可能从几百毫秒到几十秒不等不同部门、不同应用之间的资源隔离和配额控制模型供应商不稳定时的熔断、降级、重试会话上下文这种有状态数据的读写。这些需求单靠一个 Spring Boot 单体是撑不住的。所以 QuickBlue 这类底座普遍采用 Spring Cloud 体系来做服务拆分用 Sentinel 做流量控制和熔断用 Redis 集群扛会话和缓存用 JDK 21 这种较新的运行时来吃虚拟线程带来的并发红利。下面几节我会逐个展开这些技术选型背后的真实理由。1.3 它到底解决谁的什么问题把使用者分个类你会更清楚底座的价值边界角色没有底座的痛点有底座之后业务开发每个功能自己调模型重复造轮子调统一接口专注业务逻辑算法/提示词工程师提示词散落在各处改一次要发版提示词集中管理热更新运维不知道谁在调、调了多少、花了多少统一监控、配额、告警安全合规敏感数据流向不可控统一审计、脱敏、权限管理层成本黑盒无法核算按应用/部门计费这张表基本就是企业采购或自研底座时的需求清单。QuickBlue 的定位就是把这五类诉求收敛到一个平台上。2. QuickBlue 的微服务拆分思路与边界2.1 拆分的核心原则按变更频率和伸缩需求切微服务拆分最忌讳按技术分层硬切比如 controller 一层、service 一层那样只会把单体拆成一堆分布式单体。QuickBlue 这类底座的合理拆法是按业务能力的变更频率和伸缩特性来切。我总结下来大致是这么几块网关服务统一入口负责鉴权、限流、路由、协议转换。它是所有流量的第一道闸门。模型接入服务屏蔽不同模型供应商的 API 差异做统一适配。这块变更最频繁因为模型厂商接口三天两头改。提示词与编排服务管理提示词模板、版本、变量以及多步编排逻辑。会话与上下文服务管理多轮对话的状态读写频繁对 Redis 依赖重。权限与租户服务管理应用、密钥、配额、租户隔离。计费与审计服务统计 token 消耗、调用次数落审计日志。工具与插件服务管理模型可调用的外部工具函数调用。这么切的直接好处是模型接入服务可以独立扩容和发版不会因为改一个供应商适配就重启整个系统会话服务可以单独加 Redis 节点计费服务可以异步削峰不阻塞主链路。2.2 网关层为什么是重中之重网关是整个底座的咽喉。所有请求都从这里过所以鉴权、限流、灰度、日志埋点全压在这一层。用 Spring Cloud Gateway 是主流选择原因很实际它是响应式的基于 Netty能扛住大量长连接和慢请求——而 AI 请求恰恰就是典型的慢请求一次生成可能要几十秒。这里有个我踩过的坑千万别在网关层做同步阻塞的鉴权查询。早期我们把租户配额校验直接写成同步查数据库结果高峰期网关线程池被打满整个底座雪崩。正确做法是把配额、密钥这类高频读的数据放 Redis网关只做一次 Redis 查询甚至用本地缓存加短 TTL 兜一层。提示网关层的超时设置要和后端模型调用超时对齐。如果网关 30 秒超时而后端模型要跑 60 秒你会看到大量请求成功但客户端报错的诡异现象。2.3 服务间通信同步还是异步要想清楚底座内部的服务调用不是所有都适合同步。我的经验是分两类处理主链路同步网关到模型接入、到会话服务这些必须在一次请求内完成用 OpenFeign 或 WebClient 同步调用。旁路异步计费、审计、日志统计这些绝不能阻塞主链路一律走消息队列异步落库。很多团队一开始图省事把计费也做成同步结果模型返回之后还要等计费写库用户感知的延迟凭空多出几百毫秒。改成异步之后主链路只发一条消息就返回体验立刻不一样。3. Spring Cloud 全家桶在底座里的具体分工3.1 注册中心与配置中心Nacos 还是别的服务注册和配置管理是微服务的地基。QuickBlue 这类项目普遍选 Nacos理由很朴素它同时把注册中心和配置中心做了省得再单独搭一套 Config。而且配置热更新对底座特别重要——提示词、限流阈值、模型权重这些参数你不可能每次改都重启服务。配置热更新这块有个细节值得说Nacos 的配置变更推送是长轮询机制客户端监听后本地刷新。但如果你在代码里把配置读进了静态变量热更新是不会生效的。正确姿势是用RefreshScope或者监听器动态读取这一点新手特别容易翻车。3.2 Sentinel 做流控和熔断的真实配置思路Sentinel 在底座里的角色是保险丝。模型供应商是最不可控的一环它可能突然变慢、突然报错、突然限流。没有熔断一个供应商抖动就能拖垮整个底座。我一般这么配对每个模型供应商单独设资源比如model.provider.a、model.provider.b这样一家挂了不影响另一家。流控用 QPS 模式阈值根据供应商的配额和自身容量定别拍脑袋。熔断用慢调用比例模式比如 RT 超过 5 秒且比例超过 50% 就熔断熔断时长设 10 到 30 秒给供应商恢复的时间。降级逻辑要提前写好A 模型熔断后自动切 B 模型或者返回缓存结果而不是直接抛错给用户。// Sentinel 资源定义与降级示例伪代码示意思路 SentinelResource( value model.provider.a, blockHandler handleBlock, fallback fallbackToBackupModel ) public String callProviderA(String prompt) { return providerAClient.generate(prompt); } public String fallbackToBackupModel(String prompt, Throwable t) { // 主模型不可用时切备用模型 return providerBClient.generate(prompt); }这里的关键认知是熔断不是故障是设计的一部分。你要假设供应商一定会挂然后提前设计好挂了之后怎么办。3.3 Redis 集群在底座里到底存了什么Redis 在底座里绝不是缓存一下这么简单它承担了好几类关键数据会话上下文多轮对话的历史消息读写极频繁且要求低延迟。配额计数器每个应用/租户的实时调用次数用原子操作自增。限流令牌配合 Sentinel 或自研限流做分布式计数。密钥与权限缓存网关鉴权的高频读数据。幂等键防止重复请求重复计费。为什么强调集群而不是单机因为会话和配额是强依赖Redis 一挂整个底座就瘫。集群模式比如 Redis Cluster 或哨兵能提供故障转移。但要注意集群模式下多 key 操作和事务会受限设计 key 的时候要保证同一会话的数据落在同一个 slot通常用 hash tag 把会话 ID 包起来比如session:{12345}:messages。注意会话数据的过期策略要仔细设计。设太短用户聊到一半上下文丢了设太长内存爆炸。我一般按业务场景设 30 分钟到 2 小时滑动过期每次读写都续期。4. JDK 21 与虚拟线程底座性能的隐藏变量4.1 为什么底座特别吃并发模型AI 应用底座是典型的IO 密集型系统。一次请求里大部分时间都花在等模型返回、等 Redis、等数据库上CPU 其实很闲。传统的一个请求一个平台线程模型在这种场景下非常吃亏线程大部分时间在阻塞等待线程池很快就被占满吞吐上不去。这就是为什么 JDK 21 的虚拟线程对底座意义重大。虚拟线程由 JVM 调度阻塞时自动让出底层载体线程可以用极少的操作系统线程支撑海量并发请求。对底座这种高并发 长等待的场景几乎是量身定做。4.2 虚拟线程不是银弹这几个坑要避开我实测下来虚拟线程好用但有几个地方必须注意别在虚拟线程里用 synchronized 做长阻塞。虚拟线程遇到 synchronized 会 pin 住载体线程退化成平台线程优势全无。改用ReentrantLock。线程池要重新评估。用了虚拟线程之后很多原本为平台线程设计的池化配置反而成了瓶颈该去掉的去掉。数据库连接池仍是硬约束。虚拟线程能开百万个但数据库连接可能只有几十个。并发上去了连接池会成为新瓶颈要么调大要么用异步驱动。// 用虚拟线程执行器处理模型调用JDK 21 try (var executor Executors.newVirtualThreadPerTaskExecutor()) { FutureString future executor.submit(() - modelClient.generate(prompt)); String result future.get(60, TimeUnit.SECONDS); }4.3 升级 JDK 21 前要做的兼容性检查从 JDK 8 或 11 升到 21不是改个版本号就完事。我建议按这个清单过一遍依赖库是否支持 21尤其是字节码增强类的框架某些老版本会有反射问题。有没有用到被移除的内部 API比如sun.misc.*。GC 策略要不要调整21 上 G1 和 ZGC 表现都不错长会话场景可以试试 ZGC 的低延迟。虚拟线程先小范围灰度别一上来全量切。5. 企业为什么绕不开这层底座5.1 成本失控是压垮自研 AI 的第一根稻草我见过最典型的场景三个业务团队各自接模型各自写调用代码各自买额度。月底一算账谁花了多少完全说不清重复调用、无效调用一大堆。底座的价值在这里体现得最直接——统一入口意味着统一计量。每一次调用都经过底座token 消耗、调用次数、响应时间全部可统计按应用、按部门、按项目维度出账单。这不是省钱的小事而是让 AI 投入变得可管理。没有计量就没法做预算也没法判断哪个功能值得继续投入。5.2 安全与合规数据不能裸奔企业数据一旦流向外部模型风险是实打实的。底座在这里能做几件事统一脱敏请求出去之前把身份证、手机号、内部代号这类敏感字段替换掉。统一审计谁在什么时候、用什么提示词、调了哪个模型、返回了什么全程留痕。统一权限不是谁都能调所有模型按角色和应用授权。数据边界控制哪些数据允许出企业、哪些只能走私有化模型在底座层强制。这些如果让每个业务团队自己做几乎不可能做齐。放在底座统一做才有一致性。5.3 模型会换业务不该跟着重写这是最容易被低估的一点。今天用 A 模型明天可能因为价格、效果、合规换成 B 模型。如果模型调用逻辑散落在各个业务代码里换一次模型就是一场灾难。底座把模型调用抽象成统一接口换模型只需要在底座改适配层业务代码一行不动。提示设计模型适配层时尽量用能力而不是模型名来定义接口比如chat、embedding、rerank而不是callGPT4。这样上层业务和具体模型彻底解耦。6. 落地 QuickBlue 这类底座的实操顺序6.1 别一上来就追求大而全我见过太多团队规划底座的时候画了一张巨复杂的架构图结果半年过去一个能用的功能都没有。正确的做法是先跑通最小闭环网关 模型接入 一个最简单的鉴权让业务能调通一次模型调用。这个闭环跑通之后再逐步加会话、加计费、加熔断。优先级我一般这么排统一模型接入解决能调鉴权与配额解决谁能调、调多少会话与上下文解决多轮对话熔断降级解决稳定计费审计解决算账提示词管理与编排解决好用6.2 灰度与回滚机制必须一开始就有底座是所有 AI 功能的入口它出问题就是全公司 AI 功能一起挂。所以灰度发布和快速回滚不是以后再说的事而是第一天就要设计。我的做法是网关层支持按应用、按用户比例灰度路由配置中心的所有变更都可回滚且保留历史版本关键服务保留上一版本镜像出问题一键切回。6.3 监控指标要盯哪几个底座上线后这几个指标必须实时看指标含义异常信号请求成功率调用成功比例突降说明供应商或链路有问题P99 延迟长尾响应时间飙升说明有慢请求堆积熔断触发次数熔断被激活的频率频繁触发说明供应商不稳配额使用率各应用配额消耗接近上限要提前告警Redis 命中率缓存有效性下降说明缓存策略要调这几个指标配好告警基本能覆盖 80% 的线上问题。7. 几个我踩过的坑和对应经验7.1 会话上下文无限增长早期没做上下文裁剪用户聊得越久发给模型的上下文越长token 成本飙升还经常超模型的最大长度限制。后来加了滑动窗口 摘要压缩保留最近 N 轮原文更早的用模型压缩成摘要。成本立刻降下来效果也没明显损失。7.2 重试引发的重复计费模型调用超时后自动重试结果第一次其实成功了只是响应慢导致重复调用、重复计费。解决办法是引入幂等键每次请求带唯一 ID底座侧记录已处理的 ID重试时先查幂等表命中就直接返回上次结果。7.3 供应商限流没做本地感知某次供应商悄悄把我们的配额调低了底座还在拼命发请求结果大量 429 错误。后来加了自适应限流一旦检测到供应商返回限流错误本地主动降低发送速率等恢复后再逐步放开。这个机制救过好几次场。7.4 配置热更新没生效前面提过配置读进静态变量导致热更新失效。这个坑我踩过两次后来统一规范所有需要热更新的配置一律通过配置监听器动态获取禁止在类初始化时缓存。8. 关于选型与自研的一点个人判断到底是用 QuickBlue 这类现成底座还是自己从零搭我的判断标准很简单看你的团队有没有精力长期维护一套微服务基础设施。如果团队本来就有成熟的 Spring Cloud 体系、有运维能力、有专人负责中间件那自研底座是合理的因为你能完全掌控。但如果团队只是想快速让 AI 功能上线把大量时间花在搭注册中心、配 Sentinel、调 Redis 集群上那就是本末倒置。底座这东西价值在于稳定地存在而不是炫技。它最好的状态是业务方几乎感觉不到它的存在只觉得调 AI 很顺、很稳、很省心。真到了这个状态这层底座就算做成了。我自己在推进这类项目时最大的体会是先把最小闭环跑稳再谈架构优雅很多看起来必须一开始就设计好的东西其实可以等业务量上来之后再补过早优化反而拖慢落地节奏。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进