1.1 Spring AI概述

1.1.1 什么是Spring AI

Spring AI是Spring生态系统中专门用于人工智能应用开发的框架。它提供了一套完整的抽象层和工具集,使开发者能够轻松地在Spring应用中集成各种AI模型和服务。

核心特性: - 统一的AI模型抽象接口 - 多种AI提供商支持(OpenAI、Azure、Ollama等) - 向量数据库集成 - 流式处理支持 - Spring生态系统无缝集成

1.1.2 Spring AI的优势

// 传统AI集成方式
public class TraditionalAIService {
    private OpenAIClient openAIClient;
    private AzureAIClient azureClient;
    
    public String generateText(String prompt, String provider) {
        if ("openai".equals(provider)) {
            return openAIClient.complete(prompt);
        } else if ("azure".equals(provider)) {
            return azureClient.generate(prompt);
        }
        throw new UnsupportedOperationException("Provider not supported");
    }
}

// Spring AI方式
@Service
public class SpringAIService {
    private final ChatModel chatModel;
    
    public SpringAIService(ChatModel chatModel) {
        this.chatModel = chatModel;
    }
    
    public String generateText(String prompt) {
        return chatModel.call(prompt);
    }
}

优势对比: 1. 统一接口:无需关心底层AI提供商的差异 2. 配置驱动:通过配置文件切换AI提供商 3. Spring集成:享受依赖注入、AOP等Spring特性 4. 类型安全:强类型的API设计

1.2 核心概念

1.2.1 AI模型抽象

Spring AI定义了几个核心接口来抽象不同类型的AI模型:

// 聊天模型接口
public interface ChatModel extends Model<Prompt, ChatResponse> {
    ChatResponse call(Prompt prompt);
    Flux<ChatResponse> stream(Prompt prompt);
}

// 嵌入模型接口
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
    EmbeddingResponse call(EmbeddingRequest request);
    List<Double> embed(String text);
}

// 图像模型接口
public interface ImageModel extends Model<ImagePrompt, ImageResponse> {
    ImageResponse call(ImagePrompt prompt);
}

1.2.2 提示词(Prompt)系统

// 简单提示词
Prompt simplePrompt = new Prompt("解释什么是Spring AI");

// 带参数的提示词模板
PromptTemplate template = new PromptTemplate(
    "你是一个{role},请用{language}回答:{question}"
);

Map<String, Object> variables = Map.of(
    "role", "Java专家",
    "language", "中文",
    "question", "什么是Spring Boot"
);

Prompt prompt = template.create(variables);

1.2.3 消息类型

Spring AI支持多种消息类型:

// 用户消息
UserMessage userMessage = new UserMessage("你好,我想学习Spring AI");

// 系统消息
SystemMessage systemMessage = new SystemMessage(
    "你是一个专业的Java开发助手,专门帮助开发者学习Spring技术"
);

// 助手消息
AssistantMessage assistantMessage = new AssistantMessage(
    "很高兴为您介绍Spring AI!"
);

// 组合消息
List<Message> messages = List.of(systemMessage, userMessage);
Prompt prompt = new Prompt(messages);

1.2.4 响应处理

@Service
public class ChatService {
    private final ChatModel chatModel;
    
    public ChatService(ChatModel chatModel) {
        this.chatModel = chatModel;
    }
    
    // 同步调用
    public String chat(String userInput) {
        Prompt prompt = new Prompt(userInput);
        ChatResponse response = chatModel.call(prompt);
        return response.getResult().getOutput().getContent();
    }
    
    // 流式调用
    public Flux<String> chatStream(String userInput) {
        Prompt prompt = new Prompt(userInput);
        return chatModel.stream(prompt)
            .map(response -> response.getResult().getOutput().getContent());
    }
    
    // 获取元数据
    public ChatResponseMetadata getChatMetadata(String userInput) {
        Prompt prompt = new Prompt(userInput);
        ChatResponse response = chatModel.call(prompt);
        return response.getMetadata();
    }
}

1.3 支持的AI提供商

1.3.1 OpenAI集成

// 配置
@Configuration
public class OpenAIConfig {
    
    @Bean
    public OpenAiChatModel openAiChatModel(
            @Value("${spring.ai.openai.api-key}") String apiKey) {
        return new OpenAiChatModel(
            OpenAiApi.builder()
                .withApiKey(apiKey)
                .build()
        );
    }
}

