Skip to content

Spring AI 学习指南

要点

  • Spring AI 采用分层架构设计,旨在通过可移植的 API 抽象层简化企业数据/API 与多种 AI 模型的集成。
  • 框架支持多种类型的 AI 模型,包括聊天模型、嵌入模型、文本到图像模型以及音频处理模型。
  • 核心功能包括结构化输出转换、工具/函数调用机制、检索增强生成 (RAG) 以及与 Spring Boot 的无缝集成。
  • ChatClient API 是与 AI 模型交互的核心接口,支持同步和流式响应,并提供灵活的配置选项。
  • Spring AI 强调 Prompt 工程、嵌入向量的应用以及 Token 管理,以优化 AI 交互的效率和成本。
  • 提供灵活的配置系统,支持启动时默认配置和运行时选项覆盖,以及模型特定选项的扩展。

概述

Spring AI 是一个旨在简化将人工智能(AI)功能集成到 Spring 应用程序中的框架。它通过提供一套统一的 API 和抽象,使得开发者可以轻松地与各种大型语言模型(LLM)、嵌入模型和向量数据库进行交互,而无需关注底层实现的复杂性。Spring AI 的核心思想是将企业数据和 API 通过一个抽象层与 AI 模型连接起来,从而加速 AI 驱动应用的开发。其设计借鉴了 Spring Framework 的成熟模式,如类似 Spring MVC 的 Prompt 模板机制,为开发者提供了熟悉且高效的开发体验。

该框架不仅支持基础的 AI 模型交互,如聊天和文本嵌入,还提供了高级功能,例如检索增强生成(RAG)、工具调用(Function Calling)、结构化输出以及内容审核等。通过与 Spring Boot 的深度集成,Spring AI 提供了自动配置和启动器,进一步简化了项目的搭建和部署。


详细分析

1. 架构设计

Spring AI 采用分层架构,其核心是将应用程序的业务逻辑与具体的 AI 模型实现解耦。这种设计提供了高度的灵活性和可移植性。

Spring AI架构

主要架构特点包括: * 可移植的 API 抽象层:为不同的 AI 模型(如 OpenAI, Azure OpenAI, Bedrock 等)和向量数据库提供统一的接口。 * 类 Spring MVC 设计模式:例如,Prompt 模板在概念上类似于视图(View),用于动态生成发送给 AI 模型的输入。 * 灵活的选项机制:支持在运行时覆盖启动时配置的默认选项,允许动态调整模型参数。 * 标准化的输入输出处理:统一不同 AI 模型返回结果的处理方式,简化了应用层代码。

2. 核心功能模块

Spring AI 提供了一系列功能模块,以满足不同场景下的 AI 应用需求。

2.1 AI 模型支持

  • 聊天模型 (Chat Models):支持与 LLM 进行对话式交互,能够处理同步和流式响应,并支持多角色消息(如 system, user, assistant)。
  • 嵌入模型 (Embedding Models):将文本转换为数值向量(嵌入),用于语义搜索、文本聚类等任务。
  • 文本到图像 (Text-to-Image Models):利用生成式 AI 技术,根据文本描述创建图像。
  • 音频处理 (Audio Processing):包括语音转录(Speech-to-Text)和文本转语音(Text-to-Speech)功能。
  • 内容审核 (Content Moderation):提供 API 来自动过滤或标记不当内容。

2.2 关键能力

  • 结构化输出 (Structured Output):能够将 AI 模型的非结构化文本输出自动转换为预定义的 Java 对象 (POJO),简化数据提取。
  • 工具/函数调用 (Tool/Function Calling):允许 LLM 调用外部 API 或服务,扩展其能力边界,实现更复杂的任务。
  • 可观测性 (Observability):集成监控和追踪能力,方便开发者了解 AI 调用的性能和行为。
  • 文档 ETL 框架 (Document ETL Framework):提供文档加载、转换和加载的管道,用于数据预处理,尤其在 RAG 场景中非常重要。
  • AI 模型评估 (AI Model Evaluation):提供 API 用于评估 AI 模型的输出质量。
  • Spring Boot 集成:通过自动配置和 Starter 依赖,简化 Spring AI 在项目中的引入和使用。

