3.2 构建AI智能体项目扩展知识

一、自定义advisor

目的:springAI官方框架提供的advisor不够用,自己得设计一个符合业务的advisor拦截器

实现步骤:

1.定义自定义拦截器时先实现两个必要接口

【CallAroundAdvisor:用于处理同步请求和响应(非流式)】

【StreamAroundAdvisor:用于处理流式请求和响应】

2.实现接口内的核心方法:aroundCall(普通调用)、 aroundStream(流式调用)

该核心方法的作用是:执行定义好的before和after方法,before执行完了然后放行请求chain调用AI大模型,然后执行after方法

3.定义before和after方法

定义好了再去核心方法内执行

4.设置getOrder他们在advisor链中的执行顺序

5.设置advisor的名称

整体结构(自定义日志输出拦截器为例子)

二、自定义的Re2拦截器(Re-Reading Advisor)

作用:就是让AI再读一次问题,这样有便于让AI深度思考用户问的问题

实现思路:和我们之前讲通用实现自定义advisor拦截器的思路都是一样的,这里我们专注于它定义的before方法的编写:

这个方法的本质

所以本质就是再请求发送给AI前修改一下请求,改为类似于"again:用户输入的问题"

三、结构化输出

目的:让"我们设计的AI程序"返回结果是我们想要的类型

本质:AI大模型 负责"写出符合格式的答案(输出时,输出我们想要类型的文本文字)",Spring AI 负责"把答案文本变成 Java 对象"。

结构化输出具体步骤

3.2.1恋爱报告功能开发

有了之前扩展知识--结构化输出的基础,下面我们对我们之前的AI应用进行功能扩展:让AI可以输出我们指定格式的报告

1.xml引入依赖

2.用record快速生成一个只装数据的类,该类定义了生成的报告的输出格式,待会使用entity,大模型和springAI会协作帮我们把输出的结果转换为这个类的形式输出

3.复用我们之前写好的和AI多轮对话的方法,在此基础上改一下提示词,把我们想要AI输出的格式拼接到我们的系统提示词上,然后用entity来把刚刚AI输出的内容转为我们要的LoveReport类型输出

四、对话记忆持久化

我们之前实现多轮和AI的对话,多轮对话是保存在JAVA内存中的,如果我们的服务器关闭,那么用户的历史对话记录也就全部消失了,因此我们的对话记忆需要持久化

持久化的方式一共两种:

数据库层面的JDBCchatmemory

文件层面的自定义chatmemory

自定义chatmemory

基于文件保存Java对象重点在于对象的序列化和反序列化,也就是对象怎么保存在文件中,你又是怎么从文件提取文本转化为Java对象 ,所以为了方便,我们基于文件实现就需要引入++Kryo 序列化库++

1.引入依赖

2.让AI帮我们编写有关代码"基于Kryo序列化库的持久化ChatMemory代码"

我们不需要关注代码是如何实现的,我们需要关注的是底层的原理

原理:

本质上就是把"对话记录"message对象转换为文件中的文本储存在硬盘,然后再能从储存到硬盘的文件中的文本转换回message对象,每一份对话文件都是唯一的,对应着唯一的对话ID,所以到时候想要去找之前的对话,有着唯一的对话ID就可以实现

3.修改之前LoveAPP的构造函数---运用我们新建的持久化对话保存形式

4.测试方法,可以看到对话记忆储存成了kroy文件

JDBC对话记忆持久化

本质上和我们上面写的"基于文件形式的对话记忆持久化"是一样的,只不过储存位置不是kroy文件,而是数据库

所以整体流程还是大致相同:

配置数据库

我们配置好数据库后,依旧更改我们的构造方法,让他把对话记忆储存到我们设计好的数据库中

五、PromptTemplate 模板

什么是 PromptTemplate?有什么用?

++PromptTemplate++ 是 Spring AI 框架中用于构建和管理提示词的核心组件。允许开发者创建带有占位符的文本模板,然后在运行时动态替换这些占位符。

总的来说**PromptTemplate这种方式让提示词用文件形式存储,然后对话的时候读取文件存储的提示词一并发给AI,**和我们之前普通和AI交互的区别就是,之前我们的交互方法提示词都是写方法代码中的,修改起来不方便,若提示词和方法一复杂,很不利于维护,因此可以用PromptTemplate这种方式

并且PromptTemplate还支持占位符,用户只需要输入对应的答案,不需要完整的把需求和提示词输入给AI,属于是我们先给了用户模板输入,用户按照我们的思路去思考问题并且给出答案了

比如:这个场景

用户输入的就是message和status,我们在编写前端网页让用户输入问题的时候就可以针对性,让用户标准的说出自己的问题

比如我们在前端设置多个输入框,各个输入框要求用户输入有关于"恋爱"的信息,这样就不用担心用户因为"想不到一些方面"而导致信息补全。

在我们测试方法的例子中,我们就可以说是为了解决用户恋爱问题,我们前端给用户两个输入框输入问题1.用户最近的恋爱问题(用于收集message)2.你最经的恋爱状态(用于收集status)

具体实现流程:

对应的每一步:

1.新建提示词st文件

并且在里面写好对应的提示词以及占位符:

2.把我们写好的提示词模板文件注入到我们的应用中:

3.编写依赖于PromptTemplate的和AI交互的方法

这里需要注意的是:user()方法和我们之前普通调用AI来交互的时候传入的参数不一样,我们之前是直接传入用户的请求message,这次我们传入的是renderedPrompt,这个是我们按照我们自己编写的提示词模板(也就是上文的st文件)所构造的对象

4.测试方法传入需要的用户参数来测试

相关推荐
Lakers-241 小时前
1987年6月10日晚上23-24点出生性格、运势和命运
java
易知微EasyV数据可视化1 小时前
工业制造如何实现柔性规划?数字孪生技术助力产线布局编排与方案推演
人工智能·经验分享·制造·数字孪生·可视化·三维建模
pla888888881 小时前
热词驱动,智辨声纹——从ASR热词到说话人日志的尝试:海光DCU环境部署FunASR热词语音识别系统(说话人日志已集成,含完整代码)
人工智能·语音识别
唐青枫1 小时前
Java Jetty 实战详解:从嵌入式 HTTP 服务到 Spring Boot 容器替换
java
编程牛马姐1 小时前
并发、多线程和HTTP连接之间有什么关系?
人工智能
羑悻的小杀马特2 小时前
把随身WiFi改成网盘聚合器:中兴F50挂载本地存储+夸克网盘实战
运维·服务器·人工智能·网盘·openlist
meilindehuzi_a2 小时前
从跑分到生产力:重新理解大模型基准测试与分层协作
人工智能
蜜桃味女焊匠人3 小时前
焊接生产线优化思路:解决手工焊、机器人焊气体浪费问题
人工智能·经验分享·其他·机器人
Georgeviewer8 小时前
商业落地评测|实体门店GEO优化性价比与服务体系深度复盘
大数据·人工智能