第2天-核心概念-AI Model 体系总览

系列导读:本文是《Spring AI Alibaba 30 天技术博客》系列的第 2 篇。我们将从架构层面深入剖析 Spring AI Alibaba 的 AI Model 体系,理解其核心抽象、接口设计、类继承关系以及不同模型类型的工作原理。

上一篇第1天 - Spring AI Alibaba 简介与环境搭建


📋 目录


1. 为什么需要 Model 体系抽象

在 Spring AI Alibaba(以下简称 SAA)的设计哲学中,“面向接口编程,屏蔽底层差异” 是贯穿始终的核心理念。

试想以下场景:

  • 今天你使用通义千问(Qwen)作为主力模型
  • 明天客户想用智谱 GLM-4
  • 后天为了成本考虑,需要切换到 DeepSeek

如果没有统一的抽象层,你需要在每个业务模块中重写调用逻辑。而 SAA 通过一套精心设计的接口体系,让你只需修改配置文件中的 model-id,就能无缝切换底层模型。

抽象带来的好处

好处说明
零侵入切换业务代码不依赖具体模型实现
统一参数模型不同模型的参数(temperature、maxTokens 等)通过统一方式配置
可组合性可以组合多个 Model 实现复杂场景(如 ChatModel + EmbeddingModel 做 RAG)
可测试性通过接口 Mock 进行单元测试

2. Spring AI 的核心接口设计

2.1 Model 接口层级

Spring AI 的 Model 体系采用经典的 接口继承 + 默认实现 模式。理解这个层级结构是掌握 SAA 的第一步。

                    ┌──────────────────┐
                    │   Model<T, R>    │  ← 最顶层泛型接口
                    │   <Request,      │
                    │    Response>     │
                    └────────┬─────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
    ┌─────────▼──────┐ ┌─────▼──────┐ ┌──────▼───────┐
    │ ChatModel      │ │Embedding   │ │  ImageModel  │
    │                │ │Model       │ │              │
    │ (对话/文本生成) │ │(向量嵌入)  │ │  (图像生成)  │
    └────────┬───────┘ └─────┬──────┘ └──────┬───────┘
             │               │               │
             ▼               ▼               ▼
    ┌──────────────┐ ┌─────────────┐ ┌─────────────┐
    │ChatClient    │ │Embedding    │ │ImageClient  │
    │(高层API)     │ │Client       │ │(高层API)    │
    └──────────────┘ └─────────────┘ └─────────────┘

底层接口定义:

// 最顶层的泛型接口
public interface Model<Request extends ModelRequest, Response extends ModelResponse> {
    Response call(Request request);
}

// ChatModel 继承自 Model,使用专用的 Request/Response 类型
public interface ChatModel extends Model<ChatModelRequest, ChatModelResponse> {
    
    // 基础对话方法
    ChatResponse call(Prompt prompt);
    
    // 流式对话方法
    Flux<ChatResponse> stream(Prompt prompt);
}

// EmbeddingModel 专门处理文本向量化
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
    
    float[] embed(String text);
    
    List<Double> embed(Document document);
}

// ImageModel 处理文本到图像的生成
public interface ImageModel extends Model<ImageRequest, ImageResponse> {
    ImageResponse call(ImageRequest request);
}

2.2 AiModelFactory 工厂模式

Spring AI Alibaba 使用工厂模式来创建和管理不同的 Model 实例。这是自动配置的核心机制:

@Configuration
public class AlibabaModelAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.ai.dashscope.chat", name = "enabled", havingValue = "true", matchIfMissing = true)
    public ChatModel dashscopeChatModel(DashscopeApi dashscopeApi,
                                         DashscopeChatProperties chatProperties) {
        return new DashscopeChatModel(dashscopeApi, chatProperties.getOptions());
    }
    
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.ai.dashscope.embedding", name = "enabled", havingValue = "true", matchIfMissing = true)
    public EmbeddingModel dashscopeEmbeddingModel(DashscopeApi dashscopeApi,
                                                    DashscopeEmbeddingProperties embeddingProperties) {
        return new DashscopeEmbeddingModel(dashscopeApi, embeddingProperties.getOptions());
    }
    
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.ai.dashscope.image", name = "enabled", havingValue = "true", matchIfMissing = true)
    public ImageModel dashscopeImageModel(DashscopeApi dashscopeApi,
                                           DashscopeImageProperties imageProperties) {
        return new DashscopeImageModel(dashscopeApi, imageProperties.getOptions());
    }
}

