1. 从一个真实困境说起:为什么“能跑起来的 AI”和“能上线的 AI”是两回事
过去一年多,我参与过好几个企业内部的 AI 应用落地项目,从最早的“拿个开源模型跑个 Demo”,到后来要给几百人的业务团队交付一个真正能用的智能问答、智能检索、智能工单系统。踩坑踩到最后,我发现一个特别扎心的规律:Demo 阶段拼的是模型能力,上线阶段拼的是工程底座。
你随便找个会写 Python 的同事,半天就能搭出一个能对话的界面,接个模型 API,前端套个壳,看起来挺唬人。可一旦要接入企业内部的权限体系、要对接十几个业务系统的数据、要保证并发上来之后不崩、要能追溯每一次调用的日志、要做灰度发布和版本回滚,这套“玩具”立刻就散架了。模型还是那个模型,问题出在它脚下没有一块稳的地基。
这就是AI 应用底座这个概念被反复提起的原因。而QuickBlue正是围绕这个思路去做的一套工程化方案——它不是一个模型,也不是一个单纯的聊天工具,而是一层专门为 AI 应用服务的微服务基础设施。你可以把它理解成:在模型和业务之间,铺一层标准化的、可复用的、企业级的“承重墙”。
这篇文章我想聊的不是 QuickBlue 的官方介绍,而是从一个一线开发者的角度,把“企业为什么需要一个 AI 应用底座”这件事拆开讲透。涉及到的技术栈会围绕微服务、Spring Cloud、JDK 21这些关键词展开,因为底座这东西,说到底就是一套架构选型和工程约束的集合。如果你正在做企业内部 AI 平台,或者正在纠结“要不要自己搭一套底座”,那这篇内容应该能帮你少走不少弯路。
2. 先搞清楚:AI 应用底座到底“底座”了什么
2.1 从“模型即一切”到“模型只是零件”的认知转变
刚接触 AI 应用的人,脑子里通常有个默认假设:只要模型够强,应用就够好。这个假设在 Demo 阶段成立,在工程阶段彻底失效。原因很简单,企业级 AI 应用要处理的问题,模型只占其中一小部分。
我拿一个具体的场景举例。假设你要做一个“智能合同审查助手”,业务方期望的是:员工上传一份合同,系统自动比对历史合同库、识别风险条款、给出修改建议、记录审查痕迹、并且只有法务部的人能看敏感条款。这里面模型负责什么?负责“识别风险条款”和“给出建议”这两步。剩下的比对、权限、留痕、审计、并发、存储,全是工程问题。
如果把这些工程问题全部塞进一个单体应用里,会发生什么?模型一升级,整个应用要重新部署;权限逻辑一改,测试要全量回归;某个业务系统接口挂了,整个助手跟着不可用。这就是典型的“模型绑架了应用”。
AI 应用底座要做的第一件事,就是把模型能力从业务逻辑里解耦出来。模型是一个可替换的零件,业务是一套稳定的流程,中间靠底座来衔接。QuickBlue 这类方案的定位就在这里——它不跟你抢模型的事,它负责让模型“插得上、换得掉、管得住”。
2.2 底座要解决的四个核心问题
我把企业 AI 应用落地时最常撞的墙归纳成四类,这也是判断一个底座是否合格的标准。
第一类是接入问题。企业内部往往同时存在多个模型来源:公有云的大模型 API、私有化部署的开源模型、针对特定任务微调的小模型。如果没有统一接入层,每个业务团队各接各的,最后就是一堆重复代码和一堆不一致的调用方式。底座要提供统一的模型网关,把不同来源的模型抽象成一致的接口。
第二类是编排问题。一个真实的 AI 应用很少是“一问一答”这么简单,往往是多步骤的:先检索知识库,再调用模型生成,再调用工具函数校验,最后格式化输出。这套编排逻辑如果写死在业务代码里,改一次流程就要改一次代码。底座要提供可配置的编排能力,让流程调整不依赖发版。
第三类是治理问题。谁在调用、调用了多少次、花了多少 token、响应时间多长、有没有触发敏感内容、出错时怎么降级——这些问题在 Demo 阶段没人关心,在上线阶段全是刚需。底座要内置可观测性和治理能力,而不是让每个业务团队自己造轮子。
第四类是扩展问题。业务是会长大的,今天只做问答,明天可能要做 Agent,后天可能要接入语音。底座如果一开始就把架构做死,后面每加一个能力都要伤筋动骨。所以底座的架构必须是可插拔的,这也是为什么微服务架构在这个场景下几乎是必然选择。
2.3 为什么是微服务,而不是单体
有人会问,一个 AI 应用底座,用单体架构不行吗?小团队用单体确实更省事,但企业级场景下,微服务的优势是压倒性的。
我列几个实际对比。单体架构下,模型网关、编排引擎、权限服务、日志服务全部在一个进程里,任何一个模块的内存泄漏都会拖垮整个应用。微服务架构下,这些模块独立部署,模型网关崩了不影响权限校验,日志服务压力大可以单独扩容。这是故障隔离的价值。
再比如技术栈。模型相关的部分可能用 Python 生态更顺手,但企业原有的业务系统大量是 Java 技术栈。单体架构下你只能二选一,微服务架构下可以让不同服务用不同语言,通过标准协议通信。这是技术异构的价值。
还有独立演进。AI 领域变化太快,今天流行的编排框架明天可能就被替代。微服务架构下,你只需要替换编排服务这一个模块,其他部分不受影响。单体架构下,换框架等于重写应用。
所以 QuickBlue 选择微服务作为底座架构,不是赶时髦,而是被企业级场景的真实需求逼出来的。接下来我会具体讲这套架构在技术选型上的考量。
3. 技术选型拆解:Spring Cloud、JDK 21 与微服务的组合逻辑
3.1 为什么是 Spring Cloud 生态,而不是别的
聊到 Java 微服务,绕不开 Spring Cloud。但最近几年有个很现实的问题:Spring Cloud Alibaba 部分组件停更了,这让很多正在选型的企业犹豫。我自己的判断是,选型要看的是“核心组件是否活跃”,而不是“整个生态是否统一更新”。
Spring Cloud 的核心价值在于它定义了一套微服务标准:服务注册发现、配置中心、负载均衡、熔断限流、网关路由。这些标准对应的实现可以换,但标准本身是稳定的。比如服务注册发现,你可以用 Eureka、Consul、Nacos,接口抽象是一致的。熔断限流,你可以用 Hystrix、Resilience4j、Sentinel,编程模型大同小异。
QuickBlue 这类底座选择 Spring Cloud,本质上是选择了一套成熟的、有大量生产验证的微服务编程模型。企业里现有的 Java 团队大概率已经熟悉这套东西,学习成本低,招人也好招。这是很务实的考量。
至于 Spring Cloud Alibaba 停更的问题,我的建议是:核心链路尽量用 Spring Cloud 官方组件,阿里系组件按需选用。比如配置中心和注册中心,Nacos 依然是国内最主流的选择,社区活跃度也够。但像 Sentinel 这种,如果团队没有强依赖,可以考虑用 Resilience4j 替代,后者是 Spring Cloud 官方推荐的熔断方案。选型的核心原则是:不要把所有鸡蛋放在一个篮子里,关键能力要有备选方案。
3.2 JDK 21 带来的实际收益
JDK 21 是 LTS 版本,这个不用多说。但我想聊的是它在 AI 应用底座这个具体场景下,能带来什么实际好处。
最直接的是虚拟线程。AI 应用的一个典型特征是 IO 密集:调用模型 API 要等、查向量数据库要等、调外部工具要等。传统线程模型下,每个请求占一个线程,线程池一满就排队。虚拟线程让“一个请求一个线程”的模型重新变得可行,而且开销极低。我实测过一个场景,同样的硬件配置,从 JDK 17 换到 JDK 21 并启用虚拟线程后,模型网关的并发吞吐提升了接近一倍。这个收益在底座层面是实打实的。
其次是模式匹配和记录模式。底座的代码里有大量对请求、响应、配置对象的类型判断和结构解析。JDK 21 的模式匹配让这类代码简洁很多,可读性上来了,维护成本就下去了。别小看这点,底座是要长期维护的东西,代码可读性直接决定了后续迭代的效率。
还有分代 ZGC。AI 应用的内存占用普遍偏高,尤其是涉及向量计算和大量文本处理的时候。分代 ZGC 在保证低延迟的同时,对内存的回收效率比老版本更好。对于需要长时间稳定运行的服务来说,GC 停顿少一点,线上抖动就少一点。
提示:升级 JDK 21 之前,务必确认依赖的框架版本是否兼容。Spring Boot 3.2 及以上对 JDK 21 的支持比较完善,如果还在用 Spring Boot 2.x,升级 JDK 的收益会被框架限制住。
3.3 微服务拆分:拆到什么粒度才算合适
微服务拆分是门手艺,拆太粗等于没拆,拆太细运维成本爆炸。AI 应用底座的拆分,我建议按能力边界来,而不是按技术分层来。
什么叫按能力边界?就是每个服务对应一个完整的、可独立交付的能力。比如:
| 服务名称 | 核心职责 | 拆分理由 |
|---|---|---|
| 模型网关服务 | 统一接入各类模型,处理鉴权、限流、重试 | 模型来源多,变化频繁,需要独立演进 |
| 编排服务 | 定义和执行 AI 工作流 | 流程逻辑复杂,调整频繁,独立部署便于快速迭代 |
| 知识库服务 | 文档解析、向量化、检索 | 资源消耗大,需要独立扩容 |
| 权限服务 | 统一鉴权和数据隔离 | 与业务强相关,但逻辑稳定,可复用 |
| 可观测服务 | 日志、指标、链路追踪 | 横切关注点,独立部署避免影响主链路 |
这个拆法的逻辑是:变化频率不同的东西分开,资源消耗特征不同的东西分开,横切关注点单独拿出来。模型网关变化快,权限服务变化慢,放一起就是互相拖累。知识库服务吃内存,编排服务吃 CPU,放一起就是资源浪费。
至于拆到多细,我的经验法则是:一个服务如果两个开发能在一周内改完并独立上线,粒度就差不多了。如果改一个功能要协调三个服务同时发版,说明拆得太细;如果一个服务大到需要五个人同时改还经常冲突,说明拆得太粗。
4. 实操落地:从零搭一个 AI 应用底座的关键环节
4.1 环境准备与基础依赖
动手之前,先把地基打牢。我列一下我实际用的环境配置,这套配置在中小规模企业场景下够用,大规模场景按比例扩容即可。
- JDK:21(LTS),推荐用 Temurin 或 Oracle 官方版本
- 构建工具:Maven 3.9+ 或 Gradle 8+
- Spring Boot:3.2.x 及以上
- Spring Cloud:2023.0.x(对应 Spring Boot 3.2)
- 注册中心/配置中心:Nacos 2.3+
- 网关:Spring Cloud Gateway
- 熔断限流:Resilience4j 或 Sentinel(二选一)
- 容器化:Docker + Docker Compose(开发环境),K8s(生产环境)
这里有个容易踩的坑:Spring Cloud 版本和 Spring Boot 版本必须严格对应。我见过太多人因为版本不匹配,启动时报一堆莫名其妙的类找不到错误。建议直接查 Spring Cloud 官方发布的版本兼容表,别凭感觉选。
4.2 模型网关服务的核心实现
模型网关是整个底座的门面,所有模型调用都从这里走。它的核心职责是:屏蔽不同模型供应商的差异,对外提供统一接口。
我设计的接口抽象大概是这样:
public interface ModelProvider { String getName(); ModelResponse invoke(ModelRequest request); boolean supports(String modelType); }每个模型来源实现这个接口,比如OpenAIProvider、LocalModelProvider、FineTunedProvider。网关根据请求里的模型标识,路由到对应的 Provider。这样新增一个模型来源,只需要加一个实现类,不用动其他代码。
网关层还要处理几件事。鉴权:校验调用方是否有权限使用某个模型。限流:防止某个业务方把模型配额打满。重试与降级:模型调用失败时,按策略重试或切换到备用模型。计量:记录每次调用的 token 消耗,用于成本核算。
限流这块我推荐用 Resilience4j 的RateLimiter,配置示例如下:
resilience4j: ratelimiter: instances: modelGateway: limitForPeriod: 100 limitRefreshPeriod: 1s timeoutDuration: 500ms这个配置的意思是:每秒最多 100 次调用,超过的请求最多等 500ms,等不到就拒绝。参数怎么定?看你的模型供应商给的配额,以及你的业务峰值。我一般会留 20% 的余量,避免突发流量直接把配额打满。
4.3 编排服务的流程定义
编排服务是底座的“大脑”,负责把模型调用、知识检索、工具调用这些步骤串起来。我的做法是用声明式的流程定义,而不是硬编码。
一个典型的编排流程用 YAML 描述大概长这样:
flow: name: contract-review steps: - id: retrieve type: knowledge-retrieval params: knowledgeBase: contract-history topK: 5 - id: analyze type: model-invoke params: model: gpt-4 prompt: "基于以下历史合同,分析当前合同的风险条款:{{retrieve.result}}" - id: validate type: tool-invoke params: tool: risk-validator input: "{{analyze.result}}"编排引擎解析这个定义,按顺序执行每一步,把上一步的输出作为下一步的输入。这样调整流程只需要改 YAML,不用改代码、不用发版。
这里的关键设计是上下文传递。每一步的输出要能被后续步骤引用,我用的是类似模板变量的方式,{{stepId.result}}这种语法。实现上可以用 SpEL 或者简单的字符串替换,看团队熟悉程度。
注意:编排流程的异常处理一定要设计好。某一步失败了,是整体回滚还是跳过继续?是重试还是直接返回错误?这些策略要在流程定义里可配置,不能写死。
4.4 知识库服务的向量化与检索
知识库服务负责把企业文档变成可检索的向量,这是 RAG(检索增强生成)的基础。核心流程是:文档解析 → 文本分块 → 向量化 → 存入向量库 → 检索时反向查询。
文本分块是个容易被低估的环节。分块太大,检索精度下降;分块太小,上下文丢失。我的经验值是500 到 800 个 token 一块,块之间保留 10% 到 20% 的重叠。重叠是为了避免关键信息刚好被切在边界上。
向量库的选型,中小规模用 pgvector 就够了,直接挂在现有的 PostgreSQL 上,运维成本低。大规模场景可以考虑 Milvus 或 Qdrant。选型的核心考量是检索延迟和召回率的平衡,以及团队是否有能力维护。
检索这块有个实用技巧:混合检索。纯向量检索对语义相似的内容效果好,但对精确匹配的关键词(比如合同编号、产品型号)效果差。我的做法是向量检索和关键词检索各跑一遍,然后做结果融合。实测下来,混合检索的召回率比纯向量检索高 15% 到 20%。
4.5 可观测性:别等出事了才想起来加日志
可观测性是底座里最容易被忽视、但上线后最救命的部分。我建议从第一天就把这三样东西加上:结构化日志、指标采集、链路追踪。
结构化日志用 Logback + JSON 格式,每条日志带上 traceId、userId、modelName 这些关键字段。这样出问题时能快速定位是哪个用户、哪个模型、哪次调用出的问题。
指标采集用 Micrometer + Prometheus,重点采集这几类指标:模型调用次数、调用延迟分布、token 消耗量、错误率、限流触发次数。这些指标直接对应业务健康度,比单纯的 CPU、内存指标有用得多。
链路追踪用 Micrometer Tracing + Zipkin 或 Jaeger。AI 应用的调用链往往很长:网关 → 编排 → 模型 → 工具 → 数据库。没有链路追踪,排查问题基本靠猜。
5. 常见问题与排查技巧实录
5.1 模型调用超时怎么排查
这是最高频的问题。模型调用超时,原因可能有很多层,我一般按这个顺序排查。
先看网关层日志,确认请求是否成功发出。如果网关层就超时了,问题可能在网络或模型供应商侧。再看模型供应商的响应时间,如果供应商侧正常,那就是我们自己的处理逻辑慢。最后看编排层的耗时分布,确认是模型调用慢还是前后处理慢。
我整理了一个速查表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 所有模型调用都超时 | 网络问题或供应商故障 | 检查网络连通性,查看供应商状态页 |
| 特定模型超时 | 该模型负载高或配额耗尽 | 查看该模型的调用指标和配额使用情况 |
| 偶发超时 | 网络抖动或 GC 停顿 | 查看 GC 日志和网络监控 |
| 高峰期超时 | 并发超过模型承载能力 | 检查限流配置,考虑扩容或排队策略 |
5.2 微服务间的数据一致性怎么保证
AI 应用底座里,跨服务的数据一致性是个绕不开的问题。比如编排服务调用模型网关,模型网关扣了配额,但编排服务后续步骤失败了,这个配额要不要退?
我的做法是尽量用最终一致性,避免分布式事务。配额扣减用“预扣 + 确认/回滚”的模式:调用前预扣,调用成功确认,调用失败回滚。这样即使中间步骤失败,配额也能正确归还。
对于确实需要强一致性的场景,比如计费,我建议把计费逻辑收敛到单个服务里,不要跨服务。跨服务的强一致性,代价太高,收益太低。
5.3 版本升级导致的服务不兼容
微服务架构下,服务独立部署意味着版本可能不一致。老版本的编排服务调用新版本的模型网关,接口对不上,直接报错。
我的经验是:接口变更必须向后兼容。新增字段可以,删除字段不行;新增接口可以,修改接口签名不行。如果确实要破坏性变更,走版本号,比如/api/v1/invoke和/api/v2/invoke并存,老服务继续用 v1,新服务用 v2,等老服务全部下线后再移除 v1。
还有个小技巧:契约测试。在 CI 流程里加上服务间的契约测试,任何一方改了接口,测试会立刻发现不兼容。这个投入在服务数量多了之后,回报非常明显。
5.4 向量检索召回率低怎么办
召回率低是 RAG 场景的常见问题。我一般从三个方向优化。
分块策略:检查分块大小和重叠比例是否合理。太小或太大都会影响召回。嵌入模型:不同的嵌入模型对中文的支持差异很大,选一个在中文语料上表现好的。检索策略:从纯向量检索改成混合检索,加入关键词匹配。
还有一个容易被忽视的点:查询改写。用户的原始问题往往口语化、有歧义,直接拿去检索效果差。可以先让模型把问题改写成更规范的检索查询,再去做向量检索。这一步的投入产出比很高。
6. 我踩过的坑和几条实在建议
聊了这么多架构和实现,最后说几条我在实际项目里踩出来的经验,都是文档里不会写的。
第一条:不要一开始就追求大而全。我见过团队一上来就要做“企业级 AI 中台”,结果三个月过去连个能用的问答都没上线。正确的做法是先做一个最小可用的底座,能跑通“接入模型 → 编排流程 → 返回结果”这条链路,然后再逐步加能力。底座是长出来的,不是设计出来的。
第二条:模型网关的抽象要克制。我一开始想把所有模型的能力都抽象成统一接口,结果发现不同模型的能力差异太大,强行统一反而限制了使用。后来改成“核心接口统一,扩展能力透传”,既保证了通用性,又不牺牲灵活性。
第三条:可观测性要前置。我第一个项目是上线后才补的日志和监控,结果上线第一周出了个问题,排查了整整两天。第二个项目从第一天就加上了链路追踪,同样类型的问题半小时定位。这个差距是巨大的。
第四条:给模型调用留足超时和重试预算。模型调用比普通接口慢得多,超时时间设太短会频繁失败,设太长会拖垮上游。我的经验值是:普通模型调用超时设 30 秒,复杂推理设 60 秒,重试最多两次,且重试要有退避策略。
第五条:别忽视成本。模型调用是要花钱的,尤其是大规模使用的时候。底座层面一定要有 token 计量和成本核算,按业务方、按模型、按时间段统计。我见过一个团队因为没做计量,某个月账单出来才发现有个业务方在疯狂调用,成本超预算好几倍。
这套东西搭起来不轻松,但一旦搭好,后面每做一个新的 AI 应用,都能直接复用底座的能力,边际成本会越来越低。这也是为什么我一直认为,企业做 AI 落地,底座这件事值得认真投入。