// 使用
@RestController
public class ChatController {
    private final OpenAiChatModel chatModel;
    
    @PostMapping("/chat")
    public String chat(@RequestBody String message) {
        return chatModel.call(message);
    }
}

1.3.2 Azure OpenAI集成

@Configuration
public class AzureOpenAIConfig {
    
    @Bean
    public AzureOpenAiChatModel azureOpenAiChatModel(
            @Value("${spring.ai.azure.openai.api-key}") String apiKey,
            @Value("${spring.ai.azure.openai.endpoint}") String endpoint) {
        return new AzureOpenAiChatModel(
            AzureOpenAiApi.builder()
                .withApiKey(apiKey)
                .withEndpoint(endpoint)
                .build()
        );
    }
}

1.3.3 Ollama本地模型集成

@Configuration
public class OllamaConfig {
    
    @Bean
    public OllamaChatModel ollamaChatModel(
            @Value("${spring.ai.ollama.base-url:http://localhost:11434}") String baseUrl) {
        return new OllamaChatModel(
            OllamaApi.builder()
                .withBaseUrl(baseUrl)
                .build(),
            OllamaOptions.create()
                .withModel("llama2")
                .withTemperature(0.7f)
        );
    }
}

1.4 向量数据库支持

1.4.1 向量存储抽象

public interface VectorStore {
    void add(List<Document> documents);
    Optional<Boolean> delete(List<String> idList);
    List<Document> similaritySearch(String query);
    List<Document> similaritySearch(SearchRequest request);
}

1.4.2 文档处理

@Service
public class DocumentService {
    private final VectorStore vectorStore;
    private final EmbeddingModel embeddingModel;
    
    public void addDocuments(List<String> texts) {
        List<Document> documents = texts.stream()
            .map(text -> new Document(text))
            .collect(Collectors.toList());
        
        vectorStore.add(documents);
    }
    
    public List<Document> searchSimilar(String query, int topK) {
        SearchRequest request = SearchRequest.query(query)
            .withTopK(topK)
            .withSimilarityThreshold(0.7);
        
        return vectorStore.similaritySearch(request);
    }
}

1.4.3 支持的向量数据库

// Chroma配置
@Bean
public ChromaVectorStore chromaVectorStore(EmbeddingModel embeddingModel) {
    return new ChromaVectorStore(embeddingModel, "http://localhost:8000");
}

// Pinecone配置
@Bean
public PineconeVectorStore pineconeVectorStore(
        EmbeddingModel embeddingModel,
        @Value("${pinecone.api-key}") String apiKey,
        @Value("${pinecone.environment}") String environment) {
    return new PineconeVectorStore(
        PineconeApi.builder()
            .withApiKey(apiKey)
            .withEnvironment(environment)
            .build(),
        embeddingModel
    );
}

// Redis配置
@Bean
public RedisVectorStore redisVectorStore(
        EmbeddingModel embeddingModel,
        RedisTemplate<String, Object> redisTemplate) {
    return new RedisVectorStore(redisTemplate, embeddingModel);
}

1.5 函数调用(Function Calling)

1.5.1 函数定义

@Component
public class WeatherFunction implements Function<WeatherRequest, WeatherResponse> {
    
    @Override
    public WeatherResponse apply(WeatherRequest request) {
        // 模拟天气查询
        return new WeatherResponse(
            request.getLocation(),
            "晴天",
            25.0,
            "今天天气很好,适合外出"
        );
    }
}

// 请求和响应类
record WeatherRequest(String location) {}
record WeatherResponse(String location, String weather, Double temperature, String description) {}

1.5.2 函数注册和使用

@Service
public class FunctionCallingService {
    private final ChatModel chatModel;
    private final WeatherFunction weatherFunction;
    
    public String chatWithFunctions(String userMessage) {
        // 创建函数选项
        OpenAiChatOptions options = OpenAiChatOptions.builder()
            .withFunction("get_weather", "获取指定地点的天气信息", weatherFunction)
            .build();
        
        Prompt prompt = new Prompt(userMessage, options);
        ChatResponse response = chatModel.call(prompt);
        
        return response.getResult().getOutput().getContent();
    }
}

1.6 配置管理

1.6.1 应用配置文件

