当前位置: 首页 > news >正文

SpirngAI框架 Advisor API详解

SpringAI提供了Advisors API来实现请求和响应的拦截,修改,增强Spring应用程序和AI模型的互动。

可以使用ChatClient API来配置现有的advisor,例如:

var chatClient = ChatClient.builder(chatModel)

    .defaultAdvisors(

        new MessageChatMemoryAdvisor(chatMemory), // chat-memory advisor

        new QuestionAnswerAdvisor(vectorStore)    // RAG advisor

    )

    .build();

String response = this.chatClient.prompt()

    // Set advisor parameters at runtime

    .advisors(advisor -> advisor.param("chat_memory_conversation_id", "678")

            .param("chat_memory_response_size", 100))

    .user(userText)

    .call()

.content();

Advisor中的核心组件:

包括非流式场景中的CallAroundAdvisor和CallAroundAdvisorChain构成,其中CallAroundAdvisorChain是由一系列CallAroundAdvisor构成的链。非流式场景中的StreamAroundAdvisor和StreamAroundAdvisorChain构成。

还有AdvisorRequest用于表示没有密封的Prompt请求,AdvisorResponse表示聊天完成的响应,还有上下文AdviseContext,这个上下文用于保存

AdvisorRequest和AdvisorResponse在链中的共享状态。

callAroundNext()和streamAroundNext()是关键的方法,在这个方法中对请求和响应进行响应的操作,并且可以决定是否调用下一个advisor进行后续的操作。

getOrder()提供链中advisor的访问顺序,返回值越小的在链中的位置越靠前,还有getName()方法返回advisor的名称。最后一个advisor由SpringAI框架自动添加,并把请求发送到AI模型。

在链条中越靠前的advisor先执行对AdvisorRequest的操作,越后执行对AdvisorResponse的操作。注意:如果有多个advisor的getOrder()的返回值相同,可能无法保证顺序执行,因此要避免多个相同的order值。

SpringAI框架中的Advisor接口关系:

接下来自定义实现一个advisor:

上述实现了一个问题重读的advisor,就是让AI模型把问题读两遍。

SpringAI框架也提供了一些内置的advisor,比如:

1.MessageChatMemoryAdvisor:添加历史对话为消息列表,以.message(…)的形式插入到prompt,维护完整的对话结构,适用于完整对话上下文,高级模型(部分模型不支持该advisor)

2.PromptChatMemoryAdvisor:添加历史对话为系统提示,拼接成一个字符串插入到系统提示中。适用于简单记忆,对所有模型兼容。

3.VectorStoreChatMemoryAdvisor:从vectorStore中检索相关信息添加到系统提示中,通常用于提供背景信息。

4.QuestionAnswerAdvisor:用户提问时,自动从vectorStore中检索最相关的文档,添加到用户提示中,常用于RAG的精准回答。

SafeGardAdvisor:用于防止模型生成有害或不适信息

要更新 context,需要使用 .updateContext(...) 方法,它会创建一个新的不可变 map,并包含更新后的内容,例如:

@Override

public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {

    this.advisedRequest = advisedRequest.updateContext(context -> {

        context.put("aroundCallBefore" + getName(), "AROUND_CALL_BEFORE " + getName());

        context.put("lastBefore", getName());

        return context;

    });

    // 后续逻辑...

}

相关文章:

  • 在Python和C/C++之间共享std::vector<std::vector<int>>数据
  • 强化学习环境安装——openAI gym
  • DevExpressWinForms-AlertControl-使用教程
  • [Es_1] 介绍 | 特点 | 图算法 | Trie | FST
  • 屏幕炫光也能轻松应对,远程控制电脑可以避免裂痕碍眼
  • JumpServer批量添加资产
  • 时间序列数据集增强构造方案(时空网络建模)
  • python 使用 mongodb 的一些方法
  • 综述:语言模型的发展及大模型推理优化
  • 5. HTML 转义字符:在网页中正确显示特殊符号
  • MongoDB培训文档大纲(超详细)
  • 2025-05-07-FFmpeg视频裁剪(尺寸调整,画面比例不变)
  • PDF解析新范式:Free2AI工具实测
  • MySQL CTE (Common Table Expressions) 详解
  • 【前端基础】6、CSS的文本属性(text相关)
  • CSS详细学习笔记
  • FAST-LIO笔记
  • SPL量化 BBIC(多空指标)
  • 代码随想录第36天:动态规划9(序列问题)
  • 机器学习简单概述
  • 1156万+1170万,静安、宝山购彩者击中大乐透头奖
  • 著名文物鉴赏家吴荣光逝世,享年78岁
  • 汉斯·季默:不会指挥的声音工程师终成音乐“大神”
  • 高培勇:中国资本市场的发展应将预期因素全面纳入分析和监测体系
  • 瑞士联邦主席凯勒-祖特尔、联邦副主席帕姆兰会见何立峰
  • 重庆大学通报本科生发14篇SCI论文:涉事学生及其父亲被处理