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

2024-03-22 18:12

本文主要是介绍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;
}

这篇关于GPT+向量数据库+Function calling=垂直领域小助手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/835886

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

DM8数据库安装后配置

1 前言 在上篇文章中,我们已经成功将库装好。在安装完成后,为了能够更好地满足应用需求和保障系统的安全稳定运行,通常需要进行一些基本的配置。下面是一些常见的配置项: 数据库服务注册:默认包含14个功能模块,将这些模块注册成服务后,可以更好的启动和管理这些功能;基本的实例参数配置:契合应用场景和发挥系统的最大性能;备份:有备无患;… 2 注册实例服务 注册了实例服务后,可以使用系统服务管理,

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训