理解这个自动配置的关键点:

  1. @ConditionalOnProperty:只有配置了对应前缀的属性才会创建 Bean
  2. @ConditionalOnMissingBean:允许用户自定义实现覆盖默认 Bean
  3. 共用 DashscopeApi:所有 DashScope 模型共享同一个 API 客户端,避免重复创建连接

3. 三大核心 Model 类型详解

3.1 ChatModel:对话模型

ChatModel 是 Spring AI Alibaba 中最常用的模型类型,负责处理对话和文本生成任务。

3.1.1 请求-响应模型

┌────────────────────────────────────────────────────┐
│                   Prompt                           │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐│
│  │ SystemMessage│  │ UserMessage  │  │ Assistant ││
│  │ (系统提示)    │  │ (用户输入)    │  │ Message   ││
│  │              │  │              │  │ (AI回复)  ││
│  └──────────────┘  └──────────────┘  └───────────┘│
│                       ↓                            │
│              ┌──────────────┐                      │
│              │ ChatOptions  │ ← 模型参数控制         │
│              │ (温度/Token  │                      │
│              │  /TopP等)    │                      │
│              └──────────────┘                      │
└────────────────────┬───────────────────────────────┘
                     ↓
              ┌──────────────┐
              │  DashScope   │
              │    API       │
              └──────┬───────┘
                     ↓
┌────────────────────────────────────────────────────┐
│                 ChatResponse                       │
│  ┌──────────────────────────────────────────────┐  │
│  │  AssistantMessage                            │  │
│  │  "作为一名AI助手,我来回答你的问题..."         │  │
│  └──────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────┐  │
│  │  Usage (Token消耗统计)                        │  │
│  │  Prompt Tokens: 128  |  Completion: 256      │  │
│  └──────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────┐  │
│  │  Metadata (模型信息、生成参数等)               │  │
│  └──────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────┘

3.1.2 完整使用示例

@Service
public class ChatService {

    private final ChatModel chatModel;

    public ChatService(ChatModel chatModel) {
        this.chatModel = chatModel;
    }

    /**
     * 简单对话 - 使用 Prompt 构建完整的消息结构
     */
    public String chat(String userMessage) {
        Prompt prompt = new Prompt(
            List.of(
                new SystemMessage("你是一个专业的Java技术顾问。请用中文回答,并给出代码示例。"),
                new UserMessage(userMessage)
            ),
            DashscopeChatOptions.builder()
                .withModel("qwen-plus")           // 指定模型版本
                .withTemperature(0.7)             // 创造性参数 (0-1)
                .withMaxTokens(2048)              // 最大生成Token数
                .withTopP(0.8)                    // 核采样参数
                .withTopK(50)                     // Top-K 采样
                .build()
        );

        ChatResponse response = chatModel.call(prompt);
        
        // 提取AI的回复内容
        String content = response.getResult().getOutput().getContent();
        
        // 获取Token使用情况
        Usage usage = response.getMetadata().getUsage();
        log.info("Token消耗 - Prompt: {}, Completion: {}, Total: {}", 
            usage.getPromptTokens(), 
            usage.getGenerationTokens(), 
            usage.getTotalTokens());
        
        return content;
    }

    /**
     * 带多轮历史的对话
     */
    public String chatWithHistory(String userMessage, List<Message> history) {
        List<Message> messages = new ArrayList<>(history);
        messages.add(new UserMessage(userMessage));
        
        Prompt prompt = new Prompt(messages);
        ChatResponse response = chatModel.call(prompt);
        
        // 将AI的回复也加入历史
        messages.add(response.getResult().getOutput());
        
        return response.getResult().getOutput().getContent();
    }
}

3.1.3 Prompt 对象的内部结构

public class Prompt {
    
    // 消息列表(核心内容)
    private final List<Message> messages;
    
    // 模型参数选项(控制生成行为)
    private final ChatModelOptions modelOptions;
    
    // 内部状态(用于流式处理等)
    private final Map<String, Object> state;
}

// Message 的继承体系
abstract class Message {
    private final String content;
    private final Map<String, Object> metadata;
}

class SystemMessage extends Message {    // 系统提示词 - 定义AI角色和行为
    // 通常放在消息列表的最前面
}

