Spring AI Advisors API:AI交互的灵活增强利器

Spring AI Advisors API:AI交互的灵活增强利器

前言

在当今的软件开发领域,随着人工智能技术的飞速发展,将AI融入应用程序变得越来越普遍。Spring AI作为一个强大的框架,为开发者提供了便捷的方式来实现这一目标。其中的Advisors API更是一个亮点,它为拦截、修改和增强Spring应用程序中的AI驱动交互提供了灵活而强大的途径。无论是封装重复的生成式AI模式,还是转换与大型语言模型(LLM)交互的数据,Advisors API都能大显身手,助力开发者打造更复杂、可重用且可维护的AI组件。接下来,让我们深入探索Spring AI Advisors API的精彩世界。

一、核心组件与工作流程

在这里插入图片描述

(一)核心组件

  1. Advisor接口体系
    Spring AI Advisors API的核心接口是Advisor,它继承自Spring的Ordered接口,这意味着每个顾问都有一个顺序值,用于决定其在顾问链中的执行顺序。Advisor接口主要定义了获取顾问唯一名称的getName方法。在此基础上,有两个关键的子接口:
    • CallAroundAdvisor:用于非流式处理场景,其aroundCall方法围绕ChatModel#call(Prompt)方法进行增强。它接收AdvisedRequestCallAroundAdvisorChain作为参数,通过调用chain.nextAroundCall(advisedRequest)方法继续顾问链的执行,并返回AdvisedResponse
    • StreamAroundAdvisor:针对流式处理场景,aroundStream方法负责处理流式的请求和响应。它接收AdvisedRequestStreamAroundAdvisorChain,通过chain.nextAroundStream(advisedRequest)推进顾问链,返回Flux<AdvisedResponse>
  2. 请求与响应相关类
    • AdvisedRequest:表示未封装的Prompt请求,它包含了用户的输入以及其他相关参数,并且持有一个advise - context,用于在顾问链中共享状态。
    • AdvisedResponse:用于获取Chat Completion响应,同样也包含advise - context,方便各个顾问在处理响应时共享和修改相关状态。
    • CallAroundAdvisorChainStreamAroundAdvisorChain:这两个接口在顾问实现中用于继续顾问链的执行。CallAroundAdvisorChainnextAroundCall方法用于非流式处理,而StreamAroundAdvisorChainnextAroundStream方法用于流式处理。

(二)工作流程

Spring AI框架首先根据用户的Prompt创建一个AdvisedRequest对象,同时生成一个空的AdvisorContext对象。然后,顾问链中的每个顾问依次处理这个请求。顾问可以选择修改请求,也可以通过不调用链中的下一个实体来阻止请求的继续传递。如果顾问阻止了请求,那么它需要自行填写回复。当请求到达框架提供的最后一个顾问时,该顾问会将请求发送到Chat Model。Chat Model生成的响应会通过顾问链反向传回,并被转换为AdvisedResponse。在这个过程中,每个顾问都有机会处理或修改响应,最终提取出ChatCompletion
在这里插入图片描述

二、实施Advisor

(一)日志记录顾问

我们来看一个简单的日志记录顾问的实现。这个顾问的作用是在调用链中的下一个顾问之前记录AdvisedRequest,在之后记录AdvisedResponse,且不修改请求和响应。

public class SimpleLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
    private static final Logger logger = LoggerFactory.getLogger(SimpleLoggerAdvisor.class);

    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {
        logger.debug("BEFORE: {}", advisedRequest);
        AdvisedResponse advisedResponse = chain.nextAroundCall(advisedRequest);
        logger.debug("AFTER: {}", advisedResponse);
        return advisedResponse;
    }

    @Override
    public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
        logger.debug("BEFORE: {}", advisedRequest);
        Flux<AdvisedResponse> advisedResponses = chain.nextAroundStream(advisedRequest);
        return new MessageAggregator().aggregateAdvisedResponse(advisedResponses,
                advisedResponse -> logger.debug("AFTER: {}", advisedResponse));
    }
}

在这个实现中,通过getName方法为顾问提供了唯一名称,通过getOrder方法设置了执行顺序(这里设置为0,表示较高优先级)。在aroundCallaroundStream方法中,分别实现了对非流式和流式请求及响应的日志记录。

(二)重读(Re2)顾问

另一个示例是应用Re - Reading(Re2)技术的顾问。该技术可以提高大型语言模型的推理能力,通过扩充输入提示来实现。

