SpringBoot整合Spring AI对接大模型实战

1. SpringBoot与Spring AI整合概述

在当今AI技术快速发展的背景下,将大模型能力集成到企业应用中已成为提升业务智能化水平的关键路径。作为Java生态中最流行的框架之一,SpringBoot以其简洁的配置和强大的扩展能力,成为对接AI服务的理想选择。而Spring AI作为Spring官方推出的AI集成框架,为开发者提供了统一的操作接口,极大简化了不同AI服务的接入过程。

这次我们要探讨的是如何在SpringBoot项目中整合Spring AI来对接大模型服务。以阿里云百炼平台为例,这种整合可以让我们快速获得大模型的文本生成、问答对话等能力,同时保持SpringBoot应用的原有架构风格。不同于直接调用原生API的方式,通过Spring AI的抽象层,我们可以用更符合Spring习惯的方式来操作大模型,还能享受到依赖注入、自动配置等Spring特性带来的便利。

2. 环境准备与项目初始化

2.1 基础环境要求

在开始编码前,需要确保开发环境满足以下要求:

  • JDK 17或更高版本(Spring AI对Java新特性有依赖)
  • Spring Boot 3.x(推荐3.4.0及以上)
  • Maven 3.6+或Gradle 7.x(本文以Maven为例)
  • 一个可用的IDE(IntelliJ IDEA或Eclipse等)

提示:如果团队仍在使用JDK 8或11,需要考虑升级或寻找兼容方案,因为Spring AI的部分功能依赖JDK 17引入的新API。

2.2 创建SpringBoot项目

可以通过以下两种方式初始化项目:

  1. 使用Spring Initializr: 访问https://start.spring.io/,选择:

    • Project: Maven
    • Language: Java
    • Spring Boot: 3.4.0 依赖项添加:
    • Spring Web
    • Lombok(可选但推荐)
  2. 通过IDE创建: 在IntelliJ IDEA中:

    • File → New → Project → Spring Initializr
    • 选择上述相同配置

生成项目后,建议验证基础环境是否正常工作:

mvn spring-boot:run

访问http://localhost:8080应能看到Whitelabel Error Page(因为我们还没添加任何控制器),这表示基础项目已正常启动。

3. 添加Spring AI依赖与配置

3.1 引入Spring AI Alibaba Starter

在pom.xml中添加以下依赖:

<dependencies> <!-- Spring AI Alibaba核心依赖 --> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter-dashscope</artifactId> <version>1.0.0.2</version> </dependency> <!-- Web支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.4.0</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- 使用Log4j2替代默认Logback --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>3.4.0</version> </dependency> <!-- 工具类 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.14.0</version> </dependency> </dependencies>

3.2 配置API密钥与应用ID

在application.yml中添加配置:

spring: ai: dashscope: agent: app-id: ${APP_ID} # 从环境变量读取或直接填写 api-key: ${DASHSCOPE_API_KEY} # API密钥 # workspace-id: ${WORKSPACE_ID} # 子业务空间ID,非必须 server: port: 9000 # 避免端口冲突

建议通过环境变量配置敏感信息:

export DASHSCOPE_API_KEY=your_api_key export APP_ID=your_app_id # export WORKSPACE_ID=your_workspace_id # 如果需要

4. 核心代码实现

4.1 非流式调用实现

创建控制器处理常规请求:

