Spring AI Alibaba 教程:集成阿里云大模型服务

2,633 阅读6分钟

Spring AI Alibaba 教程:集成阿里云大模型服务

目录

简介

Spring AI Alibaba 是 Spring AI 生态系统中专门为阿里云大模型服务设计的集成模块。它提供了与阿里云通义千问、通义万相等大模型服务的无缝集成,让开发者能够轻松地在 Spring Boot 应用中集成 AI 能力。

主要特性

  • 🚀 简单易用:基于 Spring Boot 自动配置,开箱即用
  • 🔧 灵活配置:支持多种配置方式和参数调优
  • 🛡️ 安全可靠:内置安全机制,支持 API 密钥管理
  • 📊 监控友好:提供详细的日志和监控信息
  • 🔄 异步支持:支持异步调用,提高应用性能

支持的模型

  • 通义千问 (Qwen)
  • 通义万相 (WanXiang)
  • 其他阿里云大模型服务

环境准备

系统要求

  • Java 17 或更高版本
  • Spring Boot 3.0 或更高版本
  • Maven 3.6+ 或 Gradle 7.0+

阿里云账号准备

  1. 注册阿里云账号
  2. 开通大模型服务(如通义千问)
  3. 获取 API Key 和 Secret
  4. 配置访问权限

项目配置

1. 创建 Spring Boot 项目

首先创建一个新的 Spring Boot 项目,可以通过 Spring Initializr 或手动创建:

<!-- pom.xml -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Spring AI Alibaba 依赖 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-alibaba-spring-boot-starter</artifactId>
        <version>1.0.0.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 配置文件设置

application.yml 中配置阿里云大模型服务:

spring:
  ai:
    alibaba:
      # 阿里云 API 配置
      api-key: ${ALIBABA_API_KEY:your-api-key}
      secret-key: ${ALIBABA_SECRET_KEY:your-secret-key}
      
      # 模型配置
      model:
        # 默认模型名称
        name: qwen-turbo
        # 模型参数
        parameters:
          temperature: 0.7
          max-tokens: 2048
          top-p: 0.9
      
      # 客户端配置
      client:
        # 连接超时时间(毫秒)
        connect-timeout: 10000
        # 读取超时时间(毫秒)
        read-timeout: 30000
        # 重试次数
        max-retries: 3
      
      # 日志配置
      logging:
        level: INFO
        enable-request-logging: true
        enable-response-logging: false

3. 环境变量配置

为了安全起见,建议使用环境变量存储敏感信息:

# Windows PowerShell
$env:ALIBABA_API_KEY="your-actual-api-key"
$env:ALIBABA_SECRET_KEY="your-actual-secret-key"

# Linux/Mac
export ALIBABA_API_KEY="your-actual-api-key"
export ALIBABA_SECRET_KEY="your-actual-secret-key"

基础使用

1. 创建 AI 服务类

package com.example.springai.service;

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AiService {
    
    @Autowired
    private ChatClient chatClient;
    
    /**
     * 简单的文本对话
     */
    public String chat(String userInput) {
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        ChatResponse response = chatClient.call(prompt);
        return response.getResult().getOutput().getContent();
    }
    
    /**
     * 带系统提示的对话
     */
    public String chatWithSystemPrompt(String systemPrompt, String userInput) {
        Message systemMessage = new SystemMessage(systemPrompt);
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
        
        ChatResponse response = chatClient.call(prompt);
        return response.getResult().getOutput().getContent();
    }
}

2. 创建控制器

package com.example.springai.controller;

import com.example.springai.service.AiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/ai")
public class AiController {
    
    @Autowired
    private AiService aiService;
    
    @PostMapping("/chat")
    public Map<String, String> chat(@RequestBody Map<String, String> request) {
        String userInput = request.get("message");
        String response = aiService.chat(userInput);
        
        return Map.of("response", response);
    }
    
