ToB企服应用市场:ToB评测及商务社交产业平台
标题:
springboot + websocket对接文心一言接口实现简朴上下文谈天(贴代码)
[打印本页]
作者:
泉缘泉
时间:
2024-8-11 08:35
标题:
springboot + websocket对接文心一言接口实现简朴上下文谈天(贴代码)
如题,第一次用websocket,做了个这玩意,只做了上下文的谈天,没做流式。
中心另有个低级报错但卡了好久,具体可以看【错误记载】websocket连接失败,但后端毫无反应,另有【错误记载】ruoyi-vue@Autowired注入自定义mapper时为null解决
,感兴趣可前往观看。
实际上我后端用的是ruoyi-vue,前端用的ruoyi-app,但不重要。由于功能就是基于websocket和文心一言千帆大模型的接口,完全可以独立出来。
每个新建的账号会送一张20元的代金券,限期一个月内。而谈天服务接口单价约1分/千token,总之用来练手肯定够用了。
参考
文档中心-ERNIE-Bot-turbo
百度文心一言接入教程
若依插件-集成websocket实现简朴通信
先看看效果
大抵这样。
2023.10.13更新
:昨天和朋侪聊了一下,发现他的想法和我的差别——根本不用实体类去保存解析复杂的json,直接保存消息内容。有一说一,在这个小demo这里,确实可以更快更简朴的实现,由于这个demo最耗时的就是看又臭又长的参数,然后写哀求体和返回值的实体类,至少哀求体实体类是可以不写的。
下面进入正题。
文心千帆创建应用
文心一言,大概是这里,先创建个账号,进控制台创建一个应用(有一个apikey和secretkey,有用),开通一个谈天服务(我开通的是ErnieBot-turbo),就可以了。具体有点忘了,大家可以参考其他博客。
其次官方有给一些参考,API调用指南、在线测试平台,第二个链接可以对自己开通的谈天服务进行测试。其中也有一个分类是“技能文档”和“示例代码”,技能文档里边有普通/流式的哀求/响应的参数和示例(如果比力小不容易看,文档中心-ERNIE-Bot-turbo也有),示例代码就是哀求的各个语言的示例代码。
思路
有三个角色,大模型 ←→ 后端 ←→ 前端。
大模型:接受后端发过来的消息,返反响应消息
后端:接受前端发过来的消息,封装发给大模型;接收大模型返回的消息,回给后端;发送的消息和返回的消息都要保存到数据库
前端:发送消息,接受后端返回的响应消息,及时回显在谈天页面。
显然,websocket用在前后端之间进行交互,后端类似一个中心人,前端是一个用户,大模型是ai服务。
步调与代码
实现websocket相关
1.1 注册到spring
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
复制代码
1.2 实现一个WebSocket的服务(别看这么长,其实参考了若依插件-集成websocket实现简朴通信,但没涉及信号量之类以是没什么用,除了onMessage外,其他如onOpen打印一条消息就行了,更多如WebSocketUsers可以去链接那下载)
@CrossOrigin
@Component
@ServerEndpoint("/websocket/message")
public class WebSocketServer {
private ChatRecordMapper chatRecordMapper = SpringUtils.getBean(ChatRecordMapper.class);
/**
* WebSocketServer 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
/**
* 默认最多允许同时在线人数100
*/
public static int socketMaxOnlineCount = 100;
private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) throws Exception {
boolean semaphoreFlag = false;
// 尝试获取信号量
semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
if (!semaphoreFlag) {
// 未获取到信号量
LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
session.close();
} else {
// 添加用户
WebSocketUsers.put(session.getId(), session);
LOGGER.info("\n 建立连接 - {}", session);
LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
WebSocketUsers.sendMessageToUserByText(session, "连接成功");
}
}
/**
* 连接关闭时处理
*/
@OnClose
public void onClose(Session session) {
LOGGER.info("\n 关闭连接 - {}", session);
// 移除用户
WebSocketUsers.remove(session.getId());
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 抛出异常时处理
*/
@OnError
public void onError(Session session, Throwable exception) throws Exception {
if (session.isOpen()) {
// 关闭连接
session.close();
}
String sessionId = session.getId();
LOGGER.info("\n 连接异常 - {}", sessionId);
LOGGER.info("\n 异常信息 - {}", exception);
// 移出用户
WebSocketUsers.remove(sessionId);
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 服务器接收到客户端消息时调用的方法
*/
@OnMessage
public void onMessage(String message, Session session) {
// 首先,接收到一条消息
LOGGER.info("\n 收到消息 - {}", message);
// 1. 调用大模型API,把上下文和这次问题传入,得到回复
BigModelService bigModelService = new BigModelService();
TurboResponse response = bigModelService.callModelAPI(session.getId(),message);
if (response == null) {
WebSocketUsers.sendMessageToUserByText(session, "抱歉,似乎出了点问题,请联系管理员");
return;
}
WebSocketUsers.sendMessageToUserByText(session, response.getResult());
}
}
复制代码
实现哀求接口相关
2.1 先写实体类,包括BaiduChatMessage(最基本的谈天消息)、ErnieBotTurboParam(ErnieBot-Turbo的哀求参数,包括了List<BaiduChatMessage>)TurboResponse(哀求返回结果对应的实体类)
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsC
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4