您的位置:首页 > 文旅 > 美景 > Spring AI来了

Spring AI来了

2024/10/6 1:34:53 来源:https://blog.csdn.net/dan_seek/article/details/142153603  浏览:    关键词:Spring AI来了

刚接触springAI的时候,它还只支持openAI,只能文字生成,既没有chatMemory也没有向量支持,现如今稳定版即将发布,该有的都有了,比起langchain4j,api用起来舒服些,关键它是spring出品的。

官网文档:https://docs.spring.io/spring-ai/reference/getting-started.html
在这里插入图片描述

1、引入相关包

1.1 指定版本

听说这个月会发布稳定的1.0版本,敬请期待,目前最新的是快照版,1.0.0-M2好多功能还没有。jdk版本需要17+

<properties><java.version>17</java.version><spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
<!--        <spring-ai.version>1.0.0-M2</spring-ai.version>--></properties>

1.2 引入bom

Spring AI材料清单(BOM)声明了给定Spring AI发行版所使用的所有依赖项的推荐版本。使用来自应用程序构建脚本的BOM避免了您自己指定和维护依赖版本的需要。

<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>

1.3 引入自动配置模块

引入对应大模型的依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI Open AI 自动配置模块 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency>
</dependencies>

如果是百度千帆

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-qianfan-spring-boot-starter</artifactId>
</dependency>

如果是智普

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId>
</dependency>

1.4 配置仓库

  <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>

1.5 在application.properties配置key

server.port=8080#Open AI的配置
spring.ai.openai.base-url=your model url
spring.ai.openai.api-key=your key
spring.ai.openai.chat.options.model=gpt-3.5-turbo# 调用api接口失败后的重试次数
spring.ai.retry.max-attempts=1#spring.ai.openai.image.options.model=dall-e-3# 打印详细日志
logging.level.org.springframework.ai.chat.client.advisor=DEBUG

2、hello world

ChatModel是一个接口,每个大模型都有它的实现类,open AI对应的是OpenAiChatModel。spring boot会帮我们自动实例化它,直接使用即可。

//    @Autowired
//    private OpenAiChatModel chatModel;@Autowiredprivate ChatModel chatModel;@GetMapping("/hello")public String helloWorld(@RequestParam("message") String message) {return chatModel.call(message);}

在浏览器输入:http://localhost:8080/hello?message=你是谁

浏览器显示如下

我是一个AI智能助手,可以帮助您回答问题和提供信息。您有什么需要我帮忙的吗?

3、chatClient

直接使用chatModle来编写复杂的业务是繁琐的, ChatClient提供了一个流畅的API来与AI模型进行通信 。它封装了chatModel,chatClient实例使用ChatClient.Builder来获取,我们使用chatClient来改写上面的代码

@RestController
public class HelloWorld {private final ChatClient chatClient1;public HelloWorld(ChatClient.Builder builder) {this.chatClient1 = builder.build();}@GetMapping("/hello")public String helloWorld(@RequestParam("message") String message) {return chatClient1.prompt().user(message).call().content();}
}

好像还变复杂了,对吧

流式输出,就是文字一个一个的输出,提升等待体验

    @GetMapping("/test3")public Flux<String> test3(@RequestParam("message") String message) {return chatClient1.prompt().user(message).stream().content();}

3.1 设置系统提示词

chatModel有4类消息,系统消息(配置模型能力),用户消息,AI回复消息,工具扩展消息(调用本地方法)

关于这些基础知识参考另一篇文章:https://blog.csdn.net/dan_seek/article/details/140755726

或者官网:https://docs.spring.io/spring-ai/reference/concepts.html

使用bean方式来实例化chatClient

@Configuration
public class Config {@BeanChatClient chatClient2(ChatClient.Builder builder){return builder// 指定系统提示词.defaultSystem("你是位资深诗人").build();}
}

控制器

    private final ChatClient chatClient2;    public _01_HelloWorld(ChatClient chatClient2) {this.chatClient2 = chatClient2;}	@GetMapping("/test1")public String test1(@RequestParam("message") String message) {return chatClient2.prompt().user(message).call().content();}

浏览器输入:http://localhost:8080/test1?message=写首歌颂小草的短诗

浏览器显示如下

小小的草儿绿叶茂,生长在田野间小道。 风吹过,摇曳舞,自由自在展翅飞。 细腻的叶片婀娜姿,静静地守护大地。 无声无息默默劳,润泽万物生生不息。 小草啊,你是大自然的守护神, 你的美丽与坚强,让人心生敬仰。

使用占位符传参

如果系统提示词是动态的,可以通过传参的方式

    @BeanChatClient chatClient3(ChatClient.Builder builder){return builder.defaultSystem("请模仿{name}的口吻回答问题,并告诉用户你的名字").build();}

控制器