    @PostMapping("/chat-with-system")
    public Map<String, String> chatWithSystem(
            @RequestBody Map<String, String> request) {
        String systemPrompt = request.get("systemPrompt");
        String userInput = request.get("message");
        String response = aiService.chatWithSystemPrompt(systemPrompt, userInput);
        
        return Map.of("response", response);
    }
}

3. 测试应用

启动应用后,可以使用以下方式测试:

# 简单对话
curl -X POST http://localhost:8080/api/ai/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "你好,请介绍一下Spring AI"}'

# 带系统提示的对话
curl -X POST http://localhost:8080/api/ai/chat-with-system \
  -H "Content-Type: application/json" \
  -d '{
    "systemPrompt": "你是一个专业的Java开发专家",
    "message": "请解释一下Spring Boot的自动配置原理"
  }'

高级功能

1. 流式响应

@Service
public class StreamingAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    /**
     * 流式对话响应
     */
    public Flux<String> streamChat(String userInput) {
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        return chatClient.stream(prompt)
                .map(response -> response.getResult().getOutput().getContent());
    }
}

@RestController
@RequestMapping("/api/ai")
public class StreamingAiController {
    
    @Autowired
    private StreamingAiService streamingAiService;
    
    @PostMapping(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamChat(@RequestBody Map<String, String> request) {
        String userInput = request.get("message");
        return streamingAiService.streamChat(userInput);
    }
}

2. 自定义模型参数

@Service
public class CustomAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    /**
     * 使用自定义参数的对话
     */
    public String chatWithCustomParams(String userInput, double temperature, int maxTokens) {
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        // 创建自定义参数
        GenerationConfig config = GenerationConfig.builder()
                .withTemperature(temperature)
                .withMaxTokens(maxTokens)
                .withTopP(0.9)
                .build();
        
        ChatResponse response = chatClient.call(prompt, config);
        return response.getResult().getOutput().getContent();
    }
}

3. 多轮对话

@Service
public class ConversationService {
    
    @Autowired
    private ChatClient chatClient;
    
    private final List<Message> conversationHistory = new ArrayList<>();
    
    /**
     * 多轮对话
     */
    public String continueConversation(String userInput) {
        // 添加用户消息到历史记录
        conversationHistory.add(new UserMessage(userInput));
        
        // 创建包含历史记录的提示
        Prompt prompt = new Prompt(conversationHistory);
        
        ChatResponse response = chatClient.call(prompt);
        String aiResponse = response.getResult().getOutput().getContent();
        
        // 添加AI响应到历史记录
        conversationHistory.add(new AssistantMessage(aiResponse));
        
        return aiResponse;
    }
    
    /**
     * 清空对话历史
     */
    public void clearHistory() {
        conversationHistory.clear();
    }
    
    /**
     * 获取对话历史
     */
    public List<Message> getHistory() {
        return new ArrayList<>(conversationHistory);
    }
}

4. 错误处理

@ControllerAdvice
public class AiExceptionHandler {
    
    @ExceptionHandler(AiException.class)
    public ResponseEntity<Map<String, String>> handleAiException(AiException e) {
        Map<String, String> error = Map.of(
            "error", "AI服务异常",
            "message", e.getMessage(),
            "timestamp", LocalDateTime.now().toString()
        );
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(error);
    }
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, String>> handleGenericException(Exception e) {
        Map<String, String> error = Map.of(
            "error", "系统异常",
            "message", e.getMessage(),
            "timestamp", LocalDateTime.now().toString()
        );
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(error);
    }
}

最佳实践

1. 配置管理

@Configuration
@ConfigurationProperties(prefix = "spring.ai.alibaba")
@Data
public class AlibabaAiProperties {
    
    private String apiKey;
    private String secretKey;
    private ModelConfig model = new ModelConfig();
    private ClientConfig client = new ClientConfig();
    
    @Data
    public static class ModelConfig {
        private String name = "qwen-turbo";
        private Map<String, Object> parameters = new HashMap<>();
    }
    