class UserMessage extends Message {      // 用户输入
    // 支持文本、多模态(图片、音频等)
}

class AssistantMessage extends Message { // AI 的回复
    // 可能包含 Tool Call 信息
}

class ToolResponseMessage extends Message { // 工具调用结果
    // 用于 Function Calling 场景
}

3.2 EmbeddingModel:嵌入模型

EmbeddingModel 负责将文本转换为高维向量(通常是 1024 维或 1536 维的浮点数数组)。这是 RAG(检索增强生成)架构的基石。

3.2.1 工作原理

输入文本:"Spring Boot 是一个用于简化 Spring 应用开发的框架"
                    ↓
            ┌───────────────┐
            │  Tokenizer    │  → 分词:["Spring", "Boot", "是", "一个", ...]
            └───────┬───────┘
                    ↓
            ┌───────────────┐
            │  Encoder      │  → 上下文编码(Transformer)
            │  (Transformer)│
            └───────┬───────┘
                    ↓
            ┌───────────────────────────────────────────────┐
            │  Embedding Vector (1536维浮点数数组)           │
            │  [0.023, -0.156, 0.089, ..., 0.034]           │
            │                                               │
            │  语义相近的文本,其向量在空间中距离更近          │
            └───────────────────────────────────────────────┘

3.2.2 使用示例

@Service
public class EmbeddingService {

    private final EmbeddingModel embeddingModel;

    public EmbeddingService(EmbeddingModel embeddingModel) {
        this.embeddingModel = embeddingModel;
    }

    /**
     * 将文本转换为向量
     */
    public float[] embedText(String text) {
        return embeddingModel.embed(text);
    }

    /**
     * 批量文档向量化(用于知识库构建)
     */
    public List<Double> embedDocument(Document document) {
        return embeddingModel.embed(document);
    }

    /**
     * 计算两段文本的语义相似度
     */
    public double computeSimilarity(String text1, String text2) {
        float[] vec1 = embeddingModel.embed(text1);
        float[] vec2 = embeddingModel.embed(text2);
        
        // 计算余弦相似度
        return cosineSimilarity(vec1, vec2);
    }

    private double cosineSimilarity(float[] a, float[] b) {
        double dotProduct = 0.0;
        double normA = 0.0;
        double normB = 0.0;
        
        for (int i = 0; i < a.length; i++) {
            dotProduct += a[i] * b[i];
            normA += a[i] * a[i];
            normB += b[i] * b[i];
        }
        
        return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
    }
}

3.2.3 可用的 Embedding 模型

DashScope 平台提供了多种 Embedding 模型,各有特点:

模型维度最大输入特点
text-embedding-v31024/20488192最新版,支持多语言,可配置维度
text-embedding-v215362048经典版本,性能稳定
text-embedding-v115362048最早版本,兼容性最好

配置示例:

spring:
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}
      embedding:
        options:
          model: text-embedding-v3
          dimensions: 1024    # 可选维度:1024 或 2048

3.3 ImageModel:图像模型

ImageModel 负责文本到图像的生成,基于通义万相等模型。

3.3.1 使用示例

@Service
public class ImageService {

    private final ImageModel imageModel;

    public ImageService(ImageModel imageModel) {
        this.imageModel = imageModel;
    }

    /**
     * 根据文本描述生成图像
     */
    public String generateImage(String prompt) {
        ImageRequest request = ImageRequest.builder()
            .prompt(prompt)
            .options(DashscopeImageOptions.builder()
                .withModel("wanx-v1")          // 通义万相
                .withN(1)                       // 生成数量
                .withWidth(1024)                // 宽度
                .withHeight(1024)               // 高度
                .withStyle("<anime>")           // 风格
                .build())
            .build();

        ImageResponse response = imageModel.call(request);
        
        // 获取生成的图像 URL
        return response.getResult().getOutput().getUrl();
    }
}

4. 模型参数配置体系

Spring AI Alibaba 提供了 多层次 的参数配置方式,理解它们的优先级是关键。

4.1 配置优先级(从高到低)

