GPT+向量数据库+Function calling=垂直领域小助手

引言

将 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依赖

<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和相关账户请替换成自己的


/*** 链接信息*/private static VectorDBClient CLIENT = null;/*** 存放消息体的地方-模拟数据库,因为是DEMO所以没有接数据库只在自己内存用一下*/private static Map<String, LinkedList<MessageV2>> SESSION_MSG_MAP = new HashMap<>(10);/*** 获取腾讯云client信息* @return client*/@PostConstructprivate 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、创建腾讯云数据库

/*** 创建腾讯云数据库* @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、向指定数据库和分区构建初始化数据

/*** 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);}

清除指定构建的数据

/*** 清空指定集合* @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交互接口的请求体

/*** @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的请求类和消息体类请自己根据官方文档进行包装,这里没有进行包装。

/*** 构建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交互接口

    /*** 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)){//唯一串生成代码,请替换成自己的或使用UUIDsessionId = 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、获取产品信息
这里模拟得数查询数据库信息后续可进行替换

    /*** 获取产品下单信息* @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的请求类和消息体类请自己根据官方文档进行包装,这里没有进行包装。

/*** @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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/764760.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习 zustand

学习 zustand https://github.com/pmndrs/zustand告别繁杂的状态管理&#xff1a;Zustand 的简洁之道Zustand 状态库&#xff1a;轻便、简洁、强大的 React 状态管理工具关于 zustand 的一些最佳实践 代码库 https://gitee.com/nian_zuo_chen/learnrect/tree/master/zustand 安…

【3DsMax】展UV记录

目录 一、概念 二、边的颜色 三、UV的连续性 四、合理的划分UV接缝 五、总结 一、概念 展uv的概念可以理解为把三维的模型铺平展成一个平面&#xff0c;然后在这个平面上去绘制图案。 二、边的颜色 我们先创建一个长方体&#xff0c;然后在修改器列表中添加“UVW展开”…

探索未来的编程趋势与挑战

摘要&#xff1a; 本文将探讨未来编程领域可能面临的挑战和发展趋势&#xff0c;包括人工智能、量子计算、区块链等新兴技术对编程的影响&#xff0c;以及程序员需要具备的新技能和素质。 随着人工智能技术的快速发展&#xff0c;机器学习、深度学习等算法在编程领域的应用越来…

数据透视进阶:切片器关联与二次计算

切片器 右键切片器--选择报表连接 将想要连接的表关联在切片器 二次计算

工具类|将Entity对象转为Vo/Bo对象,并指定字段绑定

工具类|将Entity对象转为Vo/Bo对象&#xff0c;并指定字段绑定 实体类&#xff1a;People和Student,Student的三个字段和People意义一样&#xff0c;但是字段名不完全一样&#xff0c;要实现对象拷贝可使用如下工具类&#xff0c;用到了反射。 People.java Data AllArgsConst…

Vue3 组件之间的通信

一、父子通信 ① props 父传子&#xff08;这种传值方法是只读的&#xff0c;不可以进行修改。&#xff09; 父组件props.vue中 <template><h2>props:我是父组件</h2><hr><props-child msg"我是静态的数据" :num"num" :obj&…

Qt实现TFTP Server和 TFTP Client(一)

1 概述 TFTP协议是基于UDP的简单文件传输协议&#xff0c;协议双方为Client和Server.Client和Server之间通过5种消息来传输文件,消息前两个字节Code是消息类型&#xff0c;消息内容随消息类型不同而不同。传输模式有三种&#xff1a;octet,netascii和mail&#xff0c;octet为二…

Flask 与小程序 的图片数据交互 过程及探讨研究学习

今天不知道怎么的&#xff0c;之前拿编程浪子地作品抄过来粘上用好好的&#xff0c;昨天开始照片突的就不显示了。 今天不妨再耐味地细细探究一下微信小程序wxml 和flask服务器端是怎么jpg图片数据交互的。 mina/pages/food/index.wxml <!--index.wxml--> <!--1px …

上位机图像处理和嵌入式模块部署(qmacvisual图像识别)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 所谓图像识别&#xff0c;就是对图像进行分类处理&#xff0c;比如说判断图像上面的物体是飞机、还是蝴蝶。在深度学习和卷积神经网络CNN不像现在这…

leetcode热题100.移动零

前言 作者&#xff1a;晓宜 &#x1f308;&#x1f308;&#x1f308; 个人简介&#xff1a;互联网大厂Java准入职&#xff0c;阿里云专家博主&#xff0c;csdn后端优质创作者&#xff0c;算法爱好者&#xff0c;github忠实用户 &#x1f319;&#x1f319;&#x1f319; 今天给…

暴力快速入门强化学习

强化学习算法的基本思想&#xff08;直觉&#xff09; 众所周知&#xff0c;强化学习是能让智能体实现某个具体任务的强大算法。 强化学习的基本思想是让智能体跟环境交互&#xff0c;通过环境的反馈让智能体调整自己的策略&#xff0c;从反馈中学习&#xff0c;不断学习来得到…

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期&#xff0c;OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮&#xff0c;推出了创新的文本转视频模型——Sora&#xff0c;Sora 可以创建长达60 秒的视频&#xff0c;包含高度详细的场景、複杂的摄像机运动以及情感丰富角色&#xff0c;再次将AI 的…

6-190 先序输出叶节点

本题要求按照先序遍历的顺序输出给定二叉树的叶结点。 函数接口定义: void PreorderPrintLeaves( BiTree BT ); 函数PreorderPrintLeaves应按照先序遍历的顺序输出给定二叉树BT的叶结点,格式为一个字符跟着一个空格。 裁判测试程序样例: #include<stdio.h> #inc…

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区&#xff0c;能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型&#xff08;使用lora-scripts&#xff09;-CSDN博客文章浏览阅读1.1k次…

怿星科技Neptune CHT-S测试系统,让智能座舱测试更加高效便捷

随着汽车“智能化”浪潮的推进&#xff0c;汽车的智能化水平正在持续刷新行业认知。在这股智能化潮流中&#xff0c;智能座舱作为客户体验最为直观的部分&#xff0c;其重要性不言而喻。倘若座舱设备出现死机、黑屏、卡顿等现象&#xff0c;都将对客户的使用体验产生非常大的影…

ChatGPT无法登录,提示我们检测到可疑的登录行为?如何解决?

OnlyFans 订阅教程移步&#xff1a;【保姆级】2024年最新Onlyfans订阅教程 Midjourney 订阅教程移步&#xff1a; 【一看就会】五分钟完成MidJourney订阅 GPT-4.0 升级教程移步&#xff1a;五分钟开通GPT4.0 如果你需要使用Wildcard开通GPT4、Midjourney或是Onlyfans的话&am…

c语言--内存函数的使用(memcpy、memcmp、memset、memmove)

目录 一、memcpy()1.1声明1.2参数1.3返回值1.4memcpy的使用1.5memcpy模拟使用1.6注意 二、memmove()2.1声明2.2参数2.3返回值2.4使用2.5memmove&#xff08;&#xff09;模拟实现 三、memset3.1声明3.2参数3.3返回值3.4使用 四、memcmp()4.1声明4.2参数4.3返回值4.4使用 五、注…

【python】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

文章目录 一、遇到的问题&#xff1a;jupyter notebook网页不自动跳出&#xff08;一&#xff09;输入jupyter notebook命令&#xff08;二&#xff09;手动打开网页 二、解决办法&#xff1a;指定浏览器&#xff08;一&#xff09;找文件 jupyter_notebook_config.py&#xff…

设计模式,简单工厂模式

23种设计模式是基于面向对象的一些编程逻辑思想&#xff0c;无意间看了看《大话设计模式》&#xff0c;我觉得还挺好玩&#xff0c;虽然设计模式我这个阶段确实可以不着急学&#xff0c;但我觉得这些内容挺吸引我的&#xff0c;反正时间也还多&#xff0c;就学着玩玩。而且设计…

Flink 架构深度解析

## 1. 引言 在当今的数据驱动世界中&#xff0c;实时数据处理变得越来越重要。Flink 提供了一个高性能、可扩展的平台&#xff0c;用于构建实时数据分析和处理应用。它支持事件时间处理和精确一次&#xff08;exactly-once&#xff09;处理语义&#xff0c;确保数据的准确性和…