Springboot --- 使用国内的 AI 大模型 对话
- 实在是不知道标题写什么了 可以在评论区给个建议哈哈哈哈 先用这个作为标题吧
尝试使用 国内给出的 AI 大模型做出一个 可以和 AI 对话的 网站出来
- 使用 智普AI 只能 在控制台中输出 对应的信息 不如就做一个 maven 的 项目调用对应的API
https://open.bigmodel.cn/dev/api#glm-4
<dependency>
<groupId>cn.bigmodel.openapi</groupId>
<artifactId>oapi-java-sdk</artifactId>
<version>release-V4-2.0.0</version>
</dependency>
- 使用 普通的 java -- Maven项目 只能在控制台 查看结果 也就是 说没有办法在其他平台 使
用 制作出来的 AI ChatRobot - 思来想去 不如 将这个东西写成 QQ 机器人
- 但是因为我找到的 那个 不更新了 或者 腾讯不支持了 让我放弃了 写成 QQ 机器人的想法
- 于是我就尝试将这个写成一个本地的 AI 对话机器人 但是 在翻看 官方给出的 Demo 我偶然发现了一个方法 他的 输出似乎是一个 json 转换成的 String
- 这个方法并没有将这个String 返回出来 而是 直接在控制台打印
package com.codervibe.utils;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.zhipu.oapi.ClientV4;
import com.zhipu.oapi.Constants;
import com.zhipu.oapi.service.v4.image.CreateImageRequest;
import com.zhipu.oapi.service.v4.image.ImageApiResponse;
import com.zhipu.oapi.service.v4.model.*;
import io.reactivex.Flowable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class ChatAPIUtils {
private static final String API_KEY = "cb11ad7f3b68ce03ed9be6e13573aa19";
private static final String API_SECRET = "nG7UQrrXqsXtqD1S";
private static final ClientV4 client = new ClientV4.Builder(API_KEY, API_SECRET).build();
private static final ObjectMapper mapper = defaultObjectMapper();
public static ObjectMapper defaultObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.addMixIn(ChatFunction.class, ChatFunctionMixIn.class);
mapper.addMixIn(ChatCompletionRequest.class, ChatCompletionRequestMixIn.class);
mapper.addMixIn(ChatFunctionCall.class, ChatFunctionCallMixIn.class);
return mapper;
}
// 请自定义自己的业务id
private static final String requestIdTemplate = "mycompany-%d";
/**
* 同步调用
*/
public static String InvokeApi(String content) throws JsonProcessingException {
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), content);
messages.add(chatMessage);
String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
// 函数调用参数构建部分
List<ChatTool> chatToolList = new ArrayList<>();
ChatTool chatTool = new ChatTool();
chatTool.setType(ChatToolType.FUNCTION.value());
ChatFunctionParameters chatFunctionParameters = new ChatFunctionParameters();
chatFunctionParameters.setType("object");
Map<String, Object> properties = new HashMap<>();
properties.put("location", new HashMap<String, Object>() {{
put("type", "string");
put("description", "城市,如:北京");
}});
properties.put("unit", new HashMap<String, Object>() {{
put("type", "string");
put("enum", new ArrayList<String>() {{
add("celsius");
add("fahrenheit");
}});
}});
chatFunctionParameters.setProperties(properties);
ChatFunction chatFunction = ChatFunction.builder()
.name("get_weather")
.description("Get the current weather of a location")
.parameters(chatFunctionParameters)
.build();
chatTool.setFunction(chatFunction);
chatToolList.add(chatTool);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(Constants.ModelChatGLM4)
.stream(Boolean.FALSE)
.invokeMethod(Constants.invokeMethod)
.messages(messages)
.requestId(requestId)
.tools(chatToolList)
.toolChoice("auto")
.build();
ModelApiResponse invokeModelApiResp = client.invokeModelApi(chatCompletionRequest);
try {
// 这里返回出去是一个 json
return mapper.writeValueAsString(invokeModelApiResp);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return mapper.writeValueAsString(new ModelApiResponse());
}
public static void CreateImage(String content) {
CreateImageRequest createImageRequest = new CreateImageRequest();
createImageRequest.setModel(Constants.ModelCogView);
createImageRequest.setPrompt(content);
ImageApiResponse imageApiResponse = client.createImage(createImageRequest);
System.out.println("imageApiResponse:" + JSON.toJSONString(imageApiResponse));
}
}
- 工具类中 InvokeApi 方法 最后获得的是一个 ModelApiResponse类 这个类有点类似于 统一返回类型 但是我在这里 只需要里面的具体方法 请求状态和 信息 并不需要 (有另外一个统一返回类型定义 ) 所以在 后面我将这个方法 修改 改为 将我需要的数据返回给controller
- 实际上这是不应该直接返回给 controller 的 而是 应该 通过 service 的 因为service中才是真正的业务代码
- 修改后的方法 代码如下
/**
* 同步调用
*/
public static ModelData InvokeApi(String content) throwsJsonProcessingException{
List<ChatMessage> messages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), content);
messages.add(chatMessage);
String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
// 函数调用参数构建部分
List<ChatTool> chatToolList = new ArrayList<>();
ChatTool chatTool = new ChatTool();
chatTool.setType(ChatToolType.FUNCTION.value());
ChatFunctionParameters chatFunctionParameters = new ChatFunctionParameters();
chatFunctionParameters.setType("object");
Map<String, Object> properties = new HashMap<>();
properties.put("location", new HashMap<String, Object>() {{
put("type", "string");
put("description", "城市,如:北京");
}});
properties.put("unit", new HashMap<String, Object>() {{
put("type", "string");
put("enum", new ArrayList<String>() {{
add("celsius");
add("fahrenheit");
}});
}});
chatFunctionParameters.setProperties(properties);
ChatFunction chatFunction = ChatFunction.builder()
.name("get_weather")
.description("Get the current weather of a location")
.parameters(chatFunctionParameters)
.build();
chatTool.setFunction(chatFunction);
chatToolList.add(chatTool);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(Constants.ModelChatGLM4)
.stream(Boolean.FALSE)
.invokeMethod(Constants.invokeMethod)
.messages(messages)
.requestId(requestId)
.tools(chatToolList)
.toolChoice("auto")
.build();
ModelApiResponse invokeModelApiResp = client.invokeModelApi(chatCompletionRequest);
ModelData data = invokeModelApiResp.getData();
return data;
- 而这里的信息实际上是一层层 抽丝剥茧 剥离出来的
List<Choice> choices = data.getChoices();
System.out.println("choices.toString() = " + choices.toString());
for (Choice choice : choices) {
ChatMessage message = choice.getMessage();
System.out.println("message.getContent() = " + message.getContent());
//本来这里想返回具体的信息类但是发现 上面的的那个ModelApiResponse类 也是一个 统一返回类型 也包含这 请求状态码 之类的定义
return message;
}
return new ChatMessage();
try {
return mapper.writeValueAsString(invokeModelApiResp);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return mapper.writeValueAsString(new ModelApiResponse());
- 可以看到我的这段代码 有多个 return 所以这实际上是一段假 代码
- 每一个return 实际上官方都 对应的 model 或者说 resoponse
- controller 代码
@PostMapping("/chat")
public R chat(@RequestParam("content") String content) throws JsonProcessingException {
/**
* data 中的 choices 是一个 List<Choice> 类型但是实际上只有一个所以索性直接获取数组下标0的对象
*/
logger.info(ChatAPIUtils.InvokeApi(content).getChoices().get(0).getMessage().getContent().toString());
return R.ok().data("content", ChatAPIUtils.InvokeApi(content));
}
- 修改 由 service 层 调用 工具类
- service 代码
- service 接口
package com.codervibe.server.service;
import com.zhipu.oapi.service.v4.image.ImageResult;
import com.zhipu.oapi.service.v4.model.ModelData;
public interface ChatService {
/**
* AI 对话
*/
ModelData AIdialogue(String content);
/**
* AI 画图
*/
ImageResult AIcreateimage(String content);
}
- service 接口实现
package com.codervibe.server.Impl;
import com.codervibe.server.service.ChatService;
import com.codervibe.utils.ChatAPIUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhipu.oapi.service.v4.image.ImageResult;
import com.zhipu.oapi.service.v4.model.ModelData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service("chatService")
public class ChatServiceImpl implements ChatService {
Logger logger = LoggerFactory.getLogger(ChatServiceImpl.class);
/**
* AI 对话
* @param content
*/
@Override
public ModelData AIdialogue(String content) {
logger.info(ChatAPIUtils.InvokeApi(content).getChoices().get(0).getMessage().getContent().toString());
return ChatAPIUtils.InvokeApi(content);
}
/**
* AI 画图
*
* @param content
*/
@Override
public ImageResult AIcreateimage(String content) {
logger.info(ChatAPIUtils.CreateImage(content).getData().get(0).getUrl());
return ChatAPIUtils.CreateImage(content);
}
}
- controller 层调用 service
****package com.codervibe.web.controller;
import com.codervibe.server.service.ChatService;
import com.codervibe.utils.ChatAPIUtils;
import com.codervibe.web.common.response.R;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
@RestController
@RequestMapping("/chat")
public class ChatController {
Logger logger = LoggerFactory.getLogger(ChatController.class);
@Resource
private ChatService chatService;
@PostMapping("/content")
public R chat(@RequestParam("content") String content) {
return R.ok().data("content", chatService.AIdialogue(content));
}
@PostMapping("/AIcreateimage")
public R AIcreateimage(@RequestParam("content") String content){
return R.ok().data("image",chatService.AIcreateimage(content));
}
}
- 现在 虽然可以 和 AI 进行对话 但是 数据返回的速度实在是太慢 所以我打算 将 常见的问题和答案 存储在本地的数据库中以提升 数据返回的速度 这只是一个初步的想法
- 最后的想法 还未实现 先这样
- 粉丝群 企鹅 179469398
Springboot --- 使用国内的 AI 大模型 对话的更多相关文章
- AI大模型学习了解
# 百度文心 上线时间:2019年3月 官方介绍:https://wenxin.baidu.com/ 发布地点: 参考资料: 2600亿!全球最大中文单体模型鹏城-百度·文心发布 # 华为盘古 上线时 ...
- 华为高级研究员谢凌曦:下一代AI将走向何方?盘古大模型探路之旅
摘要:为了更深入理解千亿参数的盘古大模型,华为云社区采访到了华为云EI盘古团队高级研究员谢凌曦.谢博士以非常通俗的方式为我们娓娓道来了盘古大模型研发的"前世今生",以及它背后的艰难 ...
- 保姆级教程:用GPU云主机搭建AI大语言模型并用Flask封装成API,实现用户与模型对话
导读 在当今的人工智能时代,大型AI模型已成为获得人工智能应用程序的关键.但是,这些巨大的模型需要庞大的计算资源和存储空间,因此搭建这些模型并对它们进行交互需要强大的计算能力,这通常需要使用云计算服务 ...
- zz独家专访AI大神贾扬清:我为什么选择加入阿里巴巴?
独家专访AI大神贾扬清:我为什么选择加入阿里巴巴? Natalie.Cai 拥有的都是侥幸,失去的都是人生 关注她 5 人赞同了该文章 本文由 「AI前线」原创,原文链接:独家专访AI大神贾扬清:我 ...
- 文心一言,通营销之学,成一家之言,百度人工智能AI大数据模型文心一言Python3.10接入
"文心"取自<文心雕龙>一书的开篇,作者刘勰在书中引述了一个古代典故:春秋时期,鲁国有一位名叫孔文子的大夫,他在学问上非常有造诣,但是他的儿子却不学无术,孔文子非常痛心 ...
- 好饭不怕晚,Google基于人工智能AI大语言对话模型Bard测试和API调用(Python3.10)
谷歌(Google)作为开源过著名深度学习框架Tensorflow的超级大厂,是人工智能领域一股不可忽视的中坚力量,旗下新产品Bard已经公布测试了一段时间,毁誉参半,很多人把Google的Bard和 ...
- DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍 1. 概述 近日来,ChatGPT及类似模型引发了人工智能(AI)领域的一场风潮. 这场风潮对数字世 ...
- HBase实践案例:知乎 AI 用户模型服务性能优化实践
用户模型简介 知乎 AI 用户模型服务于知乎两亿多用户,主要为首页.推荐.广告.知识服务.想法.关注页等业务场景提供数据和服务, 例如首页个性化 Feed 的召回和排序.相关回答等用到的用户长期兴趣特 ...
- 阿里开源新一代 AI 算法模型,由达摩院90后科学家研发
最炫的技术新知.最热门的大咖公开课.最有趣的开发者活动.最实用的工具干货,就在<开发者必读>! 每日集成开发者社区精品内容,你身边的技术资讯管家. 每日头条 阿里开源新一代 AI 算法模型 ...
- 搭乘“AI大数据”快车,肌肤管家,助力美业数字化发展
经过疫情的发酵,加速推动各行各业进入数据时代的步伐.美业,一个通过自身技术.产品让用户变美的行业,在AI大数据的加持下表现尤为突出. 对于美妆护肤企业来说,一边是进入存量市场,一边是疫后的复苏期,一边 ...
随机推荐
- If Messi doesn't understand how to respect others, then he also doesn't deserve to receive respect from others.
If Messi doesn't understand how to respect others, if he doesn't understand the spirit of honoring c ...
- 很好用的python游戏环境(续):强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个python语言的迷宫游戏环境
相关: 很好用的python游戏环境:强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个python语言的迷宫游戏环境 前文分享了一个python下的maze游戏环境,本文再给出一 ...
- python语言绘图:绘制一组正态分布图
代码源自: https://github.com/PacktPublishing/Bayesian-Analysis-with-Python ============================= ...
- oracle执行报错 ORA-01722: 无效数字
1.背景 执行Oracle存储过程时报错:ORA-01722: 无效数字 2.错误描述 1.对于两个类型不匹配,一个数字类型,一个非数字类型的值进行赋值操作;2.两个类型不匹配的值进行比较操作,比如一 ...
- Cython将Numpy数组转为自定义结构体
技术背景 前面我们写过几篇关于Cython的文章,例如Cython计算谐振势.Cython与C语言的结合.Cython调用CUDA Kernel函数.Cython有着非常Pythonic的编程范式,又 ...
- NOI2024 集合 题解
给个链接:集合. 很神秘的题目.基本上看到之后就可以想到哈希. 首先想到一个比较神秘的暴力.就是对于每个询问,扫一遍所有 \(a\) 中的数出现的位置,把它弄成一个哈希值(具体怎么弄随意)存到 set ...
- Win32_GDI_绘制文字路径透明窗口
效果图: 前面字体是个透明窗口 后面是桌面背景 代码实现: void MyMainDialog::TextPathWindow(LPCTSTR lpShowText) { HDC hdc = GetD ...
- C程序起点main函数
C程序起点main函数 main c语言中main函数接收两个参数int argc, char* argv[] int main(int argc, char* argv[]); int main(i ...
- Oracle导出数据库与还原
导出部分 1.获取到Oracle directory目录与实际电脑目录的映射 2.CMD导出Oracle数据库 DMP文件 //expdp 用户/密码@数据库监听地址 schemas=表空间名称 du ...
- ZXING 修复预览页面变形问题
ZXING之前都用的好好的,结果在一个Android11的设备上翻了车 (基于全屏预览的情况下) 扫码页面预览效果变形, 在网上找了一些代码,修改后发现无效,不适用我这边的设备, 最后想着,预览结果变 ...