人工智能 后端架构设计与大模型服务集成实践的渐进迁移方案

存量流程接入 LLM 时,不宜把原有同步调用直接替换掉。先识别哪些环节可灰度、哪些结果需要兜底、哪些写操作必须保持确定性,再分阶段迁移。文中的延迟只用于说明风险类型。

为了实现存量系统向大模型智能路由架构的平滑迁移,需要设计一套分阶段的切换路径。通过影子模式比对、动态权重灰度切流、硬超时降级以及语义缓存拦截,能够在保证生产环境高可用的前提下完成架构升级。

1. 迁移第一阶段:影子模式(Shadow Mode)无感并行比对

在迁移初期,为了在不影响生产环境服务等级协议(SLA)的前提下验证 LLM 的分类准确率与延迟表现,应当首先构建基于消息订阅的影子运行链路。

在影子模式下,生产主流程依然由旧版规则引擎(RuleBasedClassifier)处理,并直接将结果返回给客户端。同时,主服务通过 Spring ApplicationEvent 机制将原始请求异步投递至 Kafka 消息队列的影子 Topic 中。独立的影子消费服务(Shadow Worker)监听该 Topic,异步发起大模型推理请求,随后将旧规则引擎与 LLM 的预测结果、耗时及 Token 消耗统一写入 ElasticSearch 或 ClickHouse 存储,用于离线 Diff 比对分析。

在影子运行期间,运维与开发人员可以通过分析影子日志评估两者的预测一致性率(Match Rate)与时延分布:

# 查看影子比对日志中预测分类不一致的条目
tail -f /var/log/app/llm-shadow-worker.log | grep 'STATUS=MISMATCH' | awk -F'|' '{print $2, $4, $6}'

# 统计特定时间段内 LLM 调用超时(如耗时大于 3000ms)的请求占比
grep "LLM_REQUEST_TIMED_OUT" /var/log/app/llm-shadow-worker.log | wc -l

假设在模拟压测环境运行一周后,离线分析数据表明 LLM 相比旧规则引擎将复杂工单的分类准确率提升了 24%,但 P99 延迟处于 2.8 秒水平。这为第二阶段引入动态权重切流与硬超时熔断机制提供了客观的数据基线。

2. 迁移第二阶段:基于 Dynamic Weight 的灰度切流与熔断兜底

确认大模型输出质量满足期望后,系统进入双轨并行与动态切流阶段。在 Spring Boot 应用内部可以设计 ClassifyRouterAdapter 路由适配器,结合配置中心(如 Apollo 或 Nacos)实时控制流量切分比例(从 0% 逐步放量至 100%)。

当请求命中 LLM 路由分支时,不能无限期等待模型响应,必须设置严格的 Future 硬超时限制(例如 1500 毫秒)。一旦 LLM 调用超时、遭遇网络抖动抛出异常,或返回的数据无法解析,系统必须在毫秒级内无缝回退到旧版规则引擎,确保前端业务无感知。

生产级路由适配器的 Java 实现代码如下:

@Component
@Slf4j
public class ClassifyRouterAdapter {

    private final RuleBasedClassifier legacyClassifier;
    private final LlmBasedClassifier llmClassifier;
    private final ExecutorService llmExecutor;

    @Value("${config.router.llm-weight:0}")
    private int llmWeight; // 0-100 动态灰度权重

    @Value("${config.router.llm-timeout-ms:1500}")
    private long llmTimeoutMs;

    public ClassifyRouterAdapter(RuleBasedClassifier legacyClassifier,
                                 LlmBasedClassifier llmClassifier,
                                 @Qualifier("llmThreadPool") ExecutorService llmExecutor) {
        this.legacyClassifier = legacyClassifier;
        this.llmClassifier = llmClassifier;
        this.llmExecutor = llmExecutor;
    }

    public ClassificationResult classify(TicketRequest request) {
        // 校验灰度权重抽样逻辑
        boolean triggerLlm = ThreadLocalRandom.current().nextInt(100) < llmWeight;

        if (!triggerLlm) {
            return legacyClassifier.classify(request);
        }

        // 提交异步推理任务并实施硬超时降级
        Future<ClassificationResult> future = llmExecutor.submit(() -> llmClassifier.classify(request));
        try {
            return future.get(llmTimeoutMs, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            log.warn("LLM 分类超时 [ticketId={}],耗时超过 {}ms,降级至旧规则引擎", request.getTicketId(), llmTimeoutMs);
            PrometheusMetrics.counter("llm_fallback_total", "reason", "timeout").inc();
            return legacyClassifier.classify(request);
        } catch (Exception e) {
            log.error("LLM 分类处理异常 [ticketId={}],紧急降级", request.getTicketId(), e);
            PrometheusMetrics.counter("llm_fallback_total", "reason", "exception").inc();
            return legacyClassifier.classify(request);
        }
    }
}

在灰度比例逐步扩大的过程中,持续压测与监控至关重要。可以通过 curl 动态探测路由接口在不同权重配置下的行为:

# 连续发送请求,观察响应中实际处理引擎类型的分布情况
for i in {1..10}; do
  curl -s -X POST http://localhost:8080/api/v1/ticket/classify \
    -H "Content-Type: application/json" \
    -d '{"ticketId":"TC-99281","content":"无法登录系统,提示密码错误"}' \
    | jq '{engine: .processingEngine, category: .categoryCode}'
done

3. 迁移第三阶段:全量接管与持久化安全防线构建

当灰度比例维持在 100% 运行一段时间,且 Prometheus 监控面板中 llm_fallback_total 降级指标稳定维持在较低水平(如低于 0.1%)时,即可开启全量收尾阶段。

全量接管并不意味着立即删除旧规则代码,而是将其收线重构为持久化的底层安全兜底网(Safety Net)。在这一阶段,架构调整应重点关注以下工程细节:

  1. 解耦同步阻塞与流式响应:对于交互式场景,避免长文本推理阻塞 Tomcat HTTP 线程池,改用 Server-Sent Events (SSE) 或 WebSocket 将模型输出流式推送到前端。
  2. 建立基于 Semantic Cache 的成本拦截:在请求到达大模型之前增加 Redis 语义缓存层。基于向量相似度计算,对相似度高于 0.95 的高频工单直接返回缓存结果,降低 Token 开销与接口响应时延。
  3. 隔离大模型专用线程池与限流防线:为大模型 API 调用配置独立隔离的线程池与 Resilience4j 限流器,防止大模型供应商接口故障拖垮整个应用容器。

在全量运行期间,运维监控应当持续关注模型响应耗时分布与 Token 吞吐指标:

# 检查 Prometheus 暴露的 LLM 调用响应时间分布与 Token 消耗统计
curl -s http://localhost:8081/actuator/prometheus | grep -E 'llm_request_duration_seconds|llm_token_usage_total'

存量系统引入大模型服务的核心原则在于风险可控。通过影子模式验证拟合效果、利用动态权重控制故障扩散半径、建立基于毫秒级超时的降级回路,并在上线后通过语义缓存防线优化整体成本,才能确保后端架构在演进过程中保持稳健与高效。

更多推荐