【Java SpringAI智能体开发学习 | 2】SpringAI 实用特性:自定义Advisor,结构化输出,对话记忆持久化,prompt模板,多模态

自定义Advisor

Spring官方提供了MessageChatMemoryAdvisor()和QuestionAnswerAdvisor()分别用来对话记忆和增强检索,但有可能不完全符合我们具体业务的需求。因此需要自定义Advisor来帮助我们更好地完成业务。

实现步骤:

  1. 选择合适的接口实现:CallAroundAdvisor:处理同步请求和响应

或StreamAroundAdvisor:处理流式请求和响应

(建议一起实现)

  1. 实现

  2. 设置执行顺序,实现getOrder()

  3. 提供唯一标识符,实现getName()

示例:

Spring提供的日志输出Advisor是debug级别的,我们要想实现info级别的就要自定义日志输出Advisor

java 复制代码
@Slf4j
public class MyLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {

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

    public int getOrder() {
        return 0;
    }

    private AdvisedRequest before(AdvisedRequest request) {
        log.info("request: {}", request.userText());
        return request;
    }

    private void observeAfter(AdvisedResponse advisedResponse) {
        log.info("response: {}", advisedResponse.response().getResult().getOutput().getText());
    }

    public String toString() {
        return MyLoggerAdvisor.class.getSimpleName();
    }

    public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {
        advisedRequest = this.before(advisedRequest);
        AdvisedResponse advisedResponse = chain.nextAroundCall(advisedRequest);
        this.observeAfter(advisedResponse);
        return advisedResponse;
    }

    public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
        advisedRequest = this.before(advisedRequest);
        Flux<AdvisedResponse> advisedResponses = chain.nextAroundStream(advisedRequest);
        return (new MessageAggregator()).aggregateAdvisedResponse(advisedResponses, this::observeAfter);
    }
}

结构化输出

SpringAI 通过结构化输出转换器(Structured Output Converter)来将返回的文本输出转换为结构化数据格式,如JSON,Bean等

调用前在prompt后添加提示词,明确告诉模型使用哪种格式

响应后将文本转换为实例

SpringAI 提供了多种转换器实现,如MapOutputConverter,BeanOutputConverter和ListOutputConverter

实现:

java 复制代码
record LoveReport(String title, List<String> suggestions) {

    }
    public LoveReport doChatWithReport(String message, String chatId) {
        LoveReport loveReport = client
                .prompt()
                .system(SYSTEM_PROMPT + "要求的格式,上文定义的record的{title}和{建议List}")//在prompt加后缀,要求生成的结构
                .user(message)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .call()
                .entity(LoveReport.class);//生成特定的结构
        log.info("loveReport: {}", loveReport);
        return loveReport;
    }

对话记忆持久化

一般都是基于内存来保存对话记忆上下文,当重启后记忆就会消失。所以让对话记忆持久化是我们需要去实现的。

自定义实现ChatMemory

基于内存实现的ChatMemory存储的都是Message对象,所以要想实现自定义ChatMemory就要做到写消息时Message对象转换为文本,读消息时将文本转换为对象。即序列化和反序列化。

Prompt模板

PromptTemplate支持动态生成prompt

java 复制代码
// 定义订单信息模板
String orderTemplate = "订单编号:{orderId},客户:{customer},商品:{product},数量:{quantity},总价:{totalPrice}元。";

// 创建模板对象
PromptTemplate orderPromptTemplate = new PromptTemplate(orderTemplate);

// 准备订单相关变量
Map<String, Object> orderVariables = new HashMap<>();
orderVariables.put("orderId", "ORD20230908001");
orderVariables.put("customer", "张三");
orderVariables.put("product", "无线耳机");
orderVariables.put("quantity", 2);
orderVariables.put("totalPrice", 998);

// 生成订单信息文本
String orderInfo = orderPromptTemplate.render(orderVariables);
// 结果: "订单编号:ORD20230908001,客户:张三,商品:无线耳机,数量:2,总价:998元。"

SpringAI 提供了几种专用的模板类:

SystemPromptTemplate:设置AI的行为和背景

AssistantPromptTemplate:设置AI回复的结构

从文件中加载模板

java 复制代码
// 从类路径资源加载系统提示模板
@Value("classpath:/prompts/system-message.st")
private Resource systemResource;

// 直接使用资源创建模板
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);

低侵入修改代码提示词

为不同场景提供不同提示词

多模态

多模态是同时处理多种不同数据类型的能力,比如文本,音频,图像等

相关推荐
青云交2 小时前
Java 大视界 -- 基于 Java 的大数据机器学习模型在图像识别中的迁移学习与模型优化
java·大数据·迁移学习·图像识别·模型优化·deeplearning4j·机器学习模型
2501_909800812 小时前
Java 集合框架之 Set 接口
java·set接口
断剑zou天涯2 小时前
【算法笔记】暴力递归尝试
java·笔记·算法
Nobody_Cares3 小时前
JWT令牌
java
沐浴露z3 小时前
Kafka入门:基础架构讲解,安装与使用
java·分布式·kafka
神秘的土鸡3 小时前
从数据仓库到数据中台再到数据飞轮:我的数据技术成长之路
java·服务器·aigc·数据库架构·1024程序员节
vir023 小时前
P1928 外星密码(dfs)
java·数据结构·算法·深度优先·1024程序员节
摇滚侠4 小时前
全面掌握PostgreSQL关系型数据库,备份和恢复,笔记46和笔记47
java·数据库·笔记·postgresql·1024程序员节
eguid_15 小时前
【开源项目分享】JNSM1.2.0,支持批量管理的jar包安装成Windows服务可视化工具,基于Java实现的支持批量管理已经安装服务的可视化工具
java·开源·jar·1024程序员节·windows服务·jar包安装成服务·exe安装成服务
杯莫停丶5 小时前
设计模式之:享元模式
java·设计模式·享元模式