文心一言&文心千帆大模型的starter

前言


项目开源地址https://github.com/rainveil/wenxin-starter


大家好,我是[DaCapo]。


半个月前,正在跟着鱼皮哥的视频做智能BI的项目,于是乎,我就在想是不是可以尝试一下接入其他的大模型,也可以对比下各个模型在这方面的能力,于是,我把国产所有大模型的API调用服务申请了一遍...

其中,百度的文心一言&文心千帆大模型API有了回信,在申请了一天之后,通过了。(兴奋.jpg)

(会送20的代金券)

文心千帆大模型的模型其实有很多,截止到目前,已经有了ErnieBotERNIE-Bot-turboBLOOMZ-7BLlama-2(未正式发布)、Prompt模板这几种,他们的API很类似但又存在一定的区别。


于是在API开放平台的那个starter的启发下,萌生了做一个文心一言starter的想法。


介绍


为了解决文心千帆众多模型调用复杂、大量重复代码的问题,开发了这个starter,里面封装了丰富的方法,对API做了更多的封装处理,例如在连续对话中,如果我们想实现连续对话,那么下次发送请求要把前面的问题与回答都带上,而且文心千帆模型API本身还有规则限制,问题content总长度如果超过2000字符就会依次以往最早的问题...这些逻辑都需要我们自行处理。


但是在starter中,已经对这些逻辑进行了封装,你只需要chatCont方法就可以,剩下的什么都不用管,一行代码即可解决这个问题

ChatResponse response = ernieBotClient.chatCont(content, chatUID);

相同UID即为同一轮对话,新开一轮对话只要需要更换一个chatUID即可。


并且提供了对话历史的管理功能方便开发者进行对话历史记录的管理操作,方便开发者导出对话记录保存。

Map<String, Queue<Message>> messageHistoryMap = ernieBotTurboClient.getMessageHistoryMap();

不过目前仅支持从内存里存取...也就是说,下次初始化得先从数据库或者是Redis里取出来放到内存里....

设计不太合理...我会尽快修改。


初始化消息列表:


此外,starter提供了“单轮对话”“多轮对话”“Prompt模板”等方法,并且都对应提供了“流式返回”与“非流式返回”两种方式。


关于流式返回这方面,文心千帆是基于服务器发送事件(Server-Sent Events),也就是SSE技术实现的,在客户端与服务器之间建立持久性的单向连接,服务器可以通过该连接向客户端发送任意数量的数据。

starter中,这一部分使用的是webflux实现的,相关代码如下:

具体的webflux的使用大家可以参考这篇博客:WebFlux



快速开始


首先,需要申请文心一言&文心千帆的API调用资格,并获取access-token,具体的流程可以参考我发在掘金的文章:申请文心一言&文心千帆大模型API资格、获取access_token,并使用SpringBoot接入文心一言API


然后,引入starter的maven坐标:

<dependency>
<groupId>io.github.gemingjia</groupId>
<artifactId>gear-wenxinworkshop-starter</artifactId>
<version>0.0.3.2</version>
</dependency>


在application.yml中添加你的access-token:

gear:
wenxin:
access-token: xx.xxxxxxxxxx.xxxxxx.xxxxxxx.xxxxx-xxxx


然后注入要使用的模型的客户端就可以尽情使用啦~(此处基于鱼皮哥的springboot-init模板)

@RestController
public class ChatController {

// 要调用的模型的客户端
@Resource
private ErnieBotClient ernieBotClient;

// 单次对话
@PostMapping("/chat")
public BaseResponse<String> chatSingle(String msg) {
ChatResponse response = ernieBotClient.chatSingle(msg);
return ResultUtils.success(response.getResult());
}

// 连续对话
@PostMapping("/chats")
public BaseResponse<String> chatCont(String msg) {
String chatUID = "test-user-1001";
ChatResponse response = ernieBotClient.chatCont(msg, chatUID);
return ResultUtils.success(response.getResult());
}

// 流式返回,单次对话
@PostMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public BaseResponse<Flux<ChatResponse>> chatSingleStream(String msg) {
Flux<ChatResponse> chatResponseFlux = ernieBotClient.chatSingleOfStream(msg);
return ResultUtils.success(chatResponseFlux);
}

// 流式返回,连续对话
@PostMapping(value = "/stream/chats", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public BaseResponse<Flux<ChatResponse>> chatContStream(String msg, String msgUid) {
Flux<ChatResponse> chatResponseFlux = ernieBotClient.chatContOfStream(msg, msgUid);
return ResultUtils.success(chatResponseFlux);
}

// 模板对话
@PostMapping("/rompt")
public BaseResponse<PromptResponse> chatSingle() {
Map<String, String> map = new HashMap<>();
map.put("article", "我看见过波澜壮阔的大海,玩赏过水平如镜的西湖,却从没看见过漓江这样的水。漓江的水真静啊,静得让你感觉不到它在流动。");
map.put("number", "10");
PromptRequest promptRequest = new PromptRequest();
promptRequest.setId(1234);
promptRequest.setParamMap(map);
PromptResponse promptResponse = promptBotClient.chatPrompt(promptRequest);

return ResultUtils.success(promptResponse);
}

}


上传到maven仓库教程可以参考这篇博客:gpg加密发布jar包到maven中央仓库详细过程以及踩的坑



总结


由于是第一次做这东西,确实也没太有经验,所以做的过程中也是跌跌撞撞,期间遇到了好多的问题,不过好在都解决了。有些功能与整体的设计也不太合理,大家在使用过程中遇到什么问题或者是有什么建议,欢迎在github提issue与pr~


最后感叹一句,基础知识真是太重要了!



开源地址:https://github.com/rainveil/wenxin-starter


文档:https://github.com/rainveil/wenxin-starter/blob/master/wenxin-doc.md


欢迎各位鱼友star~

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
mynna
下载 APP