    @Data
    public static class ClientConfig {
        private int connectTimeout = 10000;
        private int readTimeout = 30000;
        private int maxRetries = 3;
    }
}

2. 缓存策略

@Service
public class CachedAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    @Cacheable(value = "ai-responses", key = "#userInput")
    public String chatWithCache(String userInput) {
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        ChatResponse response = chatClient.call(prompt);
        return response.getResult().getOutput().getContent();
    }
}

3. 监控和日志

@Component
public class AiMetrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter requestCounter;
    private final Timer responseTimer;
    
    public AiMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.requestCounter = Counter.builder("ai.requests")
                .description("AI请求计数")
                .register(meterRegistry);
        this.responseTimer = Timer.builder("ai.response.time")
                .description("AI响应时间")
                .register(meterRegistry);
    }
    
    public void recordRequest() {
        requestCounter.increment();
    }
    
    public Timer.Sample startTimer() {
        return Timer.start(meterRegistry);
    }
    
    public void stopTimer(Timer.Sample sample) {
        sample.stop(responseTimer);
    }
}

4. 安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/ai/**").authenticated()
                .anyRequest().permitAll()
            )
            .httpBasic(Customizer.withDefaults())
            .csrf(csrf -> csrf.disable());
        
        return http.build();
    }
}

常见问题

Q1: 如何处理 API 限流?

A: 实现重试机制和限流控制:

@Service
public class RateLimitedAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10个请求
    
    public String chatWithRateLimit(String userInput) {
        // 获取令牌
        rateLimiter.acquire();
        
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        ChatResponse response = chatClient.call(prompt);
        return response.getResult().getOutput().getContent();
    }
}

Q2: 如何优化响应速度?

A: 使用异步处理和连接池:

@Service
public class AsyncAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    @Async
    public CompletableFuture<String> chatAsync(String userInput) {
        Message userMessage = new UserMessage(userInput);
        Prompt prompt = new Prompt(List.of(userMessage));
        
        ChatResponse response = chatClient.call(prompt);
        return CompletableFuture.completedFuture(
            response.getResult().getOutput().getContent()
        );
    }
}

Q3: 如何处理大文本输入?

A: 实现文本分块处理:

@Service
public class LargeTextAiService {
    
    @Autowired
    private ChatClient chatClient;
    
    public String processLargeText(String largeText) {
        // 分块处理大文本
        List<String> chunks = splitText(largeText, 4000);
        
        StringBuilder result = new StringBuilder();
        for (String chunk : chunks) {
            Message userMessage = new UserMessage("请处理以下文本:" + chunk);
            Prompt prompt = new Prompt(List.of(userMessage));
            
            ChatResponse response = chatClient.call(prompt);
            result.append(response.getResult().getOutput().getContent()).append("\n");
        }
        
        return result.toString();
    }
    
    private List<String> splitText(String text, int maxLength) {
        List<String> chunks = new ArrayList<>();
        int start = 0;
        
        while (start < text.length()) {
            int end = Math.min(start + maxLength, text.length());
            chunks.add(text.substring(start, end));
            start = end;
        }
        
        return chunks;
    }
}

总结

Spring AI Alibaba 为开发者提供了一个强大而灵活的工具来集成阿里云大模型服务。通过本教程,您应该能够:

  1. ✅ 正确配置 Spring AI Alibaba 环境
  2. ✅ 实现基础的 AI 对话功能
  3. ✅ 使用高级特性如流式响应和多轮对话
  4. ✅ 应用最佳实践来优化性能和安全性
  5. ✅ 处理常见的开发问题

随着 AI 技术的不断发展,Spring AI Alibaba 也会持续更新和完善。建议您:

  • 关注官方文档和更新日志
  • 参与社区讨论和贡献
  • 根据实际需求调整配置和实现
  • 持续优化应用的性能和用户体验

希望这篇教程能够帮助您快速上手 Spring AI Alibaba,并在实际项目中发挥其强大的 AI 能力!


相关资源: