电子商务网站建设期末试卷答案,订做网站,微信个人商城网站模板免费下载,打不开网页是怎么回事学习SpringAI的记录情况 文章目录 前言
因公司需要故而学习SpringAI文档#xff0c;故将自己所见所想写成文章#xff0c;供大佬们参考
主要是为什么这么写呢#xff0c;为何不抽出来呢#xff0c;还是希望可以用的时候更加方便一点#xff0c;如果大家有需求可以自行去… 学习SpringAI的记录情况 文章目录 前言
因公司需要故而学习SpringAI文档故将自己所见所想写成文章供大佬们参考
主要是为什么这么写呢为何不抽出来呢还是希望可以用的时候更加方便一点如果大家有需求可以自行去优化。
SrpingAI入门
这里我用到的是智普AI大家可以根据自己喜欢用的AI自由进行切换 至于API-KEY可自行去智谱AI开放平台可自行去找这里新用户注册目前是还送2000万TOKEN的
引包 !--智普AI--dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-zhipuai-spring-boot-starter/artifactId/dependency 配置文件 至于API-KEY可自行去智谱AI开放平台可自行去找这里新用户注册目前是还送2000万TOKEN的
配置类
获取API-KEY
Component
public class ChatConfig {//获取配置文件中的API-KEYValue(${spring.ai.zhipuai.api-key})private String apiKey;public String getApiKey() {return apiKey;}
}测试用例代码 //为啥用这个模型呢因为免费private static final String default_model GLM-4-Flash;//temperature 是一个超参数用于控制生成文本的多样性和随机性。//低温度例如0.1 到 0.3模型会生成更确定、常规和一致的输出。低温度通常会使模型产生更 加保守的回答重复性较高生成的内容更加准确、接近训练数据中的常见模式。//高温度例如0.7 到 1.0模型的输出会更加随机、多样、创意性强。高温度会导致生成的内容 更加多样化可能包括一些不太常见或创新性的回答但也可能带来不太准确或不太连贯的结果。private static final double default_temperature 0.7; GetMapping(/AIchat)public BaseResponseString AIGeneration(RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ZhiPuAiChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModelChatClient build ChatClient.builder(chatModel).build();String substring ;String content null;try {// 调用build.prompt()方法传入用户消息调用call()方法获取返回内容content build.prompt().user(message).call().content();} catch (Exception e) {// 获取异常信息String errorMessage e.getMessage();// 获取异常信息中冒号后面的内容int i errorMessage.lastIndexOf(:);String newString errorMessage.substring(i 2);// 去掉异常信息中的最后一个字符substring newString.substring(0, newString.length() - 3);}// 如果异常信息不为空抛出BusinessException异常if(!substring.isEmpty()){throw new BusinessException(ErrorCode.PARAMS_ERROR,substring);}// 返回成功结果return ResultUtils.success(content);} 测试AI返回结果 全参数响应结果
这里是对token的消耗做了一个统计查看用户的所剩token情况的一个返回结果展示
其实也就只是把String类型的返回结果转成了ChatResponse类型仅此而已
测试用例代码 GetMapping(/AIchat)public BaseResponseChatResponse AIGeneration(RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ZhiPuAiChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModelChatClient build ChatClient.builder(chatModel).build();String substring ;ChatResponse chatResponse null;try {chatResponse build.prompt().user(message).call().chatResponse();} catch (Exception e) {// 获取异常信息String errorMessage e.getMessage();// 获取异常信息中冒号后面的内容int i errorMessage.lastIndexOf(:);String newString errorMessage.substring(i 2);// 去掉异常信息中的最后一个字符substring newString.substring(0, newString.length() - 3);}// 如果异常信息不为空抛出BusinessException异常if(!substring.isEmpty()){throw new BusinessException(ErrorCode.PARAMS_ERROR,substring);}// 返回成功结果return ResultUtils.success(chatResponse);}
返回结果 前端传递不同的模型测试方法
测试用例代码 GetMapping(/chat)public BaseResponseString generation(RequestParam(value message, defaultValue 你是谁呢) String message,RequestParam(value model, defaultValue GLM-4-Flash) String model,RequestParam(value temperature, defaultValue 0.7) double temperature) {// 创建新的 ZhiPuAiChatOptions 实例根据请求的参数动态设置ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(model).withTemperature(temperature).build();// 获取 ChatModel 实例使用新的配置ChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);ChatClient build ChatClient.builder(chatModel).build();String substring ;// 使用新的 ChatModel 进行对话生成String content null;try {content build.prompt().user(message).call().content();} catch (Exception e) {// 获取错误消息String errorMessage e.getMessage();int i errorMessage.lastIndexOf(:);String newString errorMessage.substring(i 2);substring newString.substring(0, newString.length() - 3);}if(!substring.isEmpty()){throw new BusinessException(ErrorCode.PARAMS_ERROR,substring);}return ResultUtils.success(content);} 其实跟上面的代码差不多只不过是从前端传递过来一个模型当然这里我并没有对于上传上来的模型做校验如果感兴趣的话可自行查看并解决 测试结果 这里可以看到我们的异常返回起到效果了原谅我是一个穷鬼不想花钱在测试这个上面 测试到这里相信你已经知道了点什么就是如果你问的问题较长的话实际使用GET传输是有问题的因为默认GET请求的长度是有限制的建议自行换成POST请求然后再继续往下
流式响应
测试用例代码
GetMapping(value /AIStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIStream(RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ZhiPuAiChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModelChatClient chatClient ChatClient.builder(chatModel).build();FluxString content chatClient.prompt().user(message).stream().content();// 返回成功结果return content;}
响应结果
这里使用的是SSESSE是一种服务端向客户端推送的一种技术需要的可自行去浏览这个技术 流式响应全参数
测试用例代码
// 使用GetMapping注解指定请求路径为/AIChatResponseStream返回类型为TEXT_EVENT_STREAM_VALUEGetMapping(value /AIChatResponseStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)// 定义一个方法返回类型为FluxChatResponse参数为String类型的message默认值为你是谁呢public FluxChatResponse AIChatResponseStream(RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModelChatClient chatClient ChatClient.builder(chatModel).build();// 调用chatClient的prompt方法传入message返回一个FluxChatResponse对象FluxChatResponse chatResponseFlux chatClient.prompt().user(message).stream().chatResponse();// 返回FluxChatResponse对象return chatResponseFlux;}
响应结果 至于这里如何查看内容流式响应全参数输出完毕有一个STOP的停止参数可以使用
位置贴到下面 //全参数流失响应地址接口停止标志--------------当然这里如果你要配合前端可以通过这个STOP来观察结果是否输出完毕可以通过这个标志来停掉SSE连接
parsedData.results[0].metadata.finishReason STOP 默认角色回复实现
测试用例代码
// 使用GetMapping注解指定请求路径为/AIChatDefaultStream返回类型为文本流GetMapping(value /AIChatDefaultStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIChatDefaultStream(// 使用RequestParam注解指定请求参数名为message默认值为你是谁呢RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ChatModel对象使用ZhiPuAiChatModel和ZhiPuAiApiChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象设置默认系统ChatClient chatClient ChatClient.builder(chatModel).defaultSystem(你现在的身份是一个星轨会议系统的客服助手请以友好、乐于助人且愉快的方式来回复。).build();// 调用chatClient的prompt方法设置用户消息并返回内容流FluxString content chatClient.prompt().user(message).stream().content();// 返回内容流return content;} 响应结果 这里就可以看到响应结果他已经换成了星轨会议系统的客服助手如果你希望做某一个角色的内容你可以通过预训练这个参数使得这个AI客服助手的回复更加友好。
AI知晓日期
测试用例代码
// 使用GetMapping注解指定请求路径为/AIChatDefaultStream返回类型为文本流GetMapping(value /AIChatDefaultStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIChatDefaultStream(// 使用RequestParam注解指定请求参数名为message默认值为你是谁呢RequestParam(value message, defaultValue 你是谁呢) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ChatModel对象使用ZhiPuAiChatModel和ZhiPuAiApiChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象设置默认系统ChatClient chatClient ChatClient.builder(chatModel).defaultSystem(你现在的身份是一个星轨会议系统的客服助手请以友好、乐于助人且愉快的方式来回复。我希望你可以以中文的方式给我回答。今天的日期是 {current_date}.).build();// 调用chatClient的prompt方法设置用户消息并返回内容流FluxString content chatClient.prompt().user(message).system(s-s.param(current_date, LocalDate.now().toString())).stream().content();// 返回内容流return content;}
响应结果 这样的话AI就知道当前的日期 记忆对话
测试用例代码
创建一个配置类引入ChatMemory
Configuration
public class ZhiPuChatMemoryConfig {BeanQualifier(customMemory)public ChatMemory chatMemory() {return new InMemoryChatMemory();}} 引入ChatMemory
// 使用GetMapping注解指定请求路径为/AIChatDefaultStream返回类型为文本流GetMapping(value /AIChatDefaultStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIChatDefaultStream(// 使用RequestParam注解指定请求参数名为message类型为StringRequestParam(value message) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModel设置默认系统消息和默认顾问ChatClient chatClient ChatClient.builder(chatModel).defaultSystem(你现在的身份是一个星轨会议系统的客服助手请以友好、乐于助人且愉快的方式来回复。我希望你可以以中文的方式给我回答。这里我问你日期的话再回答否则的话你不要回答今天的日期是 {current_date}.)//.defaultAdvisors(new PromptChatMemoryAdvisor(chatMemory)).defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build();// 调用chatClient的prompt方法设置用户消息、系统消息参数、顾问参数返回内容流FluxString content chatClient.prompt().user(message).system(s-s.param(current_date, LocalDate.now().toString())).advisors(a - a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)).stream().content();// 返回内容流return content;} 响应结果
这样的话就会记住你最近的100条对话当然这里你也可以自行实现ChatMemory使用Redis去进行获取 上面两种记忆是不同的具体详情请看下表
特性MessageChatMemoryAdvisorPromptChatMemoryAdvisor记忆管理粒度基于消息Message级别的记忆基于提示Prompt级别的记忆记忆的存储方式将每一条消息存储到记忆中生成合适的提示将历史对话作为提示提供给模型适用场景适用于需要精细管理每一条消息的场景适用于需要生成合适提示来为模型提供上下文的场景如何影响对话直接影响聊天记录确保每一条消息都被记住影响提示构造确保生成的提示与上下文一致内存管理的灵活性依赖于每个消息的存储提示的构造和上下文的动态管理
打印日志功能 测试用例代码
其实也就是再次添加一个Advisors再控制台打印一下就可以
public class LoggingAdvisors implements RequestResponseAdvisor {Overridepublic AdvisedRequest adviseRequest(AdvisedRequest request, MapString, Object adviseContext) {System.out.println(Requestrequest);return request;}Overridepublic int getOrder() {return 0;}
}
// 使用GetMapping注解指定请求路径为/AIChatDefaultStream返回类型为文本流GetMapping(value /AIChatDefaultLoggingStream,produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIChatDefaultLoggingStream(// 使用RequestParam注解指定请求参数名为message类型为StringRequestParam(value message) String message) {// 创建ZhiPuAiChatOptions对象设置模型和温度ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(default_model).withTemperature(default_temperature).build();// 创建ChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModel设置默认系统消息和默认顾问ChatClient chatClient ChatClient.builder(chatModel).defaultSystem(你现在的身份是一个星轨会议系统的客服助手请以友好、乐于助人且愉快的方式来回复。我希望你可以以中文的方式给我回答。这里我问你日期的话再回答否则的话你不要回答今天的日期是 {current_date}.)//.defaultAdvisors(new PromptChatMemoryAdvisor(chatMemory)).defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory),new LoggingAdvisors()).build();// 调用chatClient的prompt方法设置用户消息、系统消息参数、顾问参数返回内容流FluxString content chatClient.prompt().user(message).system(s-s.param(current_date, LocalDate.now().toString())).advisors(a - a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)).stream().content();// 返回内容流return content;} 响应结果 FunctionCall回调
测试用例代码
package com.hhh.springai_test.Client;import com.hhh.springai_test.config.ChatConfig;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.zhipuai.ZhiPuAiChatModel;
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
import org.springframework.ai.zhipuai.api.ZhiPuAiApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;Component
public class ZhipuChatClient {Resourceprivate ChatConfig chatConfig;AutowiredQualifier(customMemory) // 明确指定使用你自定义的 ChatMemory 实现private ChatMemory chatMemory;public ChatClient getZhipuChatClient() {ZhiPuAiChatOptions options ZhiPuAiChatOptions.builder().withModel(GLM-4-Flash).withTemperature(0.95F).build();// 创建ChatModel对象传入ZhiPuAiApi和optionsChatModel chatModel new ZhiPuAiChatModel(new ZhiPuAiApi(chatConfig.getApiKey()), options);// 创建ChatClient对象传入chatModel设置默认系统消息和默认顾问ChatClient chatClient ChatClient.builder(chatModel).defaultSystem(你现在的身份是一个星轨会议系统的客服助手请以友好、乐于助人且愉快的方式来回复。我希望你可以以中文的方式给我回答。这里我问你日期的话再回答否则的话你不要回答).defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build();return chatClient;}
}GetMapping(value /AIChatDefaultLoggingStream, produces MediaType.TEXT_EVENT_STREAM_VALUE)public FluxString AIChatDefaultLoggingStream(RequestParam(value message) String message) {FluxString content zhipuChatClient.getZhipuChatClient().prompt().user(message).function(report, 举报, new FunctionMyController.Request, FluxString() {Overridepublic FluxString apply(MyController.Request request) {System.out.println(举报名字是 request.name);return Flux.just(星轨);}}).stream().content();return content;} 测试用例结果 可以看到日志也已经解决了在这里遇到了整整两天的bug一直在尝试使用functions通过传递functionBean来进行解决但是一直是有问题的但是一直报错只能使用这种方式来解决当然如果大佬们有好的文章记得可以推荐我使用一下谢谢各位大佬们