┌─────────────────────────────────────────────────┐
│  优先级①:代码中动态设置(最高)                  │
│  Prompt 中通过 ChatOptions 指定                   │
│  ┌───────────────────────────────────────────┐  │
│  │ new Prompt(messages,                       │  │
│  │     DashscopeChatOptions.builder()          │  │
│  │         .withTemperature(0.5)              │  │
│  │         .build())                          │  │
│  └───────────────────────────────────────────┘  │
├─────────────────────────────────────────────────┤
│  优先级②:Bean 级别配置                           │
│  自定义 Bean 时注入 Options                       │
│  ┌───────────────────────────────────────────┐  │
│  │ @Bean                                      │  │
│  │ ChatModel chatModel(Api api,               │  │
│  │     DashscopeChatOptions options) {        │  │
│  │     return new DashscopeChatModel(api,     │  │
│  │         options);                          │  │
│  │ }                                          │  │
│  └───────────────────────────────────────────┘  │
├─────────────────────────────────────────────────┤
│  优先级③:application.yaml 全局配置(最低)       │
│  ┌───────────────────────────────────────────┐  │
│  │ spring.ai.dashscope.chat.options:          │  │
│  │   temperature: 0.7                         │  │
│  │   model: qwen-plus                         │  │
│  └───────────────────────────────────────────┘  │
└─────────────────────────────────────────────────┘

4.2 核心参数详解

参数类型默认值说明推荐值
modelStringqwen-plus模型ID根据场景选择
temperaturedouble0.7创造性 (0=确定,1=随机)精确任务0.2,创意0.8
maxTokensint2048最大生成长度根据需求设定
topPdouble0.8核采样阈值0.7-0.95
topKint50Top-K采样20-100
stopList[]停止词序列按需设置
enableSearchbooleanfalse是否启用联网搜索需要实时信息时开启

4.3 完整的 YAML 配置示例

spring:
  ai:
    dashscope:
      # API 配置
      api-key: ${DASHSCOPE_API_KEY:sk-your-api-key-here}
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1  # 可选
      
      # Chat 模型配置
      chat:
        enabled: true
        options:
          model: qwen-plus
          temperature: 0.7
          max-tokens: 4096
          top-p: 0.8
          top-k: 50
          # 开启流式输出
          stream: false
          
      # Embedding 模型配置
      embedding:
        enabled: true
        options:
          model: text-embedding-v3
          dimensions: 1024
          
      # Image 模型配置
      image:
        enabled: true
        options:
          model: wanx-v1
          width: 1024
          height: 1024

5. 多模型并行与切换机制

在实际项目中,你可能需要同时使用多个模型。Spring AI Alibaba 提供了灵活的方案。

5.1 方案一:Qualifier 注解区分

@Configuration
public class MultiModelConfiguration {

    @Bean("qwenPlusChatModel")
    public ChatModel qwenPlusChatModel(DashscopeApi api) {
        DashscopeChatOptions options = DashscopeChatOptions.builder()
            .withModel("qwen-plus")
            .withTemperature(0.7)
            .build();
        return new DashscopeChatModel(api, options);
    }

    @Bean("qwenTurboChatModel")
    public ChatModel qwenTurboChatModel(DashscopeApi api) {
        DashscopeChatOptions options = DashscopeChatOptions.builder()
            .withModel("qwen-turbo")    // 更快的模型
            .withTemperature(0.3)
            .build();
        return new DashscopeChatModel(api, options);
    }
}

@Service
public class SmartChatService {

    // 高质量模型 - 用于复杂推理
    private final ChatModel qwenPlusChatModel;
    
    // 快速模型 - 用于简单分类
    private final ChatModel qwenTurboChatModel;

    public SmartChatService(
            @Qualifier("qwenPlusChatModel") ChatModel qwenPlusChatModel,
            @Qualifier("qwenTurboChatModel") ChatModel qwenTurboChatModel) {
        this.qwenPlusChatModel = qwenPlusChatModel;
        this.qwenTurboChatModel = qwenTurboChatModel;
    }

    public String routeByComplexity(String message) {
        // 简单问题用 Turbo,复杂问题用 Plus
        if (isSimpleQuery(message)) {
            return qwenTurboChatModel.call(new Prompt(message))
                .getResult().getOutput().getContent();
        } else {
            return qwenPlusChatModel.call(new Prompt(message))
                .getResult().getOutput().getContent();
        }
    }
}

5.2 方案二:动态切换模型(运行时)

@Service
public class DynamicModelService {

    private final ChatModel defaultChatModel;

    public DynamicModelService(ChatModel defaultChatModel) {
        this.defaultChatModel = defaultChatModel;
    }

