行业资讯 2025年08月6日
0 收藏 0 点赞 678 浏览 12915 个字
摘要 :

文章目录 一、获取API密钥 二、配置项目依赖 三、Spring AI模块有哪些功能? (一)客户端API (二)输出转换器 (三)检索增强生成(RAG) (四)向量存储集成 四、S……




  • 一、获取API密钥
  • 二、配置项目依赖
  • 三、Spring AI模块有哪些功能?
    • (一)客户端API
    • (二)输出转换器
    • (三)检索增强生成(RAG)
    • (四)向量存储集成
  • 四、Spring AI聊天完成示例
  • 五、Spring AI提示模板示例
  • 六、Spring AI结构化输出示例
  • 七、Spring AI图像生成示例
  • 八、总结

今天这篇文章带大家深入了解Spring AI,不仅会详细讲解它的核心概念,还会通过具体示例展示如何用简单文本提示与OpenAI的聊天和图像生成API进行交互。

一、获取API密钥

在开始使用Spring AI前,你得先拿到要接入的大语言模型(LLM)的API访问权限。本文以OpenAI的gpt-3.5-turbo模型为例,你需要在OpenAI官网注册账号,支付一点费用(我们这次花了5美元)后,就能获取API密钥啦。

项目API密钥(以前叫用户API密钥)是一串独一无二的编码字符串,它的作用是识别和验证用户或应用程序的身份。你可以在platform.openai.com/api-keys这个页面找到自己账号的密钥。在“使用情况”页面,还能查看每个API密钥的使用记录。Spring AI 从入门到实战示例

名称 密钥 创建时间 最后使用时间 创建者 权限
testkey sk-… 2024年5月8日 2024年5月9日 Lokesh Gupta 全部

点击“创建新密钥”就能生成新的密钥。Spring AI模块针对不同的大语言模型定义了不同的密钥名称,没有固定的标准。一般来说,密钥名称遵循SPRING_AI_<LLM>_API_KEY这种格式。比如OpenAI的密钥名是spring.ai.openai.api-key,Mistral的则是spring.ai.mistralai.api-key

为了安全起见,建议把API密钥添加到机器的环境变量里,然后在应用配置文件中引用它。当然,也可以直接把密钥写在application.properties文件里。下面这个例子是把API密钥导出到OPENAI_API_KEY环境变量中:

export OPENAI_API_KEY=[从OpenAI网站复制的密钥]

如果是在Windows系统上,可以在系统属性里添加环境变量:

  1. 找到“用户变量”区域。
  2. 新建一个变量,变量名为OPENAI_API_KEY,变量值填写从OpenAI获取的密钥。

Spring AI 从入门到实战示例

之后,在项目的属性文件里就能这样引用这个API密钥:

spring.ai.openai.api-key=${OPENAI_API_KEY}

二、配置项目依赖

在Spring Boot应用里,想要支持Spring AI,得添加spring-ai-openai-spring-boot-starter这个依赖。在pom.xml文件里添加如下配置:

<properties>
    <java.version>21</java.version>
    <spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version> 
</properties>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

目前Spring AI还在开发阶段,所以要从里程碑仓库拉取依赖。最新版本信息可以去官方GitHub页面查看。在pom.xml里添加仓库配置:

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>

此外,为了创建Web组件并处理与后端大语言模型的HTTP连接,还需要添加spring-webspring-webflux以及可选的HTTP客户端依赖:

<dependencies>
    <!-- 其他依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

三、Spring AI模块有哪些功能?

Spring AI是Spring框架生态系统的新成员,主要用于开发专注于生成式AI的应用程序,这类应用能根据输入的提示生成新内容。它在后端会调用OpenAI的API,然后把响应结果返回给用户。

简单来说,Spring AI提供了一个基于文本的生成式AI系统。用户输入文本,应用程序就会以不同格式(比如字符串、映射、列表、XML、JSON、图像、视频等)给出相关的输出。为了生成这些响应,Spring AI集成了许多主流的生成式AI模型,像OpenAI、Azure Open AI、Bedrock(亚马逊)、Ollama以及Vertex AI(谷歌)的模型都支持。下面详细看看它的一些关键功能。

(一)客户端API

与OpenAI大语言模型交互时,有几个重要的类和接口:

  • ChatClient / ChatModel:这是基于文本交互的核心接口。不管是简单请求,还是基于提示的请求,又或是要求特定格式(如JSON、XML)响应的请求,都可以用它来处理。
  • ImageModel:专门用来调用特定供应商的图像生成API。用这个客户端发送文本请求后,会在响应里得到生成图像的URL。
  • SpeechModel / StreamingSpeechModel:用于调用供应商的文本转语音生成API(TTS-1)。发送文本请求后,能收到语音文件的路径。
  • AudioTranscriptionModel:可以调用特定供应商的音频转录(语音转文本)模型,目前只支持OpenAI的whisper-1模型。
  • EmbeddingModel:用于调用特定供应商的向量嵌入模型,在向量存储中进行相似性搜索时经常会用到它。

