首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >企业级 Java + AI:从模型调用到生产级 AI 网关的工程实践

企业级 Java + AI:从模型调用到生产级 AI 网关的工程实践

原创
作者头像
资源大佬 jzit-top
发布于 2026-10-10 11:11:53
发布于 2026-10-10 11:11:53
150
举报

在企业级系统中集成 AI,远不止调用一次 API。多租户隔离、成本控制、熔断降级、数据合规、可观测性,每一项都决定 AI 能力能否真正上线。本文以 Spring Boot 3 + Resilience4j + Caffeine 为核心,构建一个生产级 AI 编排服务,统一管理多模型提供商、缓存、限流与审计。

一、企业级 AI 集成的核心挑战

企业场景与个人开发有本质区别:多租户要求数据与配额隔离;成本需要按部门核算 token 消耗;稳定性要求模型故障时自动降级;合规要求敏感信息脱敏与全链路审计。因此,不能把 OpenAI 调用散落在业务代码中,而应抽象为独立的 AI 网关层。

二、分层架构

  • 接入层:Spring Cloud Gateway 统一鉴权、限流、租户识别。
  • 编排层:AiOrchestratorService 负责模型路由、缓存、熔断、重试。
  • 提供商层:适配 OpenAI、Claude、本地 vLLM,统一接口。
  • 数据层:Redis 缓存、PGVector 向量库、MySQL 审计日志。
  • 观测层:Micrometer + Prometheus + Grafana 监控延迟、成功率、token 用量。

三、核心代码:AI 编排服务

代码语言:javascript
复制
@Service
public class AiOrchestratorService {

    private final WebClient webClient;
    private final CircuitBreaker circuitBreaker;
    private final Cache<String, String> cache;
    private final MeterRegistry metrics;
    private final Map<String, ModelConfig> modelConfigs;
    private final RateLimiter rateLimiter;

    public AiOrchestratorService(WebClient.Builder builder,
                                 MeterRegistry metrics,
                                 ModelConfigRepository configRepo) {
        this.webClient = builder.baseUrl("https://api.openai.com").build();
        this.circuitBreaker = CircuitBreaker.ofDefaults("aiProvider");
        this.cache = Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(10_000)
                .build();
        this.metrics = metrics;
        this.modelConfigs = configRepo.loadAll();
        this.rateLimiter = RateLimiter.ofDefaults("tenantLimiter");
    }

    public String generate(String tenantId, String prompt, String model) {
        String cacheKey = tenantId + ":" + model + ":" + prompt.hashCode();
        String cached = cache.getIfPresent(cacheKey);
        if (cached != null) {
            metrics.counter("ai.cache.hit").increment();
            return cached;
        }

        // 租户级限流
        RateLimiter.waitForPermission(rateLimiter, tenantId);

        Supplier<String> decorated = CircuitBreaker.decorateSupplier(
                circuitBreaker, () -> callModel(tenantId, prompt, model));

        try {
            String result = decorated.get();
            cache.put(cacheKey, result);
            metrics.counter("ai.request.success", "tenant", tenantId).increment();
            return result;
        } catch (Exception e) {
            metrics.counter("ai.request.failure", "tenant", tenantId).increment();
            return fallback(tenantId, prompt);
        }
    }

    private String callModel(String tenantId, String prompt, String model) {
        ModelConfig config = modelConfigs.get(model);
        long start = System.currentTimeMillis();
        String response = webClient.post()
                .uri("/v1/chat/completions")
                .header("Authorization", "Bearer " + config.getApiKey())
                .header("X-Tenant-Id", tenantId)
                .bodyValue(Map.of(
                        "model", model,
                        "messages", List.of(Map.of("role", "user", "content", prompt)),
                        "temperature", 0.2))
                .retrieve()
                .bodyToMono(String.class)
                .block(Duration.ofSeconds(15));
        metrics.timer("ai.latency", "model", model)
               .record(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
        return response;
    }

    private String fallback(String tenantId, String prompt) {
        // 降级:返回缓存或规则答案,或转人工
        return "AI 服务繁忙,请稍后重试或联系人工客服。";
    }
}

四、关键配置

application.yml 中配置 Resilience4j 与 Caffeine:

代码语言:javascript
复制
resilience4j:
  circuitbreaker:
    instances:
      aiProvider:
        slidingWindowSize: 20
        failureRateThreshold: 50
        waitDurationInOpenState: 30s
        permittedNumberOfCallsInHalfOpenState: 5
  ratelimiter:
    instances:
      tenantLimiter:
        limitForPeriod: 100
        limitRefreshPeriod: 1m
        timeoutDuration: 0s

Caffeine 缓存自动注入,无需额外配置。

五、安全与合规

Prompt 注入防护:对用户输入做正则过滤,禁止 system:、ignore previous 等指令。PII 脱敏:调用前用正则替换手机号、身份证、银行卡。审计日志:用 AOP 记录租户、模型、token 用量、耗时,写入独立表,保留 180 天。

代码语言:javascript
复制
@Aspect
@Component
public class AiAuditAspect {
    @Around("@annotation(AiAudit)")
    public Object audit(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        // 异步写入审计日志
        auditRepository.save(new AuditLog(
            TenantContext.get(), pjp.getSignature().getName(),
            System.currentTimeMillis() - start));
        return result;
    }
}

六、可观测性与成本控制

通过 Micrometer 暴露 ai.request.success、ai.request.failure、ai.latency、ai.token.usage 指标。按租户统计 token 消耗,结合定价表计算成本,超预算自动限流。Grafana 看板实时展示各模型成功率与 P99 延迟。

七、部署建议

生产环境推荐 Kubernetes 部署,AI 网关无状态,可水平扩展。外部模型走 API,内部敏感场景用 vLLM 或 TGI 私有化部署,通过 Istio 做流量治理。配置 HPA 根据 QPS 自动扩缩容。

总结:企业级 Java + AI 的核心不是模型,而是治理。用网关统一入口,用熔断缓存保稳定,用审计计量控成本,用多租户隔离保合规。代码结构清晰、边界明确,AI 才能真正融入企业生产体系。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、企业级 AI 集成的核心挑战
  • 二、分层架构
  • 三、核心代码:AI 编排服务
  • 四、关键配置
  • 五、安全与合规
  • 六、可观测性与成本控制
  • 七、部署建议
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档