# application.yml
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-3.5-turbo
          temperature: 0.7
          max-tokens: 1000
    
    azure:
      openai:
        api-key: ${AZURE_OPENAI_API_KEY}
        endpoint: ${AZURE_OPENAI_ENDPOINT}
        chat:
          options:
            deployment-name: gpt-35-turbo
    
    ollama:
      base-url: http://localhost:11434
      chat:
        options:
          model: llama2
          temperature: 0.8
    
    vectorstore:
      chroma:
        url: http://localhost:8000
      pinecone:
        api-key: ${PINECONE_API_KEY}
        environment: ${PINECONE_ENVIRONMENT}
        index-name: spring-ai-index

1.6.2 条件配置

@Configuration
public class AIModelConfiguration {
    
    @Bean
    @ConditionalOnProperty(name = "spring.ai.provider", havingValue = "openai")
    public ChatModel openAiChatModel() {
        // OpenAI配置
        return new OpenAiChatModel(/* ... */);
    }
    
    @Bean
    @ConditionalOnProperty(name = "spring.ai.provider", havingValue = "azure")
    public ChatModel azureOpenAiChatModel() {
        // Azure OpenAI配置
        return new AzureOpenAiChatModel(/* ... */);
    }
    
    @Bean
    @ConditionalOnProperty(name = "spring.ai.provider", havingValue = "ollama")
    public ChatModel ollamaChatModel() {
        // Ollama配置
        return new OllamaChatModel(/* ... */);
    }
}

1.7 最佳实践

1.7.1 错误处理

@Service
public class RobustChatService {
    private final ChatModel chatModel;
    private final RetryTemplate retryTemplate;
    
    public String chatWithRetry(String message) {
        return retryTemplate.execute(context -> {
            try {
                Prompt prompt = new Prompt(message);
                ChatResponse response = chatModel.call(prompt);
                return response.getResult().getOutput().getContent();
            } catch (Exception e) {
                log.warn("Chat request failed, attempt: {}", context.getRetryCount() + 1, e);
                throw e;
            }
        });
    }
}

@Configuration
public class RetryConfig {
    
    @Bean
    public RetryTemplate retryTemplate() {
        return RetryTemplate.builder()
            .maxAttempts(3)
            .exponentialBackoff(1000, 2, 10000)
            .retryOn(RuntimeException.class)
            .build();
    }
}

1.7.2 缓存策略

@Service
@CacheConfig(cacheNames = "ai-responses")
public class CachedChatService {
    private final ChatModel chatModel;
    
    @Cacheable(key = "#message.hashCode()")
    public String chat(String message) {
        Prompt prompt = new Prompt(message);
        ChatResponse response = chatModel.call(prompt);
        return response.getResult().getOutput().getContent();
    }
    
    @CacheEvict(allEntries = true)
    public void clearCache() {
        // 清除缓存
    }
}

1.7.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.total")
            .description("Total AI requests")
            .register(meterRegistry);
        this.responseTimer = Timer.builder("ai.response.time")
            .description("AI response time")
            .register(meterRegistry);
    }
    
    public String timedChat(ChatModel chatModel, String message) {
        return responseTimer.recordCallable(() -> {
            requestCounter.increment();
            return chatModel.call(message);
        });
    }
}

1.8 本章总结

1.8.1 核心要点

  1. 统一抽象:Spring AI提供了统一的AI模型抽象接口
  2. 多提供商支持:支持OpenAI、Azure、Ollama等多种AI提供商
  3. Spring集成:完美融入Spring生态系统
  4. 向量数据库:内置多种向量数据库支持
  5. 函数调用:支持AI模型调用外部函数

1.8.2 最佳实践

  1. 配置管理:使用配置文件管理不同环境的AI提供商
  2. 错误处理:实现重试机制和优雅降级
  3. 性能优化:合理使用缓存和连接池
  4. 监控指标:添加必要的监控和日志

1.8.3 练习题

基础练习

  1. 创建一个简单的Spring Boot项目,集成OpenAI ChatGPT
  2. 实现一个基本的聊天接口,支持用户输入和AI回复
  3. 配置不同的AI模型参数(temperature、max-tokens等)

进阶练习

  1. 实现多AI提供商的动态切换
  2. 添加请求缓存和重试机制
  3. 创建自定义的函数调用示例

高级练习

  1. 设计一个AI服务的监控和指标收集系统
  2. 实现AI模型的负载均衡和故障转移
  3. 构建一个支持多租户的AI服务平台

下一章我们将学习如何搭建Spring AI开发环境并创建第一个AI应用。