下面这段Java代码展示了如何配置这些客户端:

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.image.ImageClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiAudioSpeechClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.ai.openai.audio.speech.SpeechClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 配置类,用于定义Spring容器中的Bean
@Configuration 
public class AppConfiguration {
    // 配置SpeechClient Bean
    @Bean 
    SpeechClient speechClient(@Value(\"${spring.ai.openai.api-key}\") String apiKey) {
        // 创建OpenAiAudioSpeechClient实例,传入OpenAiAudioApi对象(包含API密钥)
        return new OpenAiAudioSpeechClient(new OpenAiAudioApi(apiKey)); 
    }

    // 配置ImageClient Bean
    @Bean 
    ImageClient imageClient(@Value(\"${spring.ai.openai.api-key}\") String apiKey) {
        // 创建OpenAiImageClient实例,传入OpenAiImageApi对象(包含API密钥)
        return new OpenAiImageClient(new OpenAiImageApi(apiKey)); 
    }

    // 配置ChatClient Bean
    @Bean 
    ChatClient chatClient(@Value(\"${spring.ai.openai.api-key}\") String apiKey) {
        // 创建OpenAiChatClient实例,传入OpenAiApi对象(包含API密钥)
        return new OpenAiChatClient(new OpenAiApi(apiKey)); 
    }
}

(二)输出转换器

和大语言模型交互时,并不总是用纯文本格式。有时候,应用程序需要特定结构(比如符合特定JSON模式)的输出。这种情况下,可以根据实际需求选择合适的转换器。

输出转换器主要干两件事:一是在提示中指定想要的响应格式和结构,这样能保证模型生成的响应格式规范;二是收到响应后,把它解析成所需的格式,比如Java Bean、列表或者映射。常见的输出转换器有:

  • BeanOutputConverter:它会根据Java Bean的字段生成JSON格式,用这个格式向大语言模型请求输出,然后再把模型的输出通过JSON模式转换成特定的Java Bean实例。
  • ListOutputConverter:它会让提示要求大语言模型以逗号分隔值的JSON格式输出,之后再把响应转换成java.util.List实例。
  • MapOutputConverter:它要求提示大语言模型以JSON格式输出,并且结构是java.util.HashMap类型,最后把响应转换成java.util.Map实例。

(三)检索增强生成(RAG)

如果希望大语言模型根据指定文档里的信息来回答问题,Spring AI提供的文档读取器就能派上用场啦,这在检索增强生成(RAG)场景里特别有用。

Spring AI的文档读取器API支持多种格式,像纯文本、JSON、Apache Tika能处理的格式,还有PDF都没问题。在Spring AI的文档处理功能里,主要涉及这些类和接口:

  • Document:用文本形式表示数据和元数据。
  • DocumentReader:负责从数据源(比如PDF、Markdown、JSON文件)加载数据,返回一个列表。
  • DocumentWriter:把文档持久化存储到向量数据库里。
  • DocumentTransformer:对数据进行各种处理,像拆分、拼接等操作。
  • Embedding:把数据表示成列表形式,向量数据库会用它来计算用户查询和相关文档的“相似度”。
  • ContentFormatter:把文档的文本和元数据转换成适合作为AI提示的文本形式。
  • VectorStore:存储嵌入向量,用来进行相似性搜索。

(四)向量存储集成

向量存储(也叫向量数据库)能进行“相似性搜索”,有点像传统关系型数据库里的精确匹配,但更灵活。向量存储可以把文档数据拆分成小片段,在RAG相关的场景里,通常会用ETL管道把文档存储到向量数据库中。

当向量数据库收到一个向量作为查询条件时,它会返回和这个查询向量“相似”的向量。这些返回的向量对应的是文档的小片段,比起直接把整个文档发给大语言模型(这可是个开销很大的操作),发送这些小片段更高效。

Spring AI支持集成多种主流向量存储,像Chroma、Pinecone、Redis、Weavite、Milvus、Azure以及PostgreSQL(PG Vector)都可以。

四、Spring AI聊天完成示例

先来看个最简单的例子,用Spring AI让大语言模型(这里是OpenAI GPT)给我们讲个笑话。这个示例里,提示就是简单的一句话,也不用指定响应格式。

下面这个tellSimpleJoke()方法用到了前面提到的ChatClient API,它会把“讲个笑话”这个简单提示发给大语言模型,然后把收到的响应放到一个映射里,再返回给API调用者。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.ai.chat.ChatClient;
import java.util.Map;

// 定义一个RestController,用于处理HTTP请求
@RestController 
public class OpenAiChatController {
    // 注入ChatClient实例
    private final ChatClient chatClient; 

    // 通过构造函数注入ChatClient
    @Autowired 
    public OpenAiChatController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    // 处理GET请求,路径为/joke-service/simple
    @GetMapping(\"/joke-service/simple\") 
    public Map<String, String> tellSimpleJoke() {
        // 调用ChatClient的call方法发送提示,把响应结果放入Map中返回
        return Map.of(\"generation\", chatClient.call(\"Tell me a joke\")); 
    }
}

接下来测试一下这个API,Spring AI 从入门到实战示例在浏览器地址栏输入http://localhost:8080/joke-service/simple,或者用API测试工具发送请求,得到的响应可能是这样:

{
    \"generation\": \"why don\'t scientists trust atoms?\\n\\nBecause they make up everything!\"
}

如果想实现模型响应的流式输出,只要客户端实现类实现了StreamingChatClient接口,就可以调用chatClient.stream()方法。比如OpenAiChatClient类就同时实现了ChatClientStreamingChatClient接口。

五、Spring AI提示模板示例

提示模板(PromptTemplate)和Java 21里的模板字符串有点像。在提示模板的字符串里,有一些可以替换的占位符,在运行时会根据传入的参数进行替换。比如在application.properties文件里定义了这样一个提示模板:

app.joke.simple.promptTemplate=Tell me a joke about {subject} in {language}.

这里的{subject}{language}就是模板参数,会在运行时传入具体的值。Spring AI的PromptTemplate类能解析这样的提示模板,并把它传给ChatClient.call()方法。

下面这段代码展示了如何使用提示模板:

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.prompt.Prompt;
import org.springframework.ai.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// 定义一个RestController,用于处理HTTP请求
@RestController 
public class OpenAiChatController {
    // 注入ChatClient实例
    private final ChatClient chatClient; 
    // 注入提示模板字符串
    private String promptTemplate; 

    // 通过构造函数注入ChatClient和提示模板字符串
    @Autowired 
    public OpenAiChatController(ChatClient chatClient,
                                @Value(\"${app.joke.simple.promptTemplate}\") String promptTemplate) {
        this.chatClient = chatClient;
        this.promptTemplate = promptTemplate;
    }

    // 处理GET请求,路径为/joke-service/simple-with-prompt
    @GetMapping(\"/joke-service/simple-with-prompt\") 
    public String tellSimpleJokeWithPrompt(@RequestParam(\"subject\") String subject,
                                           @RequestParam(\"language\") String language) {
        // 创建PromptTemplate实例
        PromptTemplate pt = new PromptTemplate(promptTemplate); 
        // 根据传入的参数替换模板占位符,生成最终的提示
        Prompt renderedPrompt = pt.create(Map.of(\"subject\", subject, \"language\", language)); 

        // 调用ChatClient的call方法发送提示,获取响应
        ChatResponse response = chatClient.call(renderedPrompt); 
        // 返回响应结果中的内容
        return response.getResult().getOutput().getContent(); 
    }
}

在这段代码里,从API用户那里获取笑话主题和语言作为请求参数。现在来测试一下:在浏览器地址栏输入http://localhost:8080/joke-service/simple-with-prompt?subject=Car&language=Hindi,或者用API测试工具发送请求,就能得到根据指定主题和语言生成的笑话啦。Spring AI 从入门到实战示例

六、Spring AI结构化输出示例

对于聊天机器人这类应用,简单的文本输出可能就够用了。但在数据密集型的智能应用里,往往需要像在典型REST API里使用Java Bean那样,以复杂格式(如XML、JSON)进行请求和响应。

下面这个示例对前面的API进行了修改,让它以JSON格式请求和响应,并且定义了一个JokeResponse记录类型来规范响应字段:

// 定义JokeResponse记录类型,包含笑话主题、语言和笑话内容三个字段
public record JokeResponse(String subject, String language, String joke) { } 

这个API用到了BeanOutputConverter类,它会根据指定的Java Bean导出JSON格式,然后用parse()方法把JSON响应转换成JokeResponse对象。

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.prompt.Prompt;
import org.springframework.ai.prompt.PromptTemplate;
import org.springframework.ai.response.BeanOutputConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// 定义一个RestController,用于处理HTTP请求
@RestController 
public class OpenAiChatController {
    // 注入ChatClient实例
    private final ChatClient chatClient; 
    // 注入JSON格式提示模板字符串
    private String jsonPromptTemplate; 

    // 通过构造函数注入ChatClient和JSON格式提示模板字符串
    @Autowired 
    public OpenAiChatController(ChatClient chatClient,
                                @Value(\"${app.joke.formatted.promptTemplate}\") String promptTemplate) {
        this.chatClient = chatClient;
        this.jsonPromptTemplate = promptTemplate;
    }

    // 处理GET请求,路径为/joke-service/json-with-prompt
    @GetMapping(\"/joke-service/json-with-prompt\") 
    public JokeResponse tellFormattedJokeWithPrompt(
    @RequestParam(\"subject\") String subject,
    @RequestParam(\"language\") String language) {
        // 创建提示模板对象
        PromptTemplate pt = new PromptTemplate(jsonPromptTemplate);
        // 使用参数渲染提示
        Prompt renderedPrompt = pt.create(Map.of(\"subject\", subject, \"language\", language));
        // 创建BeanOutputConverter对象,将响应转换为JokeResponse类型
        BeanOutputConverter<JokeResponse> converter = new BeanOutputConverter<>(JokeResponse.class);
        // 调用ChatClient发送请求并获取响应,同时进行转换
        JokeResponse response = chatClient.call(renderedPrompt, converter);
        return response;
    }
}

application.properties文件中,定义了一个JSON格式的提示模板:

app.joke.formatted.promptTemplate=Tell me a joke about {subject} in {language} and return the response in JSON format with keys \"subject\", \"language\", \"joke\".

这个模板要求大语言模型以JSON格式返回笑话,并且指定了JSON对象的键。

现在来测试这个API,Spring AI 从入门到实战示例在浏览器地址栏输入http://localhost:8080/joke-service/json-with-prompt?subject=Dog&language=English,或者使用API测试工具发送请求,得到的响应可能是这样:

{
    \"subject\": \"Dog\",
    \"language\": \"English\",
    \"joke\": \"Why don\'t dogs make good dancers? Because they have two left feet!\"
}

七、Spring AI图像生成示例

接下来看看如何使用Spring AI的ImageClient接口,调用OpenAI的图像生成API。在这个示例中,我们会发送一个简单的文本提示,让模型生成图像。

首先,在配置类中定义ImageClient的Bean:

import org.springframework.ai.image.ImageClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 配置类,用于定义Spring容器中的Bean
@Configuration
public class AppConfiguration {
    // 配置ImageClient Bean
    @Bean
    ImageClient imageClient(@Value(\"${spring.ai.openai.api-key}\") String apiKey) {
        // 创建OpenAiImageClient实例,传入OpenAiImageApi对象(包含API密钥)
        return new OpenAiImageClient(new OpenAiImageApi(apiKey));
    }
}

然后,创建一个控制器来处理图像生成请求:

import org.springframework.ai.image.ImageClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// 定义一个RestController,用于处理HTTP请求
@RestController
public class OpenAiImageController {
    // 注入ImageClient实例
    private final ImageClient imageClient;

    // 通过构造函数注入ImageClient
    @Autowired
    public OpenAiImageController(ImageClient imageClient) {
        this.imageClient = imageClient;
    }

    // 处理GET请求,路径为/image-service/generate
    @GetMapping(\"/image-service/generate\")
    public String generateImage(@RequestParam(\"prompt\") String prompt) {
        // 调用ImageClient的generate方法生成图像,返回图像URL
        return imageClient.generate(prompt);
    }
}

在这个示例中,generateImage方法接收一个文本提示作为参数,调用ImageClientgenerate方法生成图像,并返回生成图像的URL。

现在来测试这个API,Spring AI 从入门到实战示例在浏览器地址栏输入http://localhost:8080/image-service/generate?prompt=A beautiful sunset over the ocean,或者使用API测试工具发送请求,就能得到一个包含生成图像URL的响应。Spring AI 从入门到实战示例

八、总结

通过这篇文章,我们详细了解了Spring AI的基本概念和使用方法,包括获取API密钥、配置项目依赖、使用Spring AI的各种功能,以及通过多个示例展示了如何与OpenAI的大语言模型和图像生成API进行交互。希望这些内容能帮助大家,如果在实践过程中有任何问题,欢迎在评论区交流讨论!

归属教程 Spring AI 快速入门教程汇总

文章目录 Spring AI是什么?有啥优势? 如何在项目中使用Spring AI? Spring AI详细功 […]

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10276.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号