SpringAI的使用

Spring AI 是 Spring 官方推出的 AI 应用开发框架,旨在简化 AI 模型(如大语言模型、嵌入模型等)与 Spring 生态的集成,提供统一的 API 抽象,支持多类 AI 服务(如 OpenAI、Azure OpenAI、Hugging Face 等)和向量存储(如 Redis、Milvus 等),让开发者更专注于业务逻辑而非 AI 服务的底层调用细节。

一、核心概念

在使用 Spring AI 前,需理解几个核心概念:

  • 模型(Model):AI 服务的抽象(如大语言模型、嵌入模型),Spring AI 提供统一接口,屏蔽不同厂商(如 OpenAI、Anthropic)的差异。
  • 提示(Prompt) :输入给模型的指令或问题,由提示文本(Prompt Text)系统消息(System Message) 组成(系统消息用于定义模型的行为)。
  • 响应(Response):模型返回的结果,包含生成的文本、元数据(如令牌数、耗时)等。
  • 提示模板(Prompt Template):动态生成提示的模板,支持变量填充(类似模板引擎),适用于需要动态参数的场景。
  • 函数调用(Function Calling):模型根据问题自动调用外部工具(如数据库查询、API 调用)的能力,Spring AI 提供工具注册和调用机制。
  • 向量存储(Vector Store):存储嵌入向量(文本的数值表示)的组件,用于相似性检索(核心用于 RAG 场景)。

二、环境搭建

Spring AI 基于 Spring Boot,需通过 starters 引入依赖。目前最新稳定版为 0.8.1(需注意版本兼容性)。

1. 依赖配置(Maven)

以集成 OpenAI 为例,在 pom.xml 中添加:

复制代码
<!-- Spring Boot 基础依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- Spring AI OpenAI 集成 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        <version>0.8.1</version>
    </dependency>
    <!-- Web 依赖(可选,用于接口暴露) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<!-- Spring AI 仓库(部分版本需指定) -->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
2. 配置 AI 服务密钥

application.yml 中配置 OpenAI 的 API 密钥(其他服务如 Azure OpenAI、Hugging Face 配置类似):

复制代码
spring:
  ai:
    openai:
      api-key: "你的OpenAI API密钥"  # 从 OpenAI 控制台获取
      # 可选:指定模型(默认使用 gpt-3.5-turbo)
      chat:
        model: gpt-3.5-turbo
      # 超时配置
      timeout: 30000

三、基础使用:调用大语言模型(LLM)

Spring AI 对大语言模型的调用封装在 ChatClient 接口中,通过注入即可使用。

1. 简单文本对话
复制代码
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemMessage;
import org.springframework.ai.chat.prompt.UserMessage;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatController {

    // 注入 ChatClient(由 Spring AI 自动配置,基于 openai  starter)
    private final ChatClient chatClient;

    public ChatController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/chat")
    public String chat(@RequestParam String question) {
        // 1. 构建提示(系统消息 + 用户问题)
        Prompt prompt = new Prompt(
            new SystemMessage("你是一个友好的助手,用简洁的语言回答问题。"),
            new UserMessage(question)
        );

        // 2. 调用模型
        ChatResponse response = chatClient.call(prompt);

        // 3. 返回生成的内容
        return response.getResult().getOutput().getContent();
    }
}

启动应用后,访问 http://localhost:8080/chat?question=Spring AI 是什么,即可得到模型的回答。

2. 使用提示模板(动态生成提示)

当提示需要动态参数(如用户输入、数据库查询结果)时,可使用 PromptTemplate

复制代码
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.ChatClient;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class RecommendService {

    private final ChatClient chatClient;

    public RecommendService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    // 根据用户兴趣推荐书籍
    public String recommendBooks(String userInterest) {
        // 1. 定义提示模板(使用 {variable} 作为占位符)
        String template = "用户喜欢 {interest},请推荐 3 本相关的经典书籍,每本简要说明理由。";
        
        // 2. 填充变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("interest", userInterest);
        
        // 3. 生成 Prompt
        PromptTemplate promptTemplate = new PromptTemplate(template, variables);
        Prompt prompt = promptTemplate.create();
        
        // 4. 调用模型
        return chatClient.call(prompt).getResult().getOutput().getContent();
    }
}

四、高级特性:函数调用(Function Calling)

函数调用允许模型根据问题自动触发外部工具(如查询数据库、调用天气 API),适用于需要模型结合外部数据回答的场景。

1. 定义工具函数

首先定义一个工具类,用 @Tool 注解标记可被模型调用的方法:

复制代码
import org.springframework.ai.core.Tool;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

@Component
public class WeatherTool {

    // 模拟查询天气的工具函数
    @Tool("查询指定城市的天气,参数为城市名称(如北京)")
    public String getWeather(String city) {
        // 实际场景中可调用第三方天气 API
        String date = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
        return String.format("城市:%s,日期:%s,天气:晴朗,温度:25℃", city, date);
    }
}
2. 配置函数调用客户端

需使用 FunctionCallingChatClient 替代基础 ChatClient,并注册工具:

复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.functions.FunctionCallingAdvisor;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ChatConfig {

    // 注册工具并创建支持函数调用的 ChatClient
    @Bean
    public ChatClient chatClient(OpenAiChatModel openAiChatModel, WeatherTool weatherTool) {
        return ChatClient.builder(openAiChatModel)
                .withAdvisor(new FunctionCallingAdvisor(weatherTool))  // 注册工具
                .build();
    }
}
3. 使用函数调用
复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WeatherController {

    private final ChatClient chatClient;

    public WeatherController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/weather")
    public String getWeatherAnswer(@RequestParam String question) {
        // 模型会自动判断是否需要调用工具
        String response = chatClient.prompt()
                .user(question)
                .call()
                .content();

        return response;
    }
}