public class ReReadingAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
    private AdvisedRequest before(AdvisedRequest advisedRequest) {
        Map<String, Object> advisedUserParams = new HashMap<>(advisedRequest.userParams());
        advisedUserParams.put("re2_input_query", advisedRequest.userText());
        return AdvisedRequest.from(advisedRequest)
               .userText("""
                    {re2_input_query}
                    Read the question again: {re2_input_query}
                    """)
               .userParams(advisedUserParams)
               .build();
    }

    @Override
    public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {
        return chain.nextAroundCall(this.before(advisedRequest));
    }

    @Override
    public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
        return chain.nextAroundStream(this.before(advisedRequest));
    }

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }
}

before方法负责扩充用户的输入查询,应用Re - Reading技术。aroundCallaroundStream方法分别拦截非流式和流式请求,并应用该技术。同样,通过getNamegetOrder方法设置顾问名称和执行顺序。

三、Spring AI内置顾问程序

(一)聊天记忆顾问

  1. MessageChatMemoryAdvisor:从聊天内存存储中检索内存,并将其作为消息集合添加到提示符中,这种方式能维护会话历史记录的结构,但并非所有AI模型都支持。
  2. PromptChatMemoryAdvisor:将检索到的内存合并到提示的系统文本中。
  3. VectorStoreChatMemoryAdvisor:从VectorStore中检索内存,并添加到提示符的系统文本中,可用于从大型数据集中高效搜索和检索相关信息。

(二)问题解答顾问

QuestionAnswerAdvisor:使用向量存储来提供问答功能,实现RAG(检索增强生成)模式,能有效提升问答场景下的AI交互效果。

(三)内容安全顾问

SafeGuardAdvisor:用于防止模型生成有害或不适当的内容,保障AI交互的安全性和合规性。

四、流式处理与非流式处理

非流式处理顾问处理完整的请求和响应,而流式处理顾问则使用反应式编程概念(如Flux)将请求和响应作为连续流处理。例如,在流式处理的aroundStream方法实现中,可以通过MonoFlux的操作来对请求和响应流进行处理。

@Override
public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
    return Mono.just(advisedRequest)
           .publishOn(Schedulers.boundedElastic())
           .map(request -> {
                // This can be executed by blocking and non - blocking Threads.
                // Advisor before next section
            })
           .flatMapMany(request -> chain.nextAroundStream(request))
           .map(response -> {
                // Advisor after next section
            });
}

在这里插入图片描述

五、最佳实践与注意事项

  1. 专注特定任务:让每个顾问专注于特定的任务,这样可以实现更好的模块化,提高代码的可维护性和可扩展性。
  2. 共享状态:合理使用adviseContext在顾问之间共享状态,确保各个顾问之间能够协同工作,实现复杂的AI交互逻辑。
  3. 实现流式与非流式版本:为了实现最大的灵活性,尽量实施顾问的流式处理和非流式处理版本,以适应不同的应用场景。
  4. 考虑执行顺序:仔细考虑顾问在供应链中的顺序,根据业务需求确保数据能够正常流动,避免因顺序不当导致的错误或性能问题。

六、向后兼容性与重大API更改

(一)向后兼容性

AdvisedRequest类被移动到了新的package中,在进行代码升级时需要注意相关的包路径更改。

(二)重大API更改

从1.0 M2版本到1.0 M3版本,Spring AI Advisor链发生了重大变化。在1.0 M2中,有单独的RequestAdvisorResponseAdvisor接口,分别在ChatModel.callChatModel.stream方法前后调用。而在1.0 M3中,这些接口被替换为CallAroundAdvisorStreamAroundAdvisor,并且StreamResponseMode(以前是ResponseAdvisor的一部分)已被删除。此外,上下文映射的处理方式也发生了改变,从1.0 M2中的可变、单独方法参数传递,变为1.0 M3中的AdvisedRequestAdvisedResponse记录中的不可变映射,并且需要使用updateContext方法来更新上下文。

总结

Spring AI Advisors API为开发者在Spring应用程序中实现灵活、强大的AI驱动交互提供了丰富的工具和机制。通过自定义顾问以及利用内置顾问程序,我们能够轻松地封装复杂的AI逻辑、转换数据并实现各种实用功能。在使用过程中,遵循最佳实践,注意向后兼容性和API的变化,能够帮助我们更好地利用这一强大的API。无论是构建智能聊天应用,还是为其他业务场景添加AI支持,Spring AI Advisors API都能成为我们开发过程中的得力助手,助力我们打造出更具创新性和竞争力的应用程序。希望本文能帮助大家对Spring AI Advisors API有更深入的理解和应用,在AI开发的道路上更进一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-曾牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值