	@Autowiredprivate ChatClient chatClient3;@GetMapping("/test2")public String test2(@RequestParam("message") String message) {String name = "庄子";return chatClient3.prompt()// 设置系统提示词参数.system(sp -> sp.param("name", name)).user(message).call().content();}

浏览器输入:http://localhost:8080/test2?message=你的梦想是什么

浏览器显示如下

吾乃庄周也。梦境乃人生之一部分,吾之梦想乃与天地相融,如风如云自在游荡,无拘无束,无忧无虑,与万物共舞共鸣。愿世人亦能放下烦恼,追寻内心最深处的宁静与自由。

3.2 记住历史会话

上面的对话中,你告诉大模型你的名字,然后马上问大模型我是谁,大模型是不知道的。因为大模型是无状态的,想让大模型知道上下文,你需要把历史记录一并发给大模型,借助chatMemory很容易实现。

chatMemory有一个默认的实现类,也可以自己实现一个保存至数据库的实现

	@Beanpublic ChatMemory chatMemory() {return new InMemoryChatMemory();}
    @BeanChatClient chatClient4(ChatClient.Builder builder, ChatMemory chatMemory){return builder.defaultSystem("你是一位友好的助手").defaultAdvisors(
//                        new PromptChatMemoryAdvisor(chatMemory) // 历史记录添加到系统文本中new MessageChatMemoryAdvisor(chatMemory) // 历史记录添加到消息列表中).build();}

控制器

    @Autowiredprivate ChatClient chatClient4;@GetMapping("/test4")public String test4(@RequestParam("message") String message) {// memory id 用于区分会话String chatId = "123456";return chatClient4.prompt().user(message).advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)// 设置记忆的会话长度 10条会话.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().content();}

3.3 输出详细日志

如果想要查看响应体里的数据结构,需要如下配置,稍作修改上面的chatClient

    @BeanChatClient chatClient4(ChatClient.Builder builder, ChatMemory chatMemory){return builder.defaultSystem("你是一位作家").defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory) // 历史记录添加到消息列表中// 启用日志,需要在配置文件配置 logging.level.org.springframework.ai.chat.client.advisor=DEBUG,new SimpleLoggerAdvisor(// 自定义日志输出
//                                request -> "Custom request: " + request.userText(),
//                                response -> "Custom response: " + response.getResult())).build();}

控制台日志如下

request: AdvisedRequest[chatModel=OpenAiChatModel [defaultOptions=OpenAiChatOptions: {“streamUsage”:false,“model”:“gpt-3.5-turbo”,“temperature”:0.7}], userText=我是小飞, systemText=你是一位作家, chatOptions=OpenAiChatOptions: {“streamUsage”:false,“model”:“gpt-3.5-turbo”,“temperature”:0.7}, media=[], functionNames=[], functionCallbacks=[], messages=[], userParams={}, systemParams={}, advisors=[org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor@27d1c903, SimpleLoggerAdvisor], advisorParams={chat_memory_response_size=2, chat_memory_conversation_id=123456}]
2024-09-12T00:26:33.525+08:00 DEBUG 560 — [ai-spring] [nio-8080-exec-1] o.s.a.c.c.advisor.SimpleLoggerAdvisor : response: {“result”:{“output”:{“messageType”:“ASSISTANT”,“metadata”:{“refusal”:“”,“finishReason”:“STOP”,“index”:0,“id”:“chatcmpl-A6KSmRO8aLFYHBemBI5Am78dfg7oG”,“role”:“ASSISTANT”,“messageType”:“ASSISTANT”},“toolCalls”:[],“content”:“你好,小飞!很高兴认识你。你喜欢写作吗?”},“metadata”:{“finishReason”:“STOP”,“contentFilterMetadata”:null}},“results”:[{“output”:{“messageType”:“ASSISTANT”,“metadata”:{“refusal”:“”,“finishReason”:“STOP”,“index”:0,“id”:“chatcmpl-A6KSmRO8aLFYHBemBI5Am78dfg7oG”,“role”:“ASSISTANT”,“messageType”:“ASSISTANT”},“toolCalls”:[],“content”:“你好,小飞!很高兴认识你。你喜欢写作吗?”},“metadata”:{“finishReason”:“STOP”,“contentFilterMetadata”:null}}],“metadata”:{“id”:“chatcmpl-A6KSmRO8aLFYHBemBI5Am78dfg7oG”,“model”:“gpt-3.5-turbo-0125”,“rateLimit”:{“requestsLimit”:5000,“requestsRemaining”:4999,“tokensLimit”:2000000,“tokensRemaining”:1999973,“requestsReset”:0.012000000,“tokensReset”:0.0},“usage”:{“generationTokens”:27,“promptTokens”:22,“totalTokens”:49},“promptMetadata”:[],“empty”:false}}

4、生成图片

可以在application.properties全局配置模型的相关参数,也可以在调用的时候指定

	@AutowiredImageModel imageModel;//    @Autowired
//    OpenAiImageModel imageModel2;@GetMapping("/testImage")public String test1() {ImageResponse response = imageModel.call(new ImagePrompt("给spring ai框架生成一个涂鸦" ));// 自定义图片参数
//        ImageOptions options = OpenAiImageOptions.builder()
//                .withModel("dall-e-3")
//                .withQuality("hd")
//                // 图片数量
//                .withN(1)
//                // 图片高度 Must be one of 256, 512, or 1024
//                .withHeight(512)
//                .withWidth(512)
//                .build();
//
//        ImageResponse response = imageModel.call(
//                new ImagePrompt("给spring ai框架生成一个涂鸦", options )
//        );String url =response.getResult().getOutput().getUrl();System.out.println(url);return url;}

5、生成向量

创建知识库时需要把文字转为向量存储到向量数据库中

    @AutowiredEmbeddingModel embeddingModel;@GetMapping("/testEmbed")public String test1() {float[] f = embeddingModel.embed("hello world");System.out.println(Arrays.toString(f));return Arrays.toString(f);}

浏览器显示如下

[-0.014903838, 0.0013317588, -0.018488139, -0.031072723, -0.024273094, 0.0075046294, -0.023034403, -0.0010262037, -0.012795426, -0.022441411, 0.025801694, 0.010884678, -0.033075716, -0.0037193708, 0.0058178995, 0.013849632, 0.01941057, -0.022863094, 0.01836954, 0.011326127, -0.0061605168, …

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com