@RestController @RequestMapping("/ai") @Slf4j public class BailianAgentController { private final DashScopeAgent agent; @Value("${spring.ai.dashscope.agent.app-id}") private String appId; public BailianAgentController(DashScopeAgentApi dashscopeAgentApi) { this.agent = new DashScopeAgent(dashscopeAgentApi); } @GetMapping("/bailian/agent/call") public String call(@RequestParam(defaultValue = "如何使用SDK调用百炼应用?") String message) { ChatResponse response = agent.call( new Prompt(message, DashScopeAgentOptions.builder() .withAppId(appId) .build())); if (response == null || response.getResult() == null) { log.error("响应为空"); return "请求失败"; } AssistantMessage output = response.getResult().getOutput(); String content = output.getText(); // 处理元数据 DashScopeAgentResponseOutput metadata = (DashScopeAgentResponseOutput) output.getMetadata().get("output"); if (metadata.docReferences() != null) { metadata.docReferences().forEach(ref -> log.info("参考文档: {}", ref)); } return content; } }

4.2 流式调用实现

对于需要实时响应的场景,可以使用流式调用:

@RestController @RequestMapping("/ai") @Slf4j public class BailianAgentStreamController { private final DashScopeAgent agent; @Value("${spring.ai.dashscope.agent.app-id}") private String appId; public BailianAgentStreamController(DashScopeAgentApi dashscopeAgentApi) { this.agent = new DashScopeAgent(dashscopeAgentApi, DashScopeAgentOptions.builder() .withSessionId("custom_session_id") .withIncrementalOutput(true) .build()); } @GetMapping(value = "/bailian/agent/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> stream(@RequestParam(defaultValue = "你好") String message) { return agent.stream( new Prompt(message, DashScopeAgentOptions.builder() .withAppId(appId) .build())) .map(response -> { if (response == null || response.getResult() == null) { return "数据错误"; } return response.getResult().getOutput().getText(); }) .onErrorResume(e -> { log.error("流式调用异常", e); return Flux.just("服务异常: " + e.getMessage()); }); } }

5. 应用测试与调试

5.1 启动类配置

确保有标准的SpringBoot启动类:

@SpringBootApplication public class AiApplication { public static void main(String[] args) { SpringApplication.run(AiApplication.class, args); } }

5.2 测试方法

  1. 非流式接口测试

    curl "http://localhost:9000/ai/bailian/agent/call?message=如何快速入门SpringBoot?"
  2. 流式接口测试: 使用支持SSE的客户端(如Postman)访问:

    GET http://localhost:9000/ai/bailian/agent/stream?message=介绍一下阿里云百炼

    或使用前端EventSource:

    const eventSource = new EventSource('/ai/bailian/agent/stream?message=你好'); eventSource.onmessage = (e) => console.log(e.data);

5.3 常见问题排查

  1. 认证失败

    • 检查API_KEY是否正确
    • 确认环境变量已正确加载
    • 查看网络是否能够访问阿里云API端点
  2. 流式响应不完整

    • 检查客户端是否支持SSE
    • 确认没有超时设置过短
    • 验证网络稳定性
  3. 性能优化建议

    • 对于高频调用,考虑添加缓存层
    • 使用连接池管理API调用
    • 合理设置超时参数

6. 进阶配置与优化

6.1 自定义配置类

对于更复杂的场景,可以创建自定义配置:

@Configuration public class AiConfig { @Bean public DashScopeAgentOptions agentOptions( @Value("${spring.ai.dashscope.agent.app-id}") String appId) { return DashScopeAgentOptions.builder() .withAppId(appId) .withSessionId(UUID.randomUUID().toString()) .withMaxTokens(1000) .build(); } @Bean public DashScopeAgent dashScopeAgent( DashScopeAgentApi api, DashScopeAgentOptions options) { return new DashScopeAgent(api, options); } }

6.2 异常处理增强

统一处理AI服务异常:

@RestControllerAdvice public class AiExceptionHandler { @ExceptionHandler(DashScopeApiException.class) public ResponseEntity<String> handleApiException(DashScopeApiException e) { return ResponseEntity.status(502) .body("AI服务异常: " + e.getMessage()); } @ExceptionHandler(TimeoutException.class) public ResponseEntity<String> handleTimeout(TimeoutException e) { return ResponseEntity.status(504) .body("请求超时: " + e.getMessage()); } }

6.3 性能监控

集成Micrometer监控指标:

@Configuration public class MetricsConfig { @Bean public TimedAspect timedAspect(MeterRegistry registry) { return new TimedAspect(registry); } } // 在控制器方法上添加监控 @GetMapping("/call") @Timed(value = "ai.call.latency", description = "AI调用延迟") public String call(...) { ... }

7. 实际应用中的经验分享

在实际项目集成过程中,有几个关键点值得特别注意:

  1. 会话管理

    • 对于需要保持上下文的对话,务必维护好sessionId
    • 可以考虑将会话信息存储在Redis等缓存中
    • 注意大模型的上下文长度限制
  2. 限流与降级

    @Bean public RateLimiter aiRateLimiter() { return RateLimiter.create(10); // 每秒10个请求 } @GetMapping("/call") public String call(..., RateLimiter limiter) { if (!limiter.tryAcquire()) { throw new RuntimeException("请求过于频繁"); } // ... }
  3. Prompt工程实践

    • 设计清晰明确的提示词
    • 对于专业领域,提供必要的上下文
    • 通过少量示例(few-shot)引导模型输出格式
  4. 安全建议

    • 永远不要在前端暴露API_KEY
    • 对用户输入进行必要的过滤和转义
    • 考虑添加内容审核层

通过SpringBoot整合Spring AI对接大模型,我们不仅获得了先进AI能力,还能保持Spring生态的开发体验。这种架构特别适合需要快速迭代AI功能的业务场景,从原型开发到生产部署都能保持高效的开发节奏。