首页 > 其他分享 >Spring AI 1.0.0 M1版本新特性!

Spring AI 1.0.0 M1版本新特性!

时间:2024-10-22 11:47:07浏览次数:7  
标签:1.0 请求 AI Spring 模型 ChatClient MessageChatMemoryAdvisor

Spring AI 1.0.0 M1版本新特性介绍


前言

Spring AI 1.0.0-M1这个版本相对前一个版本增加了很多新特性,比如多模态的支持、模型结果评估机制、Fluent API等等,但其中我觉得最有意思的是引入了Spring AOP中的Advisor机制。

众所周知,Advisor是Spring AOP中的概念,一个Advisor表示一个切面,由Advice和PointCut组成,Advice表示切面逻辑,也就是增强逻辑,PointCut表示切点,也就是切哪些方法。

一、在1.0.0 M1版本中,主要有以下新特性:

1.ChatModel

以前的ChatClient变为了ChatModel,ChatModel表示某个模型,具体看配置使用了哪个模型,比如实现类OpenAiChatModel表示OpenAi旗下的大模型,比如gpt-4o

2.ChatClient

但ChatClient并没有废弃,而是变成了封装在ChatModel之上的客户端,相当于ChatClient底层使用的是ChatModel,ChatClient支持fluent API,ChatModel则不支持,比如:

@GetMapping("/clientChat")
public String clientChat() {
    return this.chatClient.prompt()
    .user("你是谁")
    .call()
    .content();
}

不过,我们需要自己定义ChatClient的Bean:

@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
    return builder
    .build();
}

3.多模态的支持

通过Spring AI可以让大模型来理解图片内容

@GetMapping("/multimodalChat")
public String multimodalChat() {
    ClassPathResource imageData = new ClassPathResource("/test.jpg");

    var userMessage = new UserMessage("图片里有什么?",
        List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));

    return chatModel.call(userMessage);
}

4.模型评估

对于模型生成的结果,让可以让模型针对问题和答案评估是否相关:

@GetMapping("/evaluation")
public EvaluationResponse evaluation() {
    String userText = "apikey是什么";

    ChatResponse response = ChatClient.builder(chatModel)
    .build().prompt()
    .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
    .user(userText)
    .call()
    .chatResponse();

    // 评估器
    var relevancyEvaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));

    // 评估请求
    EvaluationRequest evaluationRequest = new EvaluationRequest(userText,
        (List<Content>) response.getMetadata().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS), response);

    // 评估结果
    EvaluationResponse evaluationResponse = relevancyEvaluator.evaluate(evaluationRequest);

    return evaluationResponse;
}

评估结果为:

{
    "pass": true,
    "score": 1.0,
    "feedback": "",
    "metadata": {}
}

RequestResponseAdvisor接口

在这里插入图片描述
很明显,这个接口表示对请求和响应进行增强,传入一个请求或响应,返回增强后的请求或响应,有点类似于Spring MVC中的拦截器,联系到Spring AI的核心功能就是 请求大模型接口
以及 处理大模型响应结果 ,所以RequestResponseAdvisor接口的作用就是增强对于大模型的请求和响应,但具体增强逻辑是什么由具体的实现类来定义。

在这里插入图片描述

MessageChatMemoryAdvisor

广义的意思:
是一种Advisor,也是用来增强问答请求和响应的,而其中另外一个概念就是ChatMemory,默认实现为InMemoryChatMemory,它可以用来按conversationId进行历史对话记录的存储。

因此MessageChatMemoryAdvisor的作用就是将原始请求和向量添加到ChatMemory中。

源码讲解:
第一个实现类:MessageChatMemoryAdvisor ,类名中的 ChatMemory 也是Spring AI中的一个机制,也是1.0.0版本新增的一个特性,来源于LangChain4j,作用是用来保存与大模型的,聊天上下文,或者说聊天记录,或者说会话记录,或者说问答记录,都是一个意思,ChatMemory
是一个接口,默认实现类为InMemoryChatMemory ,表示聊天记录都存储在内存中(InMemory),当然你可以自定义一个实现类把聊天记录存在数据库中,InMemoryChatMemory,的实现其实很简单:

在这里插入图片描述
理解为就是一个Map,key为会话ID,value为会话对应的历史消息列表,注意这里的消息既包含了我们发送给大模型的UserMessage(比如“你是谁?”),也包含了大模型返回给我们的AssistantMessage(比如“我是gpt-4o…”),都是Message。

回到 MessageChatMemoryAdvisor ,它增强的是某一次请求和对应的响应,它的第一个作用就是把当前请求所发送的UserMessage添加到ChatMemory中,重点是第二个作用,由于大模型本身是无状态的,也就是大模型本身并不会保存我们和大模型之间的聊天记录,所以,我们如果想让大模型知道我们之前聊了什么,我们就需要在请求大模型时将历史聊天记录跟着当前请求一起发送给大模型,这样大模型才能知道前面聊了什么,而具体实现方式就是发送一个List给大模型,这个List中既包含了历史消息,也包含了最新消息,这样大模型就能知道前面聊天的内容了。

