引言
将 GPT、向量数据库和 Function calling 结合起来,可以构建一个垂直领域小助手。例如,我们可以使用 GPT 来处理自然语言任务,使用向量数据库来存储和管理领域相关的数据,使用 Function calling 来实现领域相关的推理和计算规则。这样,我们就可以构建一个针对特定领域的小助手,例如医疗保健、金融服务、法律咨询等。
今天为大家分享一个保险领域AI小助手的DEMO展示,含代码!!!
工具介绍
GPT
GPT (Generative Pretrained Transformer)是一种基于 Transformer 架构的大型语言模型,通过在大量文本上进行无监督学习,模型学习到了语言的统计规律和语义表示,从而能够处理各式各样的自然语言任务,例如文本生成、知识问答、推理计算、阅读理解等。
本文使用模型:gpt-3.5-turbo
本文使用GPT方法:Chat Completions API
向量数据库
向量数据库 是一种用于存储和管理向量数据的数据仓库,其中向量是一种将文本、图像、音频等非结构化数据转换为可计算的稠密向量表示的技术。通过使用向量数据库,我们可以快速地查找和比较相似的向量,从而实现诸如文本分类、聚类、推荐系统等应用。
本文使用腾讯云向量数据库
Function calling
Function calling 是一种在编程语言中调用函数的机制。通过函数调用,我们可以将复杂的任务分解为多个简单的函数,并通过调用这些函数来完成任务。在自然语言处理中,我们可以使用 Function calling 来实现自定义的推理和计算规则。
本文使用:gpt-3.5的Function calling
代码:
向腾讯云向量向量数据库构建数据
0、maven依赖
java
<vectordatabase-sdk-java.version>1.2.0</vectordatabase-sdk-java.version>
<okhttp.version>4.9.2</okhttp.version>
<dependency>
<groupId>com.tencent.tcvectordb</groupId>
<artifactId>vectordatabase-sdk-java</artifactId>
<version>${vectordatabase-sdk-java.version}</version>
<exclusions>
<!--因为我项目依赖了log4j相关其他包所以这里对impl包进行了排除 -->
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
1、获取腾讯云client信息
这里的相关Url和相关账户请替换成自己的
java
/**
* 链接信息
*/
private static VectorDBClient CLIENT = null;
/**
* 存放消息体的地方-模拟数据库,因为是DEMO所以没有接数据库只在自己内存用一下
*/
private static Map<String, LinkedList<MessageV2>> SESSION_MSG_MAP = new HashMap<>(10);
/**
* 获取腾讯云client信息
* @return client
*/
@PostConstruct
private void initVectorDBClient(){
if(CLIENT == null){
log.info("VectorTestController buildVectorDBClient -----------开始");
// 创建VectorDB Client 这里的相关Url和相关账户请替换成自己的
ConnectParam connectParam = ConnectParam.newBuilder()
.withUrl(apolloConfigHolder.getDashVector2040312EndPoint())
.withUsername(apolloConfigHolder.getDashVectorUserName2040312())
.withKey(apolloConfigHolder.getDashVectorApiKey2040312())
.withTimeout(30)
.build();
log.info("VectorTestController buildVectorDBClient -----------参数,connectParam = {}", JsonUtil.getJsonString(connectParam));
CLIENT = new VectorDBClient(connectParam, ReadConsistencyEnum.EVENTUAL_CONSISTENCY);
log.info("VectorTestController buildVectorDBClient -----------成功");
}
}
2、创建腾讯云数据库
java
/**
* 创建腾讯云数据库
* @param databaseName
* @return
*/
private Database buildDatabase(String databaseName){
log.info("VectorTestController createDatabase -----------开始 , databaseName = {}", databaseName);
SdbCommonAssert.notBlank(databaseName, ErrorCode.PARAMS_IS_NULL);
Database db = CLIENT.createDatabase(databaseName);
log.info("VectorTestController createDatabase -----------成功 , databaseName = {}", databaseName);
return db;
}
3、向指定数据库和分区构建初始化数据
java
/**
* databaseName=zzz
* collectionName=zzz
* 向指定分区构建初始化数据
* @return 初始化数据与否
*/
@RequestMapping("test/initXXX")
public com.shuidihuzhu.sdb.models.Response<Boolean> initCollection(@RequestParam(name = "databaseName",required = true) String databaseName,
@RequestParam(name = "collectionName",required = true) String collectionName){
SdbCommonAssert.notBlank(databaseName, ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(collectionName, ErrorCode.PARAMS_IS_NULL);
List<String> listDatabase = CLIENT.listDatabase();
Boolean clientBuildFlag = Boolean.FALSE;
for (String database : listDatabase){
if(Objects.equals(database,databaseName)){
clientBuildFlag = Boolean.TRUE;
}
}
Database db = null;
if(!clientBuildFlag){
db = this.buildDatabase(databaseName);
}else {
db = CLIENT.database(databaseName);
}
Boolean collectionFlag = Boolean.FALSE;
Collection collection = null;
List<Collection> collections = db.listCollections();
for(Collection collectionItem : collections){
if(Objects.equals(collectionItem.getCollection(),collectionName)){
collectionFlag = Boolean.TRUE;
collection = collectionItem;
}
}
if(!collectionFlag){
CreateCollectionParam collectionParam = CreateCollectionParam.newBuilder()
.withName(collectionName)
.withReplicaNum(2)
.withShardNum(1)
.withDescription("小超公司基本法信息章节存储表,存储小超公司历史基本法信息及基本法版本信息")
.addField(new FilterIndex("id", FieldType.String, IndexType.PRIMARY_KEY))
.addField(new FilterIndex("chapterName", FieldType.String, IndexType.FILTER))
.addField(new FilterIndex("pageNo", FieldType.Uint64, IndexType.FILTER))
.addField(new FilterIndex("chapterNo", FieldType.Uint64, IndexType.FILTER))
.addField(new FilterIndex("parentChapterNo", FieldType.Uint64, IndexType.FILTER))
.addField(new VectorIndex("vector", 768, IndexType.HNSW, MetricType.COSINE, new HNSWParams(16, 200)))
.withEmbedding(
Embedding
.newBuilder()
.withModel(EmbeddingModelEnum.BGE_BASE_ZH)
.withField("lawText")
.withVectorField("vector")
.build())
.build();
collection = db.createCollection(collectionParam);
AffectRes affectRes = db.setAlias(collectionName, collectionName);
if(Objects.equals(affectRes.getCode(),0)){
log.info("VectorTestController initCollection setAlias -----------成功 , collectionName = {}", collectionName);
}else {
log.info("VectorTestController initCollection setAlias -----------失败 , collectionName = {} ,affectRes = {}", collectionName,JsonUtil.getJsonString(affectRes));
}
}
//该信息为虚拟信息,不能产生任何价值也不代表任何利益相关,纯粹是虚拟构建
Document doc1 = Document.newBuilder()
.withId("test0001")
.addDocField(new DocField("chapterName","首年度佣金发放规则"))
.addDocField(new DocField("pageNo",13))
.addDocField(new DocField("chapterNo",22))
.addDocField(new DocField("parentChapterNo",5))
.addDocField(new DocField("lawText","首年度佣金发放规则:一、保单在当月最后一天(含)前承保(包括当月承保及之前月份承保未核发佣金的保单);二、保单在次月XX日(含)前回访成功;三、保单在次月XX日(含)前完成《委托协议书》及《客户告知书》的签署;四、保单在次月XX日(含)前为非犹豫期退保状态;五、依据当地监管要求,保单在下月XX日(含)前完成质检;"))
.build();
//该信息为虚拟信息,不能产生任何价值也不代表任何利益相关,纯粹是虚拟构建
Document doc13 = Document.newBuilder()
.withId("test0013")
.addDocField(new DocField("chapterName","产品名称:XX保意外险"))
.addDocField(new DocField("pageNo",45))
.addDocField(new DocField("chapterNo",76))
.addDocField(new DocField("parentChapterNo",1))
.addDocField(new DocField("lawText","商品编码:rbywx\t\n" +
"产品名称:xXX保意外险\n" +
"保司简称:XXX保财险\n" +
"长短险标志:长险\n" +
"险种标志:意外\n" +
"等待期天数:30\n" +
"犹豫期天数:30\n" +
"宽限期天数:60\n" +
"一句话卖点:全面升级,保障更加多元\n" +
"产品卖点:[\"意外伤害保额最高XX万\",\"因为意外情况住院不会限制社保的报销范围\",\"因为意外住院享受住院津贴,因为意外骨折后后相关保障计划\"]\n" +
"最低保费描述:XX元起\n" +
"最高保费:XX\n" +
"职业范围描述:1-6类\n" +
"投保最小年龄限制(岁):X2\n" +
"投保最大年龄限制(岁):X1\n" +
"健康告知及注意事项:常见健康告知xxxxxx\n"))
.build();
InsertParam insertParam = InsertParam.newBuilder()
.addDocument(doc1)
.addDocument(doc13)
.withBuildIndex(true)
.build();
AffectRes affectRes = collection.upsert(insertParam);
if(Objects.equals(affectRes.getCode(),0)){
log.info("VectorTestController initCollection collectionUpsert -----------成功 , affectRes = {}", affectRes);
}else {
log.info("VectorTestController initCollection collectionUpsert -----------失败 , insertParam = {} ,affectRes = {}", JsonUtil.getJsonString(insertParam),JsonUtil.getJsonString(affectRes));
}
return ResponseUtil.makeSuccess(Boolean.TRUE);
}
清除指定构建的数据
java
/**
* 清空指定集合
* @return 初始化数据与否
*/
@RequestMapping("test/cleanXXX")
public com.shuidihuzhu.sdb.models.Response<Boolean> cleanCollection(@RequestParam(name = "databaseName",required = true) String databaseName,
@RequestParam(name = "collectionName",required = true) String collectionName){
SdbCommonAssert.notBlank(databaseName, ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(collectionName, ErrorCode.PARAMS_IS_NULL);
List<String> stringList = CLIENT.listDatabase();
Boolean clientBuildFlag = Boolean.FALSE;
for (String database : stringList){
if(Objects.equals(database,databaseName)){
clientBuildFlag = Boolean.TRUE;
}
}
Database db = null;
if(!clientBuildFlag){
db = this.buildDatabase(databaseName);
}else {
db = CLIENT.database(databaseName);
}
AffectRes affectRes = db.truncateCollections(collectionName);
log.info("cleanCollection result, affectRes = {}",JsonUtil.getJsonString(affectRes));
return ResponseUtil.makeSuccess(Objects.equals(affectRes.getCode(),0));
}
GPT交互接口
1、请求体
这里是请求GPT交互接口的请求体
java
/**
* @author chao
* @date 2024/3/14
**/
@Getter
@Setter
@Accessors(chain = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class MsgDto {
/**
* databaseName 数据库名称
*/
private String databaseName;
/**
* collectionName 集合名称
*/
private String collectionName;
/**
* appCode
*/
private String appCode;
/**
* 子模型
*/
private String aiModel = "gpt-3.5-turbo";
/**
* 会话内容-把会话内容信息存到一起,可为空
* 如果想持续获取内容,建议在初次生成后获取并存入
*/
private String sessionId;
/**
* 消息体内容
*/
private String prompt;
/**
* token数,可为空,默认300
*/
private Integer maxTokens;
/**
* 调节信息 ,可为空,默认0.0
*/
private Double temperature;
/**
* 输出Json ,默认True
*/
private Boolean outputJsonFlag = Boolean.TRUE;
/**
* 排名分数阈值(建议0.75)
*/
private Double scoreFlag = 0.77;
}
2、GPT请求接口
这里是构建GPT会话信息属于公共方法。
相关GPT的请求类和消息体类请自己根据官方文档进行包装,这里没有进行包装。
java
/**
* 构建GPT请求
* @param sessionId 会话内容
* @param appCode 租户编号
* @param body 消息提提
* @return
*/
private ChatCompletionResponseV2 completionBuild(String sessionId,String appCode, ChatCompletionBodyV2 body){
SdbCommonAssert.notBlank(sessionId,ErrorCode.PARAMS_IS_NULL,"sessionId value not null");
SdbCommonAssert.notBlank(appCode,ErrorCode.PARAMS_IS_NULL,"appCode value not null");
SdbCommonAssert.notNull(body,ErrorCode.PARAMS_IS_NULL,"body value not null");
ChatCompletionRequestV2 chatRequest = new ChatCompletionRequestV2();
chatRequest.setAppCode(appCode);
chatRequest.setChatCompletionBody(body);
log.info("innerChatCompletionsV2 chatRequest sessionId = {}, appCode = {}, chatRequest = {}",
sessionId,JsonUtil.getJsonString(appCode),JsonUtil.getJsonString(chatRequest));
Response<ChatCompletionResponseV2> gptResponse = chatGptOverseaClient.innerChatCompletionsV2(chatRequest);
if(!Objects.equals(gptResponse.getCode(),0)
|| Objects.isNull(gptResponse.getData())){
log.error("innerChatCompletionsV2 gptResponse value is null, sessionId = {}, chatRequest = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(chatRequest),JsonUtil.getJsonString(gptResponse));
return null;
}
List<ChoiceV2> choices = gptResponse.getData().getChoices();
if(CollectionUtils.isEmpty(choices)){
log.error("innerChatCompletionsV2 choices value is empty, sessionId = {}, chatRequest = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(chatRequest),JsonUtil.getJsonString(gptResponse));
return null;
}
//检查内容 默认 TRUE 正确
Boolean checkChoice = Boolean.TRUE;
for (ChoiceV2 choice : choices){
if(Objects.isNull(choice)
|| Objects.isNull(choice.getMessage())){
log.error("innerChatCompletionsV2 choice value is null, sessionId = {}, chatRequest = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(chatRequest),JsonUtil.getJsonString(gptResponse));
checkChoice = Boolean.FALSE;
continue;
}
ChoiceV2.ResMessage message = choice.getMessage();
if(StringUtils.isBlank(message.getContent())
&& CollectionUtils.isEmpty(message.getTool_calls())){
log.error("innerChatCompletionsV2 choice value is null, sessionId = {}, chatRequest = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(chatRequest),JsonUtil.getJsonString(gptResponse));
checkChoice = Boolean.FALSE;
}
}
if(!checkChoice){
log.error("innerChatCompletionsV2 choice value is null, sessionId = {}, chatRequest = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(chatRequest),JsonUtil.getJsonString(gptResponse));
return null;
}
return gptResponse.getData();
}
3、GPT交互接口
真实的GPT交互接口
java
/**
* GPT交互接口
* @param msgDto
* @return
*/
@RequestMapping("test/gptXXX")
public com.shuidihuzhu.sdb.models.Response<MsgResponseDto> innerChatCompletionsV2(@RequestBody(required = true) MsgDto msgDto){
SdbCommonAssert.notNull(msgDto, ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(msgDto.getDatabaseName(),ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(msgDto.getCollectionName(),ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(msgDto.getAppCode(),ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(msgDto.getAiModel(),ErrorCode.PARAMS_IS_NULL);
SdbCommonAssert.notBlank(msgDto.getPrompt(),ErrorCode.PARAMS_IS_NULL);
String sessionId = msgDto.getSessionId();
if(StringUtils.isBlank(sessionId)){
//唯一串生成代码,请替换成自己的或使用UUID
sessionId = uniqueCodeComponent.getUniqueCode();
msgDto.setSessionId(sessionId);
}
Database db = CLIENT.database(msgDto.getDatabaseName());
Collection collection = db.collection(msgDto.getCollectionName());
String prompt = msgDto.getPrompt();
SearchByEmbeddingItemsParam searchByEmbeddingItemsParam = SearchByEmbeddingItemsParam.newBuilder()
.withEmbeddingItems(Collections.singletonList(prompt))
// 若使用 HNSW 索引,则需要指定参数 ef,ef 越大,召回率越高,但也会影响检索速度
.withParams(new HNSWSearchParams(200))
// 设置标量字段的 Filter 表达式,过滤所需查询的文档
.withRetrieveVector(false)
// 指定 Top K 的 K 值
.withLimit(3)
// 使用 filter 过滤数据
// .withFilter(new Filter(Filter.in("bookName", Arrays.asList("三国演义","西游记"))))
// 指定返回的 fields
.withOutputFields(Arrays.asList("chapterName", "lawText"))
.build();
SearchRes searchRes = collection.searchByEmbeddingItems(searchByEmbeddingItemsParam);
AtomicReference searchFlag = new AtomicReference(Boolean.FALSE);
if(Objects.equals(searchRes.getCode(),0) && CollectionUtils.isNotEmpty(searchRes.getDocuments())){
log.info("VectorTestController innerChatCompletionsV2 searchByEmbeddingItems -----------成功");
StringBuilder promptBuilder = new StringBuilder();
promptBuilder.append("提供的资料以\"...\"开头和结尾,请以提供的资料为参考进行问题的解答,如果提供的资料无法回答再根据用户实际问题进行谨慎回答。");
promptBuilder.append("...开始\n");
List<List<Document>> documentArray = searchRes.getDocuments();
documentArray.forEach(documents -> {
documents.forEach(document -> {
if(document.getScore() < msgDto.getScoreFlag()){
return;
}
document.getDocFields().forEach(docField -> {
promptBuilder.append(docField.getValue());
promptBuilder.append("\n");
searchFlag.set(Boolean.TRUE);
});
});
});
promptBuilder.append("...结束\n");
promptBuilder.append("用户问题\n:");
promptBuilder.append(prompt);
promptBuilder.append("\n");
if((Boolean)searchFlag.get()){
prompt = promptBuilder.toString();
}else {
prompt = "在保险行业中," + prompt;
}
}else {
prompt = "在保险行业中," + prompt;
log.info("VectorTestController innerChatCompletionsV2 searchByEmbeddingItems -----------失败,searchRes = {}, searchByEmbeddingItemsParam = {}", JsonUtil.getJsonString(searchRes),JsonUtil.getJsonString(searchByEmbeddingItemsParam));
}
log.info("innerChatCompletionsV2 sessionId = {}, msgDto = {}",sessionId,JsonUtil.getJsonString(msgDto));
LinkedList<MessageV2> msgLinkedList = SESSION_MSG_MAP.get(sessionId);
if(CollectionUtils.isEmpty(msgLinkedList)){
msgLinkedList = new LinkedList<>();
MessageV2 systemMessage = new MessageV2();
systemMessage.setRole("system");
String newSysMsg = sysMsgStr + "";
systemMessage.setContent(newSysMsg);
msgLinkedList.add(systemMessage);
MessageV2 userMessage = new MessageV2();
userMessage.setRole("user");
userMessage.setContent(prompt);
msgLinkedList.add(userMessage);
SESSION_MSG_MAP.put(sessionId,msgLinkedList);
}else{
MessageV2 userMessage = new MessageV2();
userMessage.setRole("user");
userMessage.setContent(prompt);
msgLinkedList.add(userMessage);
}
ChatCompletionBodyV2 body = new ChatCompletionBodyV2();
body.setLogit_bias(new HashMap<>());
body.setMessages(new ArrayList<>(msgLinkedList));
body.setModel(msgDto.getAiModel());
body.setN(1);
if(Objects.nonNull(msgDto.getTemperature())){
body.setTemperature(msgDto.getTemperature());
}else {
body.setTemperature(0.0);
}
if(Objects.nonNull(msgDto.getMaxTokens())){
body.setMax_tokens(msgDto.getMaxTokens());
}else {
body.setMax_tokens(300);
}
body.setStream(Boolean.FALSE);
// if (msgDto.getOutputJsonFlag()) {
// ResponseFormat responseFormat = new ResponseFormat();
// responseFormat.setType("json_object");
// body.setResponse_format(responseFormat);
// }
body.setTool_choice("auto");
List<Tool> toolList = new ArrayList<>(1);
Tool tool = new Tool();
toolList.add(tool);
tool.setType("function");
Tool.ToolFunction toolFunction = new Tool.ToolFunction();
toolFunction.setName("buyInsuranceProduct");
toolFunction.setDescription("向这个接口传入保险产品编码或者保险产品名称,可以获得该保险产品的下单链接以及相关宣传信息");
JSONObject jsonObject = new JSONObject();
toolFunction.setParameters(jsonObject);
jsonObject.put("type","object");
JSONObject propertiesObject = new JSONObject();
jsonObject.put("properties",propertiesObject);
jsonObject.put("required", new JSONArray(List.of("searchKey")));
JSONObject searchKeyParam = new JSONObject();
propertiesObject.put("searchKey",searchKeyParam);
searchKeyParam.put("type","string");
searchKeyParam.put("description","保险产品名称或者保险产品编码");
tool.setFunction(toolFunction);
body.setTools(toolList);
//构建GPT请求
ChatCompletionResponseV2 gptResponse = this.completionBuild(sessionId, msgDto.getAppCode(), body);
MsgResponseDto msgResponse = new MsgResponseDto();
if(Objects.nonNull(gptResponse)){
List<ChoiceV2> choices = gptResponse.getChoices();
for (ChoiceV2 choice : choices){
ChoiceV2.ResMessage message = choice.getMessage();
MessageV2 assistantMessage = new MessageV2();
assistantMessage.setRole(message.getRole());
if(StringUtils.isNotBlank(message.getContent())){
assistantMessage.setContent(message.getContent());
}
msgLinkedList.add(assistantMessage);
if(CollectionUtils.isNotEmpty(message.getTool_calls())){
List<ChoiceV2.ResToolCall> resToolCalls = message.getTool_calls();
List<MessageV2.ToolCall> toolCalls = new ArrayList<>(resToolCalls.size());
resToolCalls.forEach(callFunction -> {
MessageV2.Function function = callFunction.getFunction();
// assistantMessage.setName(function.getName());
// assistantMessage.setTool_call_id(callFunction.getId());
MessageV2.ToolCall toolCall = new MessageV2.ToolCall();
toolCall.setId(callFunction.getId());
toolCall.setType(callFunction.getType());
toolCall.setFunction(function);
toolCalls.add(toolCall);
});
assistantMessage.setTool_calls(toolCalls);
for(ChoiceV2.ResToolCall toolCall : resToolCalls){
MessageV2.Function function = toolCall.getFunction();
if(Objects.nonNull(function)
&& StringUtils.isNotBlank(function.getName())
&& StringUtils.isNotBlank(function.getArguments())){
String functionName = function.getName();
if(Objects.equals(functionName,"buyInsuranceProduct")){
String functionArguments = function.getArguments();
//arguments value :{"searchKey":"XXX医疗险(家庭版)"}
JSONObject param = JSONObject.parseObject(functionArguments);
String insuranceProductInfo = this.getInsuranceProductInfo(param.getString("searchKey"));
MessageV2 functionReqMessage = new MessageV2();
functionReqMessage.setRole("tool");
functionReqMessage.setContent(insuranceProductInfo);
functionReqMessage.setTool_call_id(toolCall.getId());
functionReqMessage.setName(functionName);
msgLinkedList.add(functionReqMessage);
}
}
}
body.setMessages(new ArrayList<>(msgLinkedList));
//构建GPT请求
ChatCompletionResponseV2 functionGptResponse = this.completionBuild(sessionId, msgDto.getAppCode(), body);
if(Objects.nonNull(functionGptResponse)){
gptResponse = functionGptResponse;
List<ChoiceV2> functionChoices = functionGptResponse.getChoices();
for (ChoiceV2 functionChoice : functionChoices){
ChoiceV2.ResMessage functionResMessage = functionChoice.getMessage();
MessageV2 functionAssistantResMessage = new MessageV2();
functionAssistantResMessage.setRole(functionResMessage.getRole());
functionAssistantResMessage.setContent(functionResMessage.getContent());
msgLinkedList.add(functionAssistantResMessage);
}
}else{
log.error("innerChatCompletionsV2 gptResponse value is null sessionId = {}, msgDto = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(msgDto),JsonUtil.getJsonString(gptResponse));
MessageV2 errorAssistantMessage = new MessageV2();
errorAssistantMessage.setRole("assistant");
errorAssistantMessage.setContent("信息好像丢失了,请更详细的描述您的要求并重试!");
msgLinkedList.add(errorAssistantMessage);
}
}
}
log.info("innerChatCompletionsV2 ResponseBody sessionId = {}, msgDto = {} , msgResponse = {}"
,sessionId,JsonUtil.getJsonString(msgDto),JsonUtil.getJsonString(msgResponse));
} else{
log.error("innerChatCompletionsV2 gptResponse value is null sessionId = {}, msgDto = {} , gptResponse = {}"
,sessionId,JsonUtil.getJsonString(msgDto),JsonUtil.getJsonString(gptResponse));
MessageV2 errorAssistantMessage = new MessageV2();
errorAssistantMessage.setRole("assistant");
errorAssistantMessage.setContent("信息好像丢失了,请更详细的描述您的要求并重试!");
msgLinkedList.add(errorAssistantMessage);
}
msgResponse.setRequestMsg(msgDto);
msgResponse.setSessionId(sessionId);
msgResponse.setMsgLinkedList(msgLinkedList);
msgResponse.setResponseMsg(gptResponse);
//保证顺序为 user|assistant 交替进行
MessageV2 last = msgLinkedList.getLast();
MessageV2 messageV2 = msgLinkedList.get(msgLinkedList.size() - 2);
if(Objects.equals(last.getRole(),"user") && Objects.equals(messageV2.getRole(),"assistant")){
msgLinkedList.removeLast();
}else if(Objects.equals(last.getRole(),"user") && Objects.equals(messageV2.getRole(),"system")){
msgLinkedList.removeLast();
}else if(Objects.equals(last.getRole(),"user") && Objects.equals(messageV2.getRole(),"function")){
msgLinkedList.removeLast();
}
log.info("innerChatCompletionsV2 SESSION_MSG_MAP = {}", JsonUtil.getJsonString(SESSION_MSG_MAP));
return ResponseUtil.makeSuccess(msgResponse);
}
4、获取产品信息
这里模拟得数查询数据库信息后续可进行替换
java
/**
* 获取产品下单信息
* @param productSearchKey 产品名称或者产品编码
* @return
*/
private String getInsuranceProductInfo(String productSearchKey){
log.info("innerChatCompletionsV2 getInsuranceProductInfo param,productSearchKey = {} ", productSearchKey);
JSONObject rbdjJsonObject = new JSONObject();
rbdjJsonObject.put("productName","xXX保意外险");
rbdjJsonObject.put("productDesc","这是xXX保意外险的产品描述");
rbdjJsonObject.put("productOrderUrl","www.baidu.com/XXX_XXYWX_XXYWX");
JSONObject ygrsJsonObject = new JSONObject();
ygrsJsonObject.put("productName","SDFSDF人寿SDFFD高端SDFSDF保险");
ygrsJsonObject.put("productDesc","这是SDFSDF人寿SDFFD高端SDFSDF保险的产品描述");
ygrsJsonObject.put("productOrderUrl","www.baidu.com/SDF_SDSDFrs_SDDFSFFSDFSDlbx");
JSONObject ygrszzJsonObject = new JSONObject();
ygrszzJsonObject.put("productName","阳光XSDSDSXX臻享XXDSDX高端XXSDSSDDX保险");
ygrszzJsonObject.put("productDesc","这是阳光XXDX臻享XXSDDX高端XSDSDXX保险的产品描述");
ygrszzJsonObject.put("productOrderUrl","www.baidu.com/XX_ygXXXs_zzSADSFADFgdylbx");
JSONObject lybJsonObject = new JSONObject();
lybJsonObject.put("productName","XXX·XX医疗险(XXX版)");
lybJsonObject.put("productDesc","这是XXX·XX医疗险(XXX版)的产品描述");
lybJsonObject.put("productOrderUrl","www.baidu.com/fXX_lXASDXXcqXXXSDFXlx_jXXtXXXb");
JSONObject sdhsjJsonObject = new JSONObject();
sdhsjJsonObject.put("productName","XXX护身甲XXX意外险");
sdhsjJsonObject.put("productDesc","这是XASDXX护身甲XXASX意外险的产品描述");
sdhsjJsonObject.put("productOrderUrl","www.baidu.com/zXXXDSAXx_XDASXhsXFDGjXXX");
JSONArray array = new JSONArray();
array.add(rbdjJsonObject);
array.add(ygrsJsonObject);
array.add(ygrszzJsonObject);
array.add(lybJsonObject);
array.add(sdhsjJsonObject);
log.info("innerChatCompletionsV2 getInsuranceProductInfo result,array = {} ", array);
return array.toString();
}
5、返回的消息体
相关GPT的请求类和消息体类请自己根据官方文档进行包装,这里没有进行包装。
java
/**
* @author chao
* @date 2024/3/14
**/
@Getter
@Setter
@Accessors(chain = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class MsgResponseDto {
/**
* 传入的消息体
*/
private MsgDto requestMsg;
/**
* 返回的内容-
*/
private ChatCompletionResponseV2 responseMsg;
/**
* 生成或者传入的消息体ID
*/
private String sessionId;
/**
* 目前该SessionId下存储的消息内容
*/
private LinkedList<MessageV2> msgLinkedList;
}