当访问 http://localhost:8080/weather?question=上海今天的天气怎么样 时,模型会自动调用 WeatherTool.getWeather("上海"),并返回工具的结果。

五、向量存储与 RAG 应用

RAG(检索增强生成)是通过检索外部知识库(如文档、数据库)来增强模型回答准确性的技术,核心依赖向量存储。Spring AI 支持 Redis、Milvus、Pinecone 等向量存储。

1. 集成 Redis 向量存储

步骤 1:添加依赖

复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-redis-spring-boot-starter</artifactId>
    <version>0.8.1</version>
</dependency>

步骤 2:配置 Redis

复制代码
spring:
  redis:
    host: localhost
    port: 6379
  ai:
    embedding:
      openai:  # 使用 OpenAI 的嵌入模型生成向量
        api-key: "你的OpenAI API密钥"
    redis:
      vector-store:
        index-name: knowledge_index  # 向量存储的索引名
2. 存储与检索向量
复制代码
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class KnowledgeService {

    private final VectorStore vectorStore;
    private final EmbeddingClient embeddingClient;

    public KnowledgeService(VectorStore vectorStore, EmbeddingClient embeddingClient) {
        this.vectorStore = vectorStore;
        this.embeddingClient = embeddingClient;
    }

    // 向向量存储添加文档(如知识库内容)
    public void addKnowledge() {
        // 模拟知识库文档
        Document doc1 = new Document(
            "Spring AI 是 Spring 生态的 AI 开发框架,简化了 AI 模型的集成。"
        );
        Document doc2 = new Document(
            "Spring AI 支持 OpenAI、Azure OpenAI 等多种 AI 服务,提供统一 API。"
        );

        // 存储文档(内部会自动调用嵌入模型生成向量)
        vectorStore.add(List.of(doc1, doc2));
    }

    // 检索与问题相关的文档
    public List<Document> searchRelatedDocs(String question) {
        // 检索相似度最高的 2 个文档
        return vectorStore.similaritySearch(question, 2);
    }
}
3. 构建 RAG 应用

结合检索到的文档和模型生成回答:

复制代码
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class RagService {

    private final KnowledgeService knowledgeService;
    private final ChatClient chatClient;

    public RagService(KnowledgeService knowledgeService, ChatClient chatClient) {
        this.knowledgeService = knowledgeService;
        this.chatClient = chatClient;
    }

    public String answerWithKnowledge(String question) {
        // 1. 检索相关文档
        List<Document> docs = knowledgeService.searchRelatedDocs(question);
        
        // 2. 构建提示(将文档作为上下文)
        String context = docs.stream()
                .map(Document::getContent)
                .collect(Collectors.joining("\n"));
        String promptText = String.format(
            "基于以下上下文回答问题:\n%s\n问题:%s", 
            context, 
            question
        );
        
        // 3. 调用模型生成回答
        return chatClient.call(promptText);
    }
}

六、切换 AI 服务

Spring AI 的抽象层使切换不同 AI 服务非常简单,只需修改依赖和配置:

  • 切换到 Azure OpenAI

    替换依赖为 spring-ai-azure-openai-spring-boot-starter,并修改配置:

    复制代码
    spring:
      ai:
        azure:
          openai:
            api-key: "你的Azure API密钥"
            endpoint: "你的Azure endpoint(如https://xxx.openai.azure.com/)"
            deployment-name: "你的部署名(如gpt-35-turbo)"
  • 切换到 Hugging Face

    替换依赖为 spring-ai-huggingface-spring-boot-starter,配置 API 密钥和模型:

    复制代码
    spring:
      ai:
        huggingface:
          api-key: "你的Hugging Face API密钥"
          chat:
            model: "mistralai/Mistral-7B-Instruct-v0.1"

总结

Spring AI 核心价值在于:

  1. 统一抽象:屏蔽不同 AI 服务的差异,切换服务只需改配置;
  2. 简化集成:通过 Spring Boot starters 快速接入 AI 模型和向量存储;
  3. 增强能力:内置提示模板、函数调用、RAG 等高级特性,降低 AI 应用开发门槛。

更多细节可参考 Spring AI 官方文档,需注意其仍在快速迭代中,建议使用稳定版本。

相关推荐
小清兔4 分钟前
c#基础知识
开发语言·数据库·学习·unity·c#·游戏引擎·.net
计算机学姐1 小时前
基于SpringBoot的社团管理系统【2026最新】
java·vue.js·spring boot·后端·mysql·spring·mybatis
过往入尘土1 小时前
计算机视觉:从 “看见” 到 “理解”,解锁机器感知世界的密码
人工智能
天上掉下来个程小白1 小时前
微服务-25.网关登录校验-网关传递用户到微服务
java·数据库·微服务
奇某人1 小时前
【语法】【C+V】本身常用图表类型用法快查【CSDN不支持,VSCODE可用】
开发语言·vscode·markdown·mermaid
飞哥数智坊2 小时前
别再组团队了,AI时代一个人就能创业
人工智能·创业
做一位快乐的码农2 小时前
php程序设计之基于PHP的手工艺品销售网站/基于php在线销售系统/基于php在线购物商城系统
开发语言·php
vivi_and_qiao2 小时前
HTML的form表单
java·前端·html
严文文-Chris2 小时前
GPT5的Test-time compute(测试时计算)是什么?
人工智能
@珍惜一生@2 小时前
Qt开源库
开发语言·qt·开源