所以,当Spring AI接收到一个请求时,这个请求一开始只会携带一条UserMessage,比如“请换一个风格”,之后 MessageChatMemoryAdvisor 会将该请求对应的UserMessage添加到ChatMemory中,也就是Map中当前会话ID对应的List中,然后生成一个新的请求,将List设置到新请求中,因此这个新的请求中就不止一条UserMessage了,而是一个List,然后Spring AI会将这个新的请求发送给大模型,此时大模型也就知道了历史聊天记录,就能知道“请换一个风格”到底是什么意思了。

在这里插入图片描述
当大模型处理完请求后,会向Spring AI返回一个响应,在Spring AI中就是一条AssistantMessage,那么MessageChatMemoryAdvisor 需要对响应做什么增强逻辑呢?很简单,只需要将AssistantMessage添加到ChatMemory即可。

在这里插入图片描述

PromptChatMemoryAdvisor

也是用来记录历史对话记录的,和MessageChatMemoryAdvisor的不同点在于,MessageChatMemoryAdvisor是把每个历史请求和响应封装为Message增强到请求中,而PromptChatMemoryAdvisor是把所有请求和响应也会存到ChatMemory中,但是会把所有内容合并一条Message增强到请求中。

PromptChatMemoryAdvisor ,其实它的作用和MessageChatMemoryAdvisor类似,也会利用ChatMemory来保存聊天记录,它和MessageChatMemoryAdvisor的区别在于,最终发送给大模型的请求中不是一个List了,而是会额外设置了一个系统提示词SystemMessage
,内容为:

Use the conversation memory from the MEMORY section to provide accurate answers
----------------------------
MEMORY:
{memory}
----------------------------

{memory}相当于一个变量,发送给大模型之前会进行占位符的填充,那填充的是啥呢?没错啦,就是历史聊天记录,源码中会把List用

System.lineSeparator()

进行连接,相当于把历史聊天记录转为一个字符串,然后放到系统提示词中随着请求一起发送给大模型,这样大模型也能知道之前聊天的内容,从而准确的理解当前问题,和MessageChatMemoryAdvisor一样,PromptChatMemoryAdvisor也会将大模型的响应AssistantMessage保存到ChatMemory中。

看到这,是否Get到了Advisor在Spring AI中的作用了呢,看到源码时还是觉得挺惊艳的,Spring还是那么的优雅,切面机制永远这么强大。

不过需要注意的是,以上MessageChatMemoryAdvisor和PromptChatMemoryAdvisor虽然都叫做Advisor,但是它们都不是通过动态代理来实现的,而是这么实现的:
在这里插入图片描述
针对原始的请求和响应,依次利用RequestResponseAdvisor进行增强,有没有感觉和BeanPostProcessor的实现机制很像呢。

QuestionAnswerAdvisor

广义: Advisor是Spring AOP中的概率,这里也应用在了Spring
AI中,QuestionAnswerAdvisor的作用是对问题请求进行增强,增强逻辑为:

  1. 根据原始问题进行相似度搜索,得到匹配知识点
  2. 拼接RAG提示词模板

后续Spring
AI会根据增强后的请求进行提示词模版的变量填充,得到请求最终的提示词,并将请求发送给大模型,得到大模型的返回结果,QuestionAnswerAdvisor也会对返回结果进行增强,会把匹配的知识点放入ChatResponse的metadata中。

向量数据库存储的是 AI 模型不知道的数据,当用户问题被发送到 AI 模型时,QuestionAnswerAdvisor 会在向量数据库中查询与用户问题相关的文档。

来自向量数据库的响应被附加到用户消息 Prompt 中,为 AI 模型生成响应提供上下文。

假设您已将数据加载到中 VectorStore,则可以通过向 ChatClient 提供 QuestionAnswerAdvisor 实例来执行检索增强生成 (RAG ) 。

    ChatResponse response = ChatClient.builder(chatModel)
            .build().prompt()
            .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
            .user(userText)
            .call()
            .chatResponse();

在此示例中,SearchRequest.defaults() 将对 Vector 向量数据库中的所有文档执行相似性搜索。为了限制要搜索的文档类型,SearchRequest 采用了可移植到任意向量数据库中的类似 SQL 筛选表达式。

动态过滤表达式

SearchRequest 使用 FILTER_EXPRESSION Advisor 上下文参数在运行时更新过滤表达式:

    ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
        .build();

    // Update filter expression at runtime
    String content = chatClient.prompt()
        .user("Please answer my question qjc")
        .advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Spring'"))
        .call()
        .content();

该 FILTER_EXPRESSION 参数允许您根据提供的表达式动态过滤搜索结果。

