在很长一段时间里,我们处理系统压力时几乎形成了一种条件反射:流量涨了,加机器;规则多了,拆服务;并发高了,上缓存、上队列、上分库分表。这套“先扩展再说”的思路,在过去十年里确实解决了很多问题,也沉淀了大量架构经验。
但最近我在几个项目里反复碰到同一种情况:团队花大力气做水平扩展、微服务拆分、规则引擎升级,最后发现真正的瓶颈并不是机器不够,而是系统里塞进了太多“需要预定义逻辑才能处理”的复杂度。而此时 AI 的介入方式,恰好可以改变这些复杂度的性质——于是问题变成:在决定 Scale 之前,是不是应该先让 AI 试试简化系统?
这篇文章想认真聊聊这个命题:为什么在 AI 时代,很多场景下可以“先别急着扩展”。我会从概念、架构演进、代码示例、决策清单和坑点几个维度展开,偏工程落地,不是纯概念讨论。
1. 背景与核心概念
1.1 Scale 到底指什么
Scale 在技术语境里通常翻译为“扩展”或“伸缩”,主要分两种:
- 垂直扩展:把单台机器做得更强,比如加 CPU、加内存、换 SSD。优点是改造成本低,但上限明显,价格也不友好。
- 水平扩展:增加机器数量,通过负载均衡、分布式存储、消息队列等方式把压力分摊到多台机器上。这是互联网架构应对高并发的标准手段。
过去我们对 Scale 的依赖,本质上是“用更多的计算资源去处理更多确定性的逻辑”。无论是数据库分片、微服务拆分、弹性伸缩,还是引入各类中间件,都是为了让系统在规则明确的前提下,能够线性扩展处理能力。
1.2 传统扩展的典型驱动因素
一个系统为什么要扩展?通常跑不掉这四类原因:
- 并发量上升:单位时间请求变多,单机处理不过来。
- 数据量膨胀:存储和查询压力变大,单个数据库开始成为瓶颈。
- 规则复杂度增长:业务逻辑越来越细,代码分支越来越多,维护成本急剧上升。
- 团队规模扩大:多人协作时,需要把代码和职责拆开,于是拆服务、拆应用。
前两类是“物理原因”,后两类其实是“逻辑原因”。而 AI 能带来的改变,恰恰集中在后两类上。
1.3 AI 为什么会影响扩展决策
AI 对扩展决策的影响,不是“可以让代码跑得更快”,而是“可以改变问题的复杂度结构”。
举个例子:传统客服工单系统里,要给不同类型的工单配置不同的处理流程,于是你写规则引擎、建配置中心、做流程编排,为了支撑这些规则,你需要更多的服务实例、更多的存储、更多的研发维护人手。但当你用语义模型直接理解工单内容、自动匹配处理方式时,一部分规则逻辑就不再需要“写死”在代码里,系统本身的复杂度就下降了。
复杂度下降之后,原来为了支撑复杂度而设计的扩展方案,就需要重新评估。这可能才是标题“Don‘t Scale Yet, Because of AI”最核心的逻辑:在动手扩展之前,先问一下,当前系统的复杂度能否用 AI 吸收掉。
2. 为什么过去我们总是优先 Scale
2.1 规则复杂度推动的系统膨胀
早期业务系统通常很直接:用户下单,那就创建订单;用户退款,那就走退款流程。但随着业务发展,规则会不断叠加:
- 不同用户等级不同折扣。
- 不同商品类目不同运费策略。
- 不同渠道来源不同优惠权益。
- 大促、秒杀、直播带货等场景又有各自独立的活动规则。
这些规则如果全部靠硬编码,代码会迅速膨胀。于是团队开始引入规则引擎、配置中心、工作流编排,再配合微服务拆分,把不同规则放进不同服务。服务变多之后,就需要服务注册中心、网关、配置管理、链路追踪,整套基础设施也水涨船高。
这套架构看起来很“分布式”,但本质上是在用架构手段应对规则复杂度。问题在于:规则越多,组合爆炸越严重,最终连规则引擎本身都变成需要维护的复杂系统。
2.2 高并发预期下的过度设计
很多团队在系统早期,就按照“未来一定会爆发流量”的假设去设计:消息队列、分布式缓存、读写分离、分库分表,全套上齐。
不能说这些设计完全错误,但确实存在“提前扩展”的问题。系统真实瓶颈还没出现,架构复杂度先上来了。而复杂架构带来的运维成本、研发成本、故障排查成本,往往比业务流量带来的压力更大。
2.3 组织分工带来的拆分冲动
还有一个经常被忽视的原因:团队组织方式会影响系统架构。
当团队从 5 人扩张到 50 人时,如果所有人仍然在一个单体应用里提交代码,合并冲突、发布协调、职责边界都会很痛苦。于是很自然地会按业务模块拆微服务,让每个小团队独立维护自己的服务。
这种“组织驱动”的扩展非常常见,但问题是:它扩展的是团队协作的边界,而不是系统真实需要的计算能力。在 AI 时代,如果 AI 可以帮助少数人维护更复杂的业务逻辑,那么“为了配合团队规模而拆分服务”的必要性也会下降。
3. AI 时代扩展逻辑的变化
3.1 从“编码规则”到“语义理解”
传统系统处理多样化输入,靠的是预设分支:
if (order.getChannel().equals("APP") && order.getAmount() > 100) { // 走 A 策略 } else if (order.getChannel().equals("H5") && user.getLevel() > 3) { // 走 B 策略 }这种写法在规则少时没问题,规则一多就难以维护。AI 的做法则不同:把输入文本和候选策略一起交给模型,让模型基于语义判断最合适的策略。
比如用零样本分类模型处理工单类型:
from transformers import pipeline classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") text = "我的订单超过24小时未发货,想要退款" candidate_labels = ["物流问题", "支付问题", "售后问题", "技术问题"] result = classifier(text, candidate_labels=candidate_labels) print(result["labels"][0], result["scores"][0])这段代码看起来简单,但它背后的意义是:你不再需要针对每一种“订单未发货 + 退款意图”的组合去写规则。只要训练数据足够、模型能力够用,系统可以理解用户表达背后的意图,并自动完成分类。
这直接降低了“规则组合爆炸”带来的扩展压力。
3.2 长尾问题不再需要更多代码
传统系统最怕的就是长尾需求。比如审核业务,可能有上百种异常情况需要判断,每种情况都要配置审批节点、通知对象、超时策略。这些逻辑全部落到代码里,系统会变得非常臃肿。
AI 可以把长尾问题统一收敛为“理解 + 决策”模式:
- 理解:用模型理解业务对象和上下文。
- 决策:用模型或规则模板输出处理建议。
- 兜底:对于置信度低的场景,转人工或者走默认策略。
这样一来,业务上虽然仍有上百种情况,但代码里不再需要上百个分支,系统复杂度大幅下降,扩展需求也随之减少。
3.3 架构简化的直接收益
架构简化带来的收益是可以量化的:
- 少一个服务,就少一套部署单元、少一份监控、少一份权限配置。
- 少一套中间件,就少一个故障点、少一份版本兼容问题。
- 少一段规则代码,就少一批测试用例、少一次版本发布、少一批线上告警。
这些收益在需求频繁变化时尤其明显。因为传统架构每增加一个规则,都需要“改代码 - 发版 - 扩容”的完整链路;AI 化之后,很多规则只需要调整提示词、更新示例、或者补充标注数据。
当然,这不是说 AI 可以完全替代规则和扩展,而是说:AI 改变了“规则增长必然导致系统膨胀”的因果关系。当复杂度不再等于代码量,扩展的紧迫性就会下降。
4. 实战案例:从规则引擎到 AI 简化架构
4.1 场景描述
假设我们有一个电商售后工单系统。用户提交售后申请,系统需要根据工单内容自动分配处理小组,并决定是否自动退款。
传统实现方案里,需要设置大量规则:
- 关键词命中:如果工单标题包含“退款”,走退款流程。
- 金额判断:如果退款金额小于 50 元,自动通过。
- 用户等级判断:VIP 用户优先处理。
- 渠道判断:不同渠道来源的工单走不同处理队列。
这些规则一开始只有 10 条,后来变成 200 条。每次规则变更都要改代码、发版、测试,系统需要持续扩容以支撑规则计算和配置下发。
4.2 传统扩展方案架构
传统架构大致是这样的:
客户端 ↓ 接入网关 ↓ 工单服务 ──→ 规则引擎服务 | ↓ | 规则配置中心 ↓ 消息队列 ──→ 处理 worker 集群 ↓ 订单服务 / 用户服务 / 消息通知服务规则引擎服务需要独立部署,并且通常需要多实例运行。规则数量越多,规则编译、匹配和下发压力越大,于是要继续加机器。这就是典型的“规则复杂度驱动扩展”。
传统规则判断的代码示例:
// 文件路径:src/main/java/com/example/aftersale/RefundRuleChecker.java public class RefundRuleChecker { private final RuleConfigCenter configCenter; public RefundRuleChecker(RuleConfigCenter configCenter) { this.configCenter = configCenter; } public boolean canAutoRefund(WorkOrder order) { // 规则1:金额小于 50 自动通过 if (order.getRefundAmount() < 50) { return true; } // 规则2:VIP 用户金额小于 200 自动通过 if (order.getUserLevel() >= 3 && order.getRefundAmount() < 200) { return true; } // 规则3:商品类目命中风险名单,不允许自动退款 if (configCenter.riskCategorySet().contains(order.getCategory())) { return false; } // 规则4:工单标题含特定关键词时转人工 for (String keyword : configCenter.manualKeywords()) { if (order.getTitle().contains(keyword)) { return false; } } return false; } }可以看到,规则一旦变多,这个类会越来越臃肿,而且每个规则都需要测试覆盖。更麻烦的是,规则之间有优先级,优先级错了就可能出现资损风险。
4.3 AI 化改造方案
用 AI 改造后,架构可以简化很多:
客户端 ↓ 接入网关 ↓ 工单服务 ──→ AI 意图分类服务 ↓ ↓ 基础数据服务 兜底规则(少量关键规则)AI 服务负责判断工单的意图和风险等级,返回处理建议。兜底规则只保留少数必须保证确定性的判断,比如“金额超过 5000 必须人工审批”“涉及法律纠纷必须转专业团队”。
这里给出一个基于 FastAPI 的轻量 AI 分类服务示例:
# 文件路径:app/main.py from fastapi import FastAPI from pydantic import BaseModel from transformers import pipeline app = FastAPI(title="WorkOrder Classifier") classifier = pipeline( "zero-shot-classification", model="facebook/bart-large-mnli", device=-1 # CPU 环境;有 GPU 时可改为 0 ) candidate_labels = [ "普通退款", "高价商品退款", "物流异常投诉", "商品质量投诉", "账号安全问题", "人工升级诉求", ] class WorkOrder(BaseModel): text: str @app.post("/classify") def classify(order: WorkOrder): result = classifier(order.text, candidate_labels=candidate_labels) return { "label": result["labels"][0], "score": result["scores"][0], "all_scores": dict(zip(result["labels"], result["scores"])), }对应的调用示例:
curl -X POST http://127.0.0.1:8000/classify \ -H "Content-Type: application/json" \ -d '{"text": "我买的手机用了一周屏幕就花了,要求退货退款,另外希望有人尽快联系我"}'预期返回类似:
{ "label": "商品质量投诉", "score": 0.87, "all_scores": { "普通退款": 0.21, "高价商品退款": 0.35, "物流异常投诉": 0.05, "商品质量投诉": 0.87, "账号安全问题": 0.02, "人工升级诉求": 0.11 } }拿到分类结果后,主业务服务只需要做两件事:
- 根据分类结果和置信度,决定走自动处理还是人工处理。
- 记录模型决策日志,方便后续分析和优化。
这样,原先 200 条规则中的大部分,都被语义理解模型替代了。
4.4 为什么要保留兜底规则
需要特别说明:AI 化改造不代表完全去掉规则。对于涉及资金安全、法律合规、用户人身安全等场景,必须保留确定性规则兜底。
这里的工程设计原则是:
- 高确定性、高风险的场景:用硬规则。
- 灵活性高、长尾场景:用 AI 模型。
- 无法判断的场景:走人工或默认安全策略。
所以在实际项目中,工单服务会先跑兜底规则,通过后再调 AI 分类服务,最后根据综合结果决定处理方式。
# 文件路径:app/service.py def process_work_order(text: str, amount: float): # 第一步:确定性兜底规则 if amount > 5000: return {"action": "manual_review", "reason": "高金额必须人工审批"} # 第二步:AI 分类 result = classifier(text, candidate_labels=candidate_labels) label = result["labels"][0] score = result["scores"][0] # 第三步:置信度不足时转人工 if score < 0.6: return {"action": "manual_review", "reason": "模型置信度不足"} if label == "普通退款" and amount < 200: return {"action": "auto_refund", "reason": f"AI 分类为普通退款,分数 {score}"} return {"action": "manual_review", "reason": f"AI 分类为 {label},需要人工确认"}4.5 架构对比与成本分析
从部署角度看,传统方案可能需要:
- 规则引擎服务 3 个实例。
- 配置中心 3 个节点。
- 支撑规则计算的缓存和消息队列若干。
- 对应的人工维护和发版成本。
AI 化方案初期则需要:
- 一个模型推理服务,可以单机 CPU 运行小型分类模型。
- 如果并发量高,可以加 GPU 或横向复制推理服务。
- 兜底规则依然存在,但通常只是简单的判断逻辑,不需要独立服务。
需要强调的是,AI 化不是“不用扩展”,而是“可以用更小的集群支撑同样复杂的业务”。当规则被模型吸收后,系统瓶颈从“规则计算”转变为“推理吞吐”,而推理吞吐是可以通过模型量化、缓存、批量推理等方式优化的。
5. 什么时候仍然应该 Scale
AI 能简化很多问题,但绝不是银弹。下面几类场景,扩展仍然是必要且理性的选择。
5.1 核心状态与事务
订单、支付、库存这类涉及资金和状态一致性的核心链路,必须依赖确定性事务。AI 可以在旁边做辅助判断,但不能替代数据库事务、分布式锁、幂等机制。
当这类核心链路的并发量确实上涨时,该分库分表就分库分表,该上分布式事务就上分布式事务。AI 在这里的作用有限,因为问题核心不是逻辑复杂度,而是物理吞吐量。
5.2 固定规则与合规约束
金融风控、税务计算、医疗数据脱敏等场景,规则由监管或合规要求定义,不允许模型“自由发挥”。这些规则必须硬编码,并且有完整审计。
这种情况下,即使规则数量很大,也不能简单用 AI 替代。合规规则的增长仍然会导致系统扩容,因为每条规则都需要计算资源来执行。
5.3 高并发读的确定性路径
对于商品详情页、用户信息查询这类高并发读场景,最好的方案仍然是缓存 + CDN + 静态化。AI 不适合放在高频主路径上增加延迟。
相反,AI 更适合放在非主路径,比如内容预处理、个性化排序、异常识别。主路径还是应该保持尽可能快的确定性响应。
所以,更准确的表述是:在决定扩展前,先判断问题的性质。如果问题是“逻辑太复杂”,先看 AI 能否简化;如果问题是“物理吞吐量不够”,则直接进入扩展流程。
6. 扩展决策评估清单
6.1 六个判断维度
我在项目里会用一个简单的评估清单来决定“该不该先做 AI 化改造,再考虑扩展”:
| 维度 | 问题 | 适合 AI 化 | 适合直接扩展 |
|---|---|---|---|
| 问题性质 | 是逻辑复杂度还是吞吐量瓶颈? | 逻辑复杂度 | 吞吐量瓶颈 |
| 规则稳定性 | 规则频繁变化还是长期稳定? | 频繁变化 | 长期稳定 |
| 容错空间 | 判断错误是否可接受? | 可接受或可兜底 | 不可接受 |
| 延迟要求 | 主路径响应要求是多少? | 非主路径或异步 | 毫秒级主路径 |
| 数据可得性 | 是否有足够的标注数据或示例? | 有 | 不依赖 |
| 审计要求 | 是否需要完整可解释的决策链? | 可以结合日志 | 必须硬编码 |
根据清单打分后,可以快速判断方向。
6.2 小成本验证方案
如果你想搞清楚 AI 能否简化当前系统,不需要一步到位建设大平台。推荐按这个顺序验证:
- 挑选一个复杂度最高的业务模块,例如工单分类、内容审核、售后建议。
- 整理 100 条真实业务数据,覆盖常见和长尾场景。
- 用零样本分类模型先跑一轮,观察准确率和置信度分布。
- 如果准确率达到预期,再用少量标注数据微调一个更小、更快的模型。
- 上线时加“降级开关”,置信度不足时回退到旧规则系统。
这套流程能在几天内给出初步结论,成本远低于一次大规模架构扩展。
6.3 架构降级开关
工程上一定要注意:AI 服务也可能故障或给出错误结果,线上必须有降级方案。实际项目中,可以设计如下配置:
# 文件路径:config/ai-feature-toggle.yaml ai: classification: enabled: true min_score: 0.6 fallback: rule-engine model: facebook/bart-large-mnli risk: high_amount_threshold: 5000 force_manual_categories: - "法律纠纷" - "人身安全"这段配置的意思是:AI 分类开启,但置信度低于 0.6 时回退到规则引擎;金额超过 5000 或命中特定风险类别时,强制走人工。这样,即使模型效果不理想,也不会造成资损或安全事件。
7. 常见问题与排查思路
7.1 模型输出结果不稳定
现象:相同文本在不同时间调用,返回的分类或建议不一致。
原因:大模型或零样本模型本身带有随机性;温度参数过高;模型输入上下文中包含无关信息。
排查步骤:
- 检查推理服务是否设置温度参数为 0。
- 检查输入文本是否有拼接错误或多余字符。
- 增加前缀提示,把任务描述写得更加明确。
- 增加输出约束,比如只允许返回候选标签中的某一项。
对于分类任务,我更推荐使用小型专用模型,而不是直接调用大模型。因为分类场景的标签空间有限,专用模型在小样本上表现更稳定,推理成本也更低。
7.2 AI 服务成为新瓶颈
现象:引入 AI 分类服务后,接口 RT 从 50ms 涨到 800ms,系统整体吞吐下降。
原因:模型推理是在线阻塞链路中完成的。
排查步骤:
- 确认 AI 调用是否在同步主链路。
- 如果是,考虑用消息队列改成异步处理。
- 对相同文本增加缓存,减少重复推理。
- 必要时使用量化模型或换更小的模型。
异步化改造的关键点:如果业务允许,AI 结果不必立刻返回给用户,可以先给用户一个默认结果,后台再更新。
7.3 新旧规则并存时的逻辑冲突
现象:AI 分类结果和旧规则结果不一致,导致同一个工单走了不同流程。
原因:两个系统并行运行,但决策入口没有统一优先级。
排查步骤:
- 明确新旧系统的边界,比如新系统处理 80% 流量,旧系统作为兜底。
- 在日志中记录两条路径的决策结果,方便对比。
- 灰度期间以“AI 建议 + 人工确认”为主,不建议直接全量自动化。
7.4 数据标注成本被低估
现象:模型初始效果不错,但随着业务发展,准确率下降,标注数据又不够。
原因:很多团队把 AI 化改造简单理解为“接一个模型就完事”,忽略了持续的数据运营。
排查步骤:
- 建立线上 badcase 回收机制,定期把模型判断错误的样本加入训练集。
- 设计轻量标注平台,让业务同学也能参与标注。
- 对于规则长期不变的场景,不要强行使用 AI,直接硬编码更经济。
8. 最佳实践与工程建议
8.1 区分“确定性逻辑”和“语义逻辑”
这是我在 AI 化改造中最重要的一条经验。系统里的逻辑可以分成两类:
- 确定性逻辑:事务、金额、状态机、权限、合规,必须精确控制。
- 语义逻辑:分类、推荐、审核、摘要、内容生成,允许模型输出建议。
设计系统时,不要让模型决定资金和状态,模型只做“前置理解”和“辅助建议”。最终决策权应该落在确定性规则和人工流程上。
8.2 建立模型置信度监控
对 AI 服务不能只监控可用性和延迟,还要监控置信度分布。
建议关注三个指标:
- 低置信度占比:低于阈值的请求占比过高,说明模型对当前业务数据理解不足。
- 误导率:模型高置信度但判断错误的样本,这是最危险的,需要专门回收。
- 标签分布偏移:线上标签分布和训练集分布差异过大,说明业务输入发生了变化。
这些指标可以通过日志系统采集,在监控面板上展示。
8.3 设计降级链路
AI 服务在设计时就要考虑降级,而不是故障后再补:
- 网络超时设置短超时,比如 2 秒。
- 超时后直接走默认策略,而不是阻塞等待。
- 默认策略必须是安全的,比如“转人工”而不是“自动退款”。
降级链路要定期演练,确保 AI 服务不可用时,核心链路仍然能工作。
8.4 保持团队的技术判断力
最后想多说一句:AI 不是万能药。过度依赖模型来处理所有问题,会带来新的风险。团队需要有足够的技术判断力,知道哪些问题适合让模型解决,哪些问题必须靠工程手段解决。
一个实用的原则是:
- 如果一段规则可以用三五行确定性代码写清楚,并且变化频率很低,就不要用模型。
- 如果规则已经多到团队维护不过来,组合爆炸严重,这时候再考虑 AI。
- 如果系统的核心问题是并发吞吐,AI 帮不上太多忙,老老实实做扩展。
9. 总结
回到开头的命题:“Don’t Scale Yet, Because of AI”。我想强调的不是“永远不要扩展”,而是“在看到流量和复杂度上升时,不要条件反射式地进入扩展流程”。
先花几天时间评估一下:当前的复杂度是规则逻辑造成的,还是真实吞吐量造成的?如果是前者,AI 可能帮助你用更小的系统承载同样的业务;如果是后者,扩展仍然是必须的。
AI 并不改变扩展的工具箱,但可以改变你对系统复杂度的判断方式。当一个系统的复杂度可以被模型吸收时,机器数量、服务数量、代码数量都不再是硬指标,业务响应速度才是。
实际项目中,最常见的错误不是“用错了 AI 模型”,而是根本没有思考就开始加机器、拆服务。希望这篇文章能给你提供一个更理性的决策框架。如果你正面临类似的扩展难题,不妨先从一个小模块开始做 AI 验证,再看值不值得推广到整个系统。