2.3 高级功能

检索增强生成 (RAG)

RAG 是一种将外部知识库与 LLM 结合的技术,以提高生成内容的准确性和相关性。Spring AI 提供了对 RAG 模式的内置支持。

RAG架构

其流程通常包括: 1. 文档分块与嵌入:将外部文档分割成小块,并为每块生成嵌入向量。 2. 向量数据库集成:将嵌入向量存储在向量数据库中,以便进行高效的相似性搜索。 3. 查询时上下文增强:当用户提问时,首先在向量数据库中检索相关文档块,然后将这些信息作为上下文与用户问题一起提供给 LLM。

工具调用 (Tool Calling)

工具调用允许 LLM 在需要时执行外部函数或 API,以获取实时信息或执行特定操作。

工具调用流程

主要特点: * 注解驱动的 API 绑定:通过注解将 Java 方法暴露给 LLM 作为可调用的工具。 * 动态工具注册:支持在运行时动态注册和管理可用的工具。 * 多步骤执行流程:LLM 可以决定调用哪个工具以及何时调用,并能处理工具的返回结果以继续对话或生成最终答案。

3. 核心 API 与代码示例

Spring AI 的核心 API 设计简洁且易于使用,ChatClient 是进行聊天交互的主要入口。

3.1 ChatModel 与 ChatClient API

ChatModel 是一个通用接口,定义了与模型交互的基本方法。

public interface ChatModel extends Model<Prompt, ChatResponse> {
    ChatResponse call(Prompt prompt);
    // 其他方法,如流式处理等
}

ChatClient 提供了更流畅的 API 来构建请求和处理响应。

基础使用示例 (自动配置):

@RestController
class MyController {
    private final ChatClient chatClient;

    // Spring Boot 3.2+ 支持构造函数注入 ChatClient.Builder
    public MyController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    @GetMapping("/ai")
    String generation(String userInput) {
        return this.chatClient.prompt()
            .user(userInput)
            .call()
            .content();
    }
}

多模型配置示例: 如果应用需要与多个不同的 AI 模型提供商交互,可以进行如下配置:

@Configuration
public class ChatClientConfig {
    // 假设已配置 OpenAiChatModel 和 AnthropicChatModel Beans
    @Bean
    public ChatClient openAiChatClient(OpenAiChatModel chatModel) {
        return ChatClient.create(chatModel);
    }

    @Bean
    public ChatClient anthropicChatClient(AnthropicChatModel chatModel) {
        return ChatClient.create(chatModel);
    }
}

3.2 Prompt 模板与消息处理

Prompt 工程是与 LLM 有效交互的关键。Spring AI 提供了强大的 Prompt 模板功能。

消息处理: * 支持多角色消息:SystemMessage (设定 AI 行为)、UserMessage (用户输入)、AssistantMessage (AI 回复)。 * 支持多媒体内容(如图像)作为输入。 * 允许为消息附加元数据。

带参数的 Prompt 模板示例:

// 假设 chatModel 已被注入或创建
String composerName = "John Williams";
String promptText = "List movies composed by " + composerName;

String answer = ChatClient.create(chatModel).prompt()
    .user(u -> u
        .text("Movies by <composer>") // 使用占位符
        .param("composer", composerName)) // 填充参数
    // .templateRenderer(StTemplateRenderer.builder() // 可选:自定义模板渲染器
    //     .startDelimiterToken('<')
    //     .endDelimiterToken('>')
    //     .build())
    .call()
    .content();

// System.out.println(answer);

系统提示模板:

// 假设 chatModel 已被注入或创建
ChatClient clientWithSystemPrompt = ChatClient.builder(chatModel)
    .defaultSystem("You are a helpful {role}") // 设置默认系统提示模板
    .build();

String response = clientWithSystemPrompt.prompt()
    .system(s -> s.param("role", "Java expert")) // 填充系统提示参数
    .user("Explain Spring AI in brief.")
    .call()
    .content();

// System.out.println(response);

3.3 配置系统