    /**
     * 运行时动态指定模型 - 无需重启
     */
    public String chatWithDynamicModel(String message, String targetModel) {
        ChatOptions runtimeOptions = ChatOptionsBuilder.builder()
            .withModel(targetModel)  // 运行时指定模型
            .withTemperature(0.7)
            .build();

        Prompt prompt = new Prompt(
            List.of(new UserMessage(message)),
            runtimeOptions
        );

        return defaultChatModel.call(prompt)
            .getResult().getOutput().getContent();
    }

    /**
     * 根据任务类型自动选择模型
     */
    public String autoSelectModel(String message, TaskType type) {
        String modelId = switch (type) {
            case CODE_GENERATION -> "qwen-coder-plus";   // 代码任务用 Coder
            case CREATIVE_WRITING -> "qwen-max";          // 创作用 Max
            case FAST_REPLY -> "qwen-turbo";              // 快速回复用 Turbo
            case COMPLEX_REASONING -> "qwen-plus";        // 复杂推理用 Plus
            default -> "qwen-plus";
        };
        
        return chatWithDynamicModel(message, modelId);
    }
}

6. Spring AI Alibaba 特有的模型扩展

6.1 通义千问系列模型矩阵

DashScope 平台提供了丰富的模型选择:

模型系列代表模型定位适用场景
Qwen-Maxqwen-max最强推理复杂逻辑、深度分析
Qwen-Plusqwen-plus均衡之选日常对话、一般任务
Qwen-Turboqwen-turbo速度优先快速响应、简单任务
Qwen-Coderqwen-coder-plus代码专家代码生成、审查、转换
Qwen-Longqwen-long长文本10万+字文档处理
Qwen-VLqwen-vl-max视觉理解图片分析、OCR
Qwen-Audioqwen-audio-turbo语音理解语音转写、音频分析

6.2 联网搜索能力

通义千问支持内置联网搜索,这是一个非常有用的功能:

public String chatWithWebSearch(String question) {
    DashscopeChatOptions options = DashscopeChatOptions.builder()
        .withModel("qwen-plus")
        .withEnableSearch(true)       // 开启联网搜索
        .withSearchOptions(SearchOptions.builder()
            .withEnableSource(true)   // 返回搜索来源
            .withCitation(true)       // 返回引用标注
            .build())
        .build();

    Prompt prompt = new Prompt(
        List.of(new UserMessage(question)),
        options
    );

    ChatResponse response = chatModel.call(prompt);
    
    // 获取带引用的回复
    String answer = response.getResult().getOutput().getContent();
    
    // 获取搜索来源信息
    Map<String, Object> metadata = response.getMetadata().getMetadata();
    List<String> sources = (List<String>) metadata.get("search_results");
    
    log.info("搜索来源: {}", sources);
    return answer;
}

6.3 长文本处理(Qwen-Long)

public String analyzeLongDocument(String documentContent) {
    DashscopeChatOptions options = DashscopeChatOptions.builder()
        .withModel("qwen-long")       // 支持10万+Token
        .withMaxTokens(8192)
        .withEnableSearch(false)      // 长文本模式下不需要搜索
        .build();

    Prompt prompt = new Prompt(
        List.of(
            new SystemMessage("请详细分析以下文档,提取关键信息并生成摘要。"),
            new UserMessage(documentContent)
        ),
        options
    );

    return chatModel.call(prompt)
        .getResult().getOutput().getContent();
}

7. 最佳实践与常见陷阱

✅ 最佳实践

1. 根据场景选择模型

public enum ModelSelectionStrategy {
    
    // 日常对话 - 使用 Plus,性价比最高
    DAILY_CHAT("qwen-plus", 0.7, 2048),
    
    // 代码生成 - 使用 Coder 系列
    CODE_GENERATION("qwen-coder-plus", 0.2, 4096),
    
    // 创意写作 - 使用 Max,创造性更强
    CREATIVE_WRITING("qwen-max", 0.85, 4096),
    
    // 快速问答 - 使用 Turbo,延迟最低
    QUICK_ANSWER("qwen-turbo", 0.5, 1024),
    
    // 长文档分析 - 使用 Long
    LONG_DOCUMENT("qwen-long", 0.3, 8192);
    
    private final String modelId;
    private final double temperature;
    private final int maxTokens;
}

2. 合理使用 Token 预算