VectorStoreChatMemoryAdvisor

这个就更加强大了,它既会进行RAG,也会把存储历史对话,只不过会把对话记录封装为Document存到向量数据库中。

VectorStoreChatMemoryAdvisor :构造函数VectorStoreChatMemoryAdvisor(VectorStore vectorStore, String defaultConversationId, int chatHistoryWindowSize)允许您指定要从中检索聊天历史记录的 VectorStore、唯一的对话 ID、要检索的聊天历史记录的大小(以令牌大小为单位)。

这个没有具体分析一下,我先提供一个案例:回头展开细说这个模块,因为我看到官方M2 M3也出来了,慢慢研究

 @Service
public class SupportAssistant {

        private final ChatClient chatClient;

        public SupportAssistant(ChatClient.Builder builder, VectorStore vectorStore, ChatMemory chatMemory) {

        this.chatClient = builder
                .defaultSystem("""
                    xxxxx
                        """)
                .defaultAdvisors(
                        new PromptChatMemoryAdvisor(chatMemory),
                        // new MessageChatMemoryAdvisor(chatMemory), // CHAT MEMORY
                        new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()),
                        new LoggingAdvisor()) // RAG
                .build();
    }

    public Flux<String> chat(String chatId, String userMessageContent) {

        return this.chatClient.prompt()
                .user(userMessageContent)
                .advisors(a -> a
                        .param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
                .stream().content();
        }
    }

总结

这是个里程碑版本,后续M2 M3都已经出来了,目前文档看不到。

标签:1.0,请求,AI,Spring,模型,ChatClient,MessageChatMemoryAdvisor
From: https://blog.csdn.net/qq_42731358/article/details/143111866

相关文章

  • 高效工作的必备工具库——ToolFul.AI 精选推荐
    摘要:面对纷繁复杂的AI工具,如何快速找到最适合的工具来提高工作效率?ToolFul.AI是一个智能推荐平台,汇集了丰富的AI工具库,帮助用户在各类任务中轻松找到高效解决方案。从文本转语音到图片生成,ToolFul.AI提供的工具应有尽有,成为每位职场人士和创意工作者的好帮手。在信息化时代......
  • 《DNK210使用指南 -CanMV版 V1.0》第三十二章 音频FFT实验
    第三十二章音频FFT实验1)实验平台:正点原子DNK210开发板2)章节摘自【正点原子】DNK210使用指南-CanMV版V1.03)购买链接:https://detail.tmall.com/item.htm?&id=7828013987504)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html5)正点原......
  • JAVA开源项目 基于Vue和SpringBoot母婴商城系统
    本文项目编号T030,文末自助获取源码\color{red}{T030,文末自助获取源码}......
  • Springboot计算机毕业设计程序设计竞赛团队管理系统72262
    Springboot计算机毕业设计程本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:团队信息,用户,团队风采,团队成员,团队项目,项目反馈,团队任务开题报告内容一、研究背景与意义随着信息技术的飞速发展......
  • Springboot计算机毕业设计城市轨道交通线路查询p2df3
    Springboot计算机毕业设计城本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,站点信息,交通线路,周边类型,周边信息开题报告内容一、研究背景随着城市化进程的加速,城市轨道交通系统作为城市交......
  • Springboot计算机毕业设计超时代停车场管理平台s91w4
    Springboot计算机毕业设计超时代停车场管理平台s91w4本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:车主,停车场,车位预留,入场信息,停车记录,财务信息开题报告内容一、项目背景与意义随着城市化......
  • spring整合整合Druid数据源连接池
    1.普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接......
  • 1亿播放量!AI风景治愈视频杀疯了,网友调侃:生活不易,需要治愈
    打工人,打工魂,“牛马”们需要一个AI风景治愈视频来提神!上班背负着老板的KPI,下班背负着人生的KPI,在这个快节奏、高压力的"内卷"时代,每个人心灵都像是被生活浪潮不断拍打的孤帆,日日悬命。而释放高压的最好方式就是看AI风景治愈视频,这些视频以超乎想象的创意、温暖人心的......
  • Spring Boot 依赖注入为 null 问题
    目录问题省流代码复现TestServiceTestAspectTestController源码分析AbstractAutoProxyCreatorCglibAopProxyEnhancer问题工作中,在负责的模块里使用@DubboService注解注册了一个dubbo接口,给定时任务模块去调用。在自我调试阶段,需要在本地自己验证一下接口的功......
  • 猫鼠游戏: KaijiK病毒入侵溯源分析
    1.事件背景近期,网宿平台某客户在使用云主机工作的时候突然出现主机卡顿,连接不稳定,网络断开的情况,并且收到了网宿主机入侵检测产品的告警信息。由于客户没有专职的安全人员,由运维人员兼任安全运营工作,于是网宿安全专家协助对事件进行排查、溯源、处理。2.入侵过程溯源分析......