Spring AI 的配置系统非常灵活,允许开发者在不同层面进行定制。 * 启动时默认配置:通过 application.propertiesapplication.yml 设置全局默认参数。 * 运行时选项覆盖:在构建 Prompt 对象时,可以传入 ChatOptions 来覆盖默认配置,针对单次调用生效。 * 模型特定选项扩展:每种 AI 模型实现(如 OpenAiChatOptions)可以有其特有的配置项。

自定义 API 端点和模型选项配置示例 (以 OpenAI 为例):

// 假设 baseOpenAiApi 和 baseChatModel 是基础配置的 Beans
// OpenAiApi newApi = baseOpenAiApi.mutate()
//     .baseUrl("https://api.example.com/openai") // 自定义 API 地址
//     .apiKey("YOUR_CUSTOM_API_KEY")
//     .build();

// OpenAiChatModel newModel = baseChatModel.mutate()
//     .openAiApi(newApi)
//     .defaultOptions(OpenAiChatOptions.builder()
//         .withModel("gpt-4-custom") // 使用自定义模型
//         .withTemperature(0.7f)
//         .build())
//     .build();

// ChatClient customClient = ChatClient.create(newModel);
// String result = customClient.prompt().user("Tell me a joke").call().content();

注:上述代码片段为演示结构,实际使用时需确保 baseOpenAiApibaseChatModel 已正确初始化。

3.4 流式响应处理

对于需要逐步显示结果的场景(如聊天机器人),Spring AI 支持流式响应。

响应式流处理 (Reactive Stream):

@GetMapping("/stream")
public Flux<String> streamGeneration(String message) {
    // 假设 chatClient 已被注入
    return chatClient.prompt()
        .user(message)
        .stream()
        .content(); // 返回一个 Flux<String>,每个元素是响应内容的一部分
}

3.5 聊天记忆配置

为了在多轮对话中保持上下文,Spring AI 支持聊天记忆功能。

// 假设 chatModel 已被注入或创建
// ChatClient clientWithMemory = ChatClient.builder(chatModel)
//     .defaultAdvisors(new MessageChatMemoryAdvisor(
//         new MessageWindowChatMemory(20) // 保留最近20条消息
//     ))
//     .build();

// // 第一次调用
// String response1 = clientWithMemory.prompt()
//     .user("My name is Bob.")
//     .call().content();

// // 第二次调用,AI应该能记住之前的对话
// String response2 = clientWithMemory.prompt()
//     .user("What is my name?")
//     .call().content(); // AI 应该回答 "Your name is Bob."

注:上述代码片段为演示结构,实际使用时需确保相关依赖和配置正确。

4. 关键概念

理解以下关键概念有助于更好地使用 Spring AI:

4.1 Prompt 工程

Prompt 工程是指设计和优化输入给 LLM 的文本(即 Prompt),以获得期望输出的艺术和科学。 * 动态模板填充:使用变量和模板引擎动态生成 Prompt。 * 多消息组合:通过组合不同角色的消息(System, User, Assistant)来引导对话。 * 角色指定:明确指定消息的角色,以影响模型的行为和响应风格。

4.2 嵌入向量 (Embeddings)

嵌入向量是将文本或其他数据类型(如图像)转换为高维空间中的数值向量的过程。

嵌入向量

  • 语义相似度计算:在向量空间中,语义相似的文本其向量表示也更接近。
  • 高维空间映射:文本被映射到一个包含丰富语义信息的高维向量空间。
  • 检索优化:嵌入向量是实现高效语义搜索和 RAG 的基础。

4.3 Token 管理

Token 是 LLM 处理文本的基本单位,可以是一个词、一个子词或一个字符。 * 上下文窗口限制:大多数 LLM 都有一个最大的 Token 输入限制(上下文窗口),超出部分会被截断或导致错误。 * 成本控制:许多商业 LLM API 的收费与处理的 Token 数量相关。 * 自动分块处理:在处理长文档时,需要将其分割成适合模型上下文窗口的块(Chunks)。


关键引用

- spring-ai-alibaba GitHub Repository (示例参考)

本文由Proteus自动生成