@Service
public class TokenAwareChatService {

    private final ChatModel chatModel;
    private final TokenBudgetTracker tokenTracker;  // 自定义的Token追踪器

    public TokenAwareChatService(ChatModel chatModel, TokenBudgetTracker tracker) {
        this.chatModel = chatModel;
        this.tokenTracker = tracker;
    }

    public String chatWithinBudget(String message, int budgetTokens) {
        int estimatedPromptTokens = estimateTokenCount(message);
        int remainingBudget = budgetTokens - estimatedPromptTokens;
        
        if (remainingBudget <= 0) {
            throw new TokenBudgetExceededException("Token预算不足");
        }

        DashscopeChatOptions options = DashscopeChatOptions.builder()
            .withMaxTokens(Math.min(remainingBudget, 4096))
            .build();

        ChatResponse response = chatModel.call(new Prompt(message, options));
        
        // 更新Token使用统计
        tokenTracker.record(
            response.getMetadata().getUsage().getTotalTokens());
        
        return response.getResult().getOutput().getContent();
    }
}

3. 分离系统提示词和业务逻辑

@Component
public class PromptTemplateService {
    
    // 使用 Spring 的 @Value 注入模板,或使用配置文件管理
    private static final String CODE_REVIEW_TEMPLATE = """
        你是一个资深的 Java 代码审查专家。请按照以下标准审查代码:
        
        1. 代码规范:是否符合阿里巴巴 Java 开发手册
        2. 性能:是否存在性能瓶颈
        3. 安全:是否存在 SQL 注入、XSS 等安全漏洞
        4. 可维护性:命名、结构是否清晰
        5. 最佳实践:是否使用了合适的模式和技术
        
        请给出具体修改建议和改进后的代码。
        """;
    
    public String reviewCode(String code) {
        Prompt prompt = new Prompt(List.of(
            new SystemMessage(CODE_REVIEW_TEMPLATE),
            new UserMessage("请审查以下代码:\n\n" + code)
        ));
        
        return chatModel.call(prompt)
            .getResult().getOutput().getContent();
    }
}

❌ 常见陷阱

陷阱 1:忘记配置 API Key

Error: Dashscope API key is required but not found.
Please set spring.ai.dashscope.api-key or DASHSCOPE_API_KEY environment variable.

解决: 确保通过环境变量或配置文件正确设置了 API Key。

陷阱 2:模型不支持某些参数

不同模型支持的参数不同。例如:

  • qwen-turbo 不支持 enableSearch
  • qwen-long 不支持流式输出

解决: 查阅文档,确认目标模型支持所需参数。

陷阱 3:忽略 Token 限制

// ❌ 错误:直接传入超长文本
String hugeText = loadFile("large-document.txt");  // 50万字
chatModel.call(new Prompt(hugeText));  // 会报错

// ✅ 正确:先检查长度,再分块处理
String hugeText = loadFile("large-document.txt");
if (estimateTokenCount(hugeText) > 100_000) {
    // 使用 qwen-long 或分块处理
    return processInChunks(hugeText);
}

陷阱 4:硬编码模型参数

// ❌ 错误:参数写死在代码中
Prompt prompt = new Prompt(message, 
    DashscopeChatOptions.builder()
        .withTemperature(0.7)  // 硬编码
        .withModel("qwen-plus") // 硬编码
        .build());

// ✅ 正确:通过配置管理
Prompt prompt = new Prompt(message, 
    chatOptionsProvider.getOptions());  // 从配置中心获取

8. 总结

本文深入剖析了 Spring AI Alibaba 的 Model 体系,核心要点:

  1. 三层架构:顶层 Model<Request, Response> 泛型接口 → 具体类型接口(ChatModel/EmbeddingModel/ImageModel) → 各云厂商的具体实现
  2. 工厂模式:通过 @ConditionalOnProperty 实现按需创建,@ConditionalOnMissingBean 支持自定义覆盖
  3. 配置优先级:代码动态设置 > Bean 级别配置 > YAML 全局配置
  4. 模型选择策略:根据场景(代码/创作/快速/长文本)选择不同模型,实现成本与效果的最优平衡
  5. 多模型并行:通过 @Qualifier 区分不同模型 Bean,或通过运行时 ChatOptions 动态切换
  6. 阿里特色能力:联网搜索、长文本支持、多模态理解等