From 324590681208fe68b7afe8694b87d224ed30a95e Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 23 Apr 2024 10:30:17 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../supervision/controller/AskController.java | 23 +++++++- .../handler/gpt/AnswerQuestionHandler.java | 58 +++++-------------- .../service/impl/AskServiceImpl.java | 18 +++--- .../com/supervision/vo/SingleTalkReqVO.java | 2 + 4 files changed, 48 insertions(+), 53 deletions(-) diff --git a/kbqa-graph/src/main/java/com/supervision/controller/AskController.java b/kbqa-graph/src/main/java/com/supervision/controller/AskController.java index dd4c740..1886ea8 100644 --- a/kbqa-graph/src/main/java/com/supervision/controller/AskController.java +++ b/kbqa-graph/src/main/java/com/supervision/controller/AskController.java @@ -1,17 +1,25 @@ package com.supervision.controller; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.supervision.dto.roundAsk.SessionParamDTO; import com.supervision.exception.BusinessException; import com.supervision.service.AskService; import com.supervision.vo.*; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Set; +import static com.supervision.service.impl.AskServiceImpl.SESSION_PARAM; + @Slf4j @RestController @RequestMapping("ask") @@ -20,13 +28,26 @@ public class AskController { private final AskService askService; + private final RedisTemplate redisTemplate; + @ApiOperation("多轮对话") @PostMapping("roundTalk") public RoundTalkResVO roundTalk(@RequestBody RoundTalkReqVO roundTalkReqVO) { if (StrUtil.isBlank(roundTalkReqVO.getSessionId())) { throw new BusinessException("会话ID不能为空"); } - return askService.roundTalk(roundTalkReqVO); + try { + return askService.roundTalk(roundTalkReqVO); + } catch (Exception e) { + log.info("多轮对话过程中出现了异常,则说明多轮对话走不通,那么就根据sessionId获取Redis中的原始问题,直接走单轮对话"); + // 如果多轮对话过程中出现了异常,则说明多轮对话走不通,那么就根据sessionId获取Redis中的原始问题,直接走单轮对话 + Object cache = redisTemplate.opsForValue().get(SESSION_PARAM + roundTalkReqVO.getSessionId()); + SessionParamDTO sessionParamDTO = BeanUtil.toBean(cache, SessionParamDTO.class); + SingleTalkResVO singleTalkResVO = askService.singleTalk(SingleTalkReqVO.builder().userTalk(sessionParamDTO.getOriginalQuestion()).build()); + return RoundTalkResVO.builder().sessionId(roundTalkReqVO.getSessionId()) + .answerText(singleTalkResVO.getAnswerText()).build(); + } + } @ApiOperation("单轮对话") diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/AnswerQuestionHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/AnswerQuestionHandler.java index 6811a59..d90dbba 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/AnswerQuestionHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/AnswerQuestionHandler.java @@ -17,50 +17,22 @@ import java.util.Map; public class AnswerQuestionHandler { public String answerQuestion(String question, List detailList, Map talkRecord) { - List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("system", "现在你是一个政务事项领域的问答大模型.\n" + - "现在有一个问题,根据这个问题我查到了政策内容,并提供了用户问询过程中的对话记录,可供参考;\n" + - "请你严格根据政策内容回答这个问题,请不要有文件内容之外的内容")); - messageList.add(new MessageDTO("assistant", "好的")); - messageList.add(new MessageDTO("user", StrUtil.format("政务文件内容:[{}]", CollUtil.join(detailList, ";")))); - messageList.add(new MessageDTO("assistant", "继续")); - messageList.add(new MessageDTO("user", StrUtil.format("问题:{}", question))); - messageList.add(new MessageDTO("assistant", "继续")); - if (CollUtil.isNotEmpty(talkRecord)) { - List record = new ArrayList<>(); - for (Map.Entry entry : talkRecord.entrySet()) { - record.add("询问用户:" + entry.getKey()); - record.add("用户回答:" + entry.getValue()); - } - messageList.add(new MessageDTO("user", "下面是用户回答过程中的对话记录,可供参考,并提供更精确的回答:{" + CollUtil.join(record, ";") + "}")); - messageList.add(new MessageDTO("assistant", "继续")); + String template = "作为AI助手,你的任务是帮助用户查找和理解特定政务的政策内容并给于用户答案。在这个场景中,你将使用政策内容来回答用户问题:{}。请根据政策内容\n" + + "\"\"\"{}\"\"\"\n" + + "同时,有一个和用户的问答过程的记录供你参考以提供更精确的回答,内容是:" + + "\"\"\"{}\"\"\"\n" + + "请用不超过 100 个词的长度准确和详细的回答用户的问题。"; + String askRecordTemplate = "问:{}\n 用户答:{};\n"; + StringBuilder askRecord = new StringBuilder(); + for (Map.Entry entry : talkRecord.entrySet()) { + askRecord.append(StrUtil.format(askRecordTemplate, entry.getKey(), entry.getValue())); } - messageList.add(new MessageDTO("user", StrUtil.format("现在你可以回答了,如果你从文件内容中,没有提取到回答,你就回复:我暂时还不会这个问题哦!"))); - log.info("answerQuestion的prompt是:{}", JSONUtil.toJsonStr(messageList)); - String answer = AiUtil.chatByMessage(messageList); - log.info("answerQuestion的答案是:{}", answer); - return answer; - } - - /** - * 回答单轮对话问题 - * - * @return 单轮对话问题的答案 - */ - public String answerSingleQuestion(String question, Map> detailMap) { List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("system", "现在你是一个政务事项领域的问答大模型.\n" + - "现在有一个问题,根据这个问题我查到了一些政策内容\n" + - "请你对该政策内容进行解读后,将这个问题进行回答.但是注意不要有文件内容之外的政策内容解读")); - messageList.add(new MessageDTO("assistant", "好的")); - messageList.add(new MessageDTO("user", StrUtil.format("政务文件内容:[{}]", JSONUtil.toJsonStr(detailMap)))); - messageList.add(new MessageDTO("assistant", "继续")); - messageList.add(new MessageDTO("user", StrUtil.format("问题:{}", question))); - messageList.add(new MessageDTO("assistant", "继续")); - messageList.add(new MessageDTO("user", StrUtil.format("现在你可以回答了,请用100字以内进行回答.如果你从文件内容中,没有提取到回答,你就回复:我暂时还不会这个问题哦!"))); - log.info("answerQuestion的prompt是:{}", JSONUtil.toJsonStr(messageList)); + messageList.add(new MessageDTO("user", StrUtil.format(template, question, JSONUtil.toJsonStr(detailList), askRecord.toString()))); + + log.info("多轮问答answerQuestion的prompt是:{}", JSONUtil.toJsonStr(messageList)); String answer = AiUtil.chatByMessage(messageList); - log.info("answerQuestion的答案是:{}", answer); + log.info("多轮问答answerQuestion的答案是:{}", answer); return answer; } @@ -74,9 +46,9 @@ public class AnswerQuestionHandler { List messageList = new ArrayList<>(); messageList.add(new MessageDTO("user", StrUtil.format(template, question, JSONUtil.toJsonStr(detailMap)))); - log.info("answerQuestion的prompt是:{}", JSONUtil.toJsonStr(messageList)); + log.info("单轮问答answerQuestion的prompt是:{}", JSONUtil.toJsonStr(messageList)); String answer = AiUtil.chatByMessage(messageList); - log.info("answerQuestion的答案是:{}", answer); + log.info("单轮问答answerQuestion的答案是:{}", answer); return answer; } } diff --git a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java index a5b5a04..240732e 100644 --- a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java +++ b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java @@ -55,9 +55,9 @@ public class AskServiceImpl implements AskService { private final AnswerQuestionHandler answerQuestionHandler; - private static final String SESSION_PARAM = "KBQA:ASK:SESSION_PARAM:"; + public static final String SESSION_PARAM = "KBQA:ASK:SESSION_PARAM:"; - private static final String USER_PARAM = "KBQA:ASK:USER_ROLE:"; + public static final String USER_PARAM = "KBQA:ASK:USER_ROLE:"; /** @@ -91,13 +91,13 @@ public class AskServiceImpl implements AskService { // 识别出来意图之后,再去判断是否识别过实体 if (CollUtil.isEmpty(sessionParamDTO.getEntityValueByExtract())) { // 识别实体(先从图中获取所有的节点名称,然后识别) - // List allItemNode = findItemNodeHandler.findAllItemNode(); - //List extractValue = itemExtractHandler.itemExtractByPossibleItem(sessionParamDTO.getOriginalQuestion(), allItemNode); + List allItemNode = findItemNodeHandler.findAllItemNode(); + List extractValue = itemExtractHandler.itemExtractByPossibleItemWithExample(sessionParamDTO.getOriginalQuestion(), allItemNode); // 识别问题中,用户可能问的业务是什么 - String extractValue = itemExtractHandler.itemExtractBusiness(sessionParamDTO.getOriginalQuestion()); - sessionParamDTO.setEntityValueByExtract(Collections.singletonList(extractValue)); +// String extractValue = itemExtractHandler.itemExtractBusiness(sessionParamDTO.getOriginalQuestion()); + sessionParamDTO.setEntityValueByExtract(extractValue); // 根据提取的内容,开始在知识图谱中寻找节点(首先找叶子节点,如果叶子节点有数据,直接返回,如果叶子节点没数据,再去找分支节点) - List allMatchLeafNode = findItemNodeHandler.findAllMatchLeafNode(Collections.singletonList(extractValue)); + List allMatchLeafNode = findItemNodeHandler.findAllMatchLeafNode(extractValue); // 如果找到的节点只有1个,那么说明问的就是这个节点,那么直接缓存起来进行下一步 if (allMatchLeafNode.size() == 1) { ItemLeaf itemLeaf = allMatchLeafNode.get(0); @@ -194,12 +194,12 @@ public class AskServiceImpl implements AskService { // 根据意图和节点,找到对应的结果 List itemDetail = findItemDetailHandler.findItemDetail(matchItemLeaf.getVid(), intentEnum.getTagType(), intentEnum.getEdgeType()); if (CollUtil.isEmpty(itemDetail)) { - return RoundTalkResVO.builder().sessionId(sessionParamDTO.getSessionId()).answerText("暂时还不会回答这个问题哦").build(); + throw new BusinessException("未找到意图,暂不支持回答"); } // 提交GPT,问问题的答案 String answer = answerQuestionHandler.answerQuestion(sessionParamDTO.getOriginalQuestion(), itemDetail, sessionParamDTO.getTalkRecord()); if (StrUtil.isBlank(answer)) { - return RoundTalkResVO.builder().sessionId(sessionParamDTO.getSessionId()).answerText("暂时还不会回答这个问题哦!").build(); + throw new BusinessException("未找到答案,暂不支持回答"); } // 清空问话实体 sessionParamDTO.setCurrentEntity(null); diff --git a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java index 7388d1a..e8bca32 100644 --- a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java +++ b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java @@ -1,8 +1,10 @@ package com.supervision.vo; +import lombok.Builder; import lombok.Data; @Data +@Builder public class SingleTalkReqVO { From 0c6a29ed559d20f94cbb541f81be4d80ff60d646 Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 23 Apr 2024 10:36:37 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/gpt/ConditionJudgeHandler.java | 48 ------------ .../handler/gpt/ItemExtractHandler.java | 77 +------------------ .../com/supervision/vo/SingleTalkReqVO.java | 4 + .../test/java/com/supervision/GlmTest.java | 47 ----------- 4 files changed, 5 insertions(+), 171 deletions(-) delete mode 100644 kbqa-graph/src/test/java/com/supervision/GlmTest.java diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ConditionJudgeHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ConditionJudgeHandler.java index 14bac7f..02fe9db 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ConditionJudgeHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ConditionJudgeHandler.java @@ -19,28 +19,6 @@ import java.util.*; @Component public class ConditionJudgeHandler { - /** - * 效果有些一般,但是也能勉强去用 - * - * @param question - * @param candidateAnswerList - * @param userAnswer - * @return - */ - public Set conditionJudge(String question, Collection candidateAnswerList, String userAnswer) { - List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("system", "现在要做社会保障业务分类,我现在给你一个问题,给你候选答案列表,请你根据用户的实际回答,从候选答案列表中给我选择对应的候选答案.除了候选答案,什么其他的都不要说.")); - messageList.add(new MessageDTO("assistant", "好的")); - messageList.add(new MessageDTO("user", StrUtil.format("问题:[{}]", question))); - messageList.add(new MessageDTO("assistant", "继续")); - messageList.add(new MessageDTO("user", StrUtil.format("候选答案列表:[{};未找到匹配答案]", StrUtil.join(";", candidateAnswerList)))); - messageList.add(new MessageDTO("assistant", "继续")); - messageList.add(new MessageDTO("user", StrUtil.format("用户答案:[{}],现在请给我所有匹配的候选答案.如果有多个候选答案,用;号分割.现在你可以回答了.", userAnswer))); - log.info("conditionJudge判断候选答案:{}", JSONUtil.toJsonStr(messageList)); - String judgeResult = AiUtil.chatByMessage(messageList); - log.info("conditionJudge判断结果是:{}", judgeResult); - return new HashSet<>(Arrays.asList(judgeResult.split(";"))); - } /** * 最新的判断方法,现在建议用搞这个 @@ -72,31 +50,5 @@ public class ConditionJudgeHandler { return result; } - /** - * 以循环的形式去判断条件是否满足 - * - * @param question 问题 - * @param candidateAnswerList 判断条件 - * @param userAnswer 用户回答 - */ - public Set newConditionJudge(String question, Collection candidateAnswerList, String userAnswer, String conditionType) { - Set judgeResultSet = new HashSet<>(); - String template = "当我问用户:{},用户给我的回答是:[{}],\n" + - "基于用户的回答,判断一下用户{}是否满足[{}]?满足就只回复true,反之只回复false"; - for (String candidateAnswer : candidateAnswerList) { - String judgeResult = StrUtil.format(template, question, userAnswer, conditionType, candidateAnswer); - String answer = AiUtil.chat(judgeResult); - log.info("conditionJudge判断条件:\n{},\n结果是:{}", judgeResult, answer); - try { - if (BooleanUtil.toBoolean(answer)) { - judgeResultSet.add(candidateAnswer); - } - } catch (Exception e) { - log.info("{}非布尔类型,不统计在内", answer); - } - - } - return judgeResultSet; - } } diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java index 0c1ae6a..0afe45b 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java @@ -18,50 +18,6 @@ import java.util.*; @Component public class ItemExtractHandler { - /** - * 直接从问题中提取事项 - * - * @param question 问题 - * @return 提取结果 - */ - @Deprecated - public String itemExtract(String question) { - List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("system", "假设你是一个命名实体识别模型且精通社保实体识别." + - "现在我会给你一个句子,请根据我的要求识别出句子中的实体数据在社保业务中属于哪一类业务事项,并给我事项名称,如果未找到事项,就回复:未找到;其他什么都不要说!")); - messageList.add(new MessageDTO("assistant", "好的")); - messageList.add(new MessageDTO("user", "句子是:" + question + ";请识别这句话中的社保业务事项.除了识别到的业务事项,其他什么都不要说")); - String item = AiUtil.chatByMessage(messageList); - if (StrUtil.equals("未找到", item)) { - throw new ItemExtractException("未从问题中找到事项"); - } - return item; - } - - /** - * 提供可能的意图之后,从问题中提取事项 - * - * @param question 问题 - * @return 提取结果 - */ - @Deprecated - public List itemExtractByPossibleItem(String question, List possible) { - String template = "请根据以下事项列表,从句子中识别并标注出对应的社保业务事项名称。若句子中不能直接对应到任何事项,就找可能性最高的事项。请确保只识别并标注一种可能性最高的社保业务事项。" + - "事项名称列表:\n" + - "{}" + - "句子是:{}"; - List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("user", StrUtil.format(template, CollUtil.join(possible, ";"), question))); - - log.info("itemExtractByPossibleItem查询语句为:{}", JSONUtil.toJsonStr(messageList)); - String item = AiUtil.chatByMessage(messageList); - log.info("itemExtractByPossibleItem结果为:{}", item); - if (StrUtil.equals("未找到", item)) { - throw new ItemExtractException("未从问题中找到事项"); - } - return Collections.singletonList(item); - } - /** * 提供示例的实体提取 * @@ -70,7 +26,7 @@ public class ItemExtractHandler { */ public List itemExtractByPossibleItemWithExample(String question, List possible) { String template = "请根据以下事项列表,从句子中识别并标注出对应的社保业务事项名称。若句子中不能直接对应到任何事项,就找可能性最高的事项。" + - "请确保只识别并标注一种可能性最高的社保业务事项。\n" + + "请确保只识别并标注一种可能性最高的社保业务事项。不要识别出事项列表之外的事项。\n" + "事项列表:{}\n" + "我现在有一些示例,可供你学习。\n" + "输入:企业职工多少岁可以退休?输出:企业职工退休\n" + @@ -101,37 +57,6 @@ public class ItemExtractHandler { } - @Deprecated - public String itemExtractBusiness(String question) { - List messageList = new ArrayList<>(); - messageList.add(new MessageDTO("user", "我现在是要进行实体抽取任务,并且精通社保业务,现在需要抽取[业务]这个实体类型的内容。\n" + - "\n" + - "下面是一些示例:\n" + - "\n" + - "输入:女性工人一般多少岁可以退休?\n" + - "输出:{\"business\":\"退休\"}\n" + - "输入:办理退休一般需要什么条件?\n" + - "输出:{\"business\":\"退休\"}\n" + - "输入:身份证挂失怎么办?\n" + - "输出:{\"business\":\"身份证挂失\"}\n" + - "输入:退休金没发,是什么原因?\n" + - "输出:{\"business\":\"退休金发放\"}\n" + - "\n" + - "现在有一句话,请进行抽取。\n" + - "输入:" + question + "\n" + - "输出:")); - log.info("itemExtractBusiness查询语句为:{}", JSONUtil.toJsonStr(messageList)); - String item = AiUtil.chatByMessage(messageList); - log.info("itemExtractBusiness查询结果为:{}", item); - boolean typeJSON = JSONUtil.isTypeJSON(item); - if (typeJSON) { - String business = JSONUtil.parseObj(item).getStr("business"); - if (StrUtil.isNotBlank(business)) { - return business; - } - } - throw new ItemExtractException("未从问题中找到业务事项"); - } } diff --git a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java index e8bca32..abcc89c 100644 --- a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java +++ b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java @@ -1,10 +1,14 @@ package com.supervision.vo; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public class SingleTalkReqVO { diff --git a/kbqa-graph/src/test/java/com/supervision/GlmTest.java b/kbqa-graph/src/test/java/com/supervision/GlmTest.java deleted file mode 100644 index 13b0fde..0000000 --- a/kbqa-graph/src/test/java/com/supervision/GlmTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.supervision; - -import cn.hutool.core.collection.CollUtil; -import com.supervision.handler.gpt.ConditionJudgeHandler; -import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import java.util.ArrayList; -import java.util.Set; - -@Slf4j -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@RunWith(SpringJUnit4ClassRunner.class) -public class GlmTest { - - @Autowired - private ConditionJudgeHandler conditionJudgeHandler; - - @Test - public void test() { - ArrayList strings = CollUtil.newArrayList("深圳户口", "广东省其他地区", "港澳台及外籍地区", "省外户口", "非深圳户口"); - - Set strings1 = conditionJudgeHandler.newConditionJudge("你的户口所在地是哪里?", strings, "我是汕头人", "户籍所在地"); - log.info("答案是: {}", CollUtil.join(strings1, ";")); - } - - @Test - public void test1() { - ArrayList strings = CollUtil.newArrayList("深圳户口", "广东省其他地区", "港澳台及外籍地区", "省外户口", "非深圳户口"); - - Set strings1 = conditionJudgeHandler.conditionJudge("你的户口所在地是哪里?", strings, "我是汕头人"); - log.info("答案是: {}", CollUtil.join(strings1, ";")); - } - - @Test - public void test2() { - ArrayList strings = CollUtil.newArrayList("大于60岁", "65岁以上", "年龄大于50周岁", "50岁以上"); - Set strings1 = conditionJudgeHandler.conditionJudgeAll("你的年龄多少岁?", strings, "我今天中午吃的酸菜鱼"); - log.info("答案是: {}", CollUtil.join(strings1, ";")); - } - - -} From cddcb8a298007aa082c57ff644c768af3a872ec9 Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 23 Apr 2024 11:07:32 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../supervision/handler/graph/FindItemDetailHandler.java | 6 +----- .../src/main/java/com/supervision/vo/SingleTalkReqVO.java | 1 - kbqa-graph/src/main/resources/application.yml | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/kbqa-graph/src/main/java/com/supervision/handler/graph/FindItemDetailHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/graph/FindItemDetailHandler.java index 6feaddc..ee74aea 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/graph/FindItemDetailHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/graph/FindItemDetailHandler.java @@ -17,10 +17,6 @@ public class FindItemDetailHandler { private CommonQueryDao commonQueryDao; public List findItemDetail(String itemVid, String itemType, String edgeType) { - List itemDetail = commonQueryDao.findItemDetail(itemVid, edgeType, itemType); - if (CollUtil.isEmpty(itemDetail)){ - throw new BusinessException("未找到事项信息"); - } - return itemDetail; + return commonQueryDao.findItemDetail(itemVid, edgeType, itemType); } } diff --git a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java index abcc89c..34734e9 100644 --- a/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java +++ b/kbqa-graph/src/main/java/com/supervision/vo/SingleTalkReqVO.java @@ -11,6 +11,5 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class SingleTalkReqVO { - private String userTalk; } diff --git a/kbqa-graph/src/main/resources/application.yml b/kbqa-graph/src/main/resources/application.yml index 01ef35b..5628966 100644 --- a/kbqa-graph/src/main/resources/application.yml +++ b/kbqa-graph/src/main/resources/application.yml @@ -99,7 +99,7 @@ cql: logging: level: - org.nebula.contrib: INFO + org.nebula.contrib: DEBUG youdao: qanthing: From 90297ad26a69d521bfc8ca2b06041af546c7c614 Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 23 Apr 2024 13:02:37 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BA=86=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E6=84=8F=E5=9B=BE=E8=AF=86=E5=88=AB=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../supervision/enums/IdentifyIntentEnum.java | 12 +++--- .../handler/gpt/IdentifyIntentHandler.java | 37 +++++++++++++++++++ .../handler/gpt/ItemExtractHandler.java | 2 +- .../service/impl/AskServiceImpl.java | 4 +- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/kbqa-graph/src/main/java/com/supervision/enums/IdentifyIntentEnum.java b/kbqa-graph/src/main/java/com/supervision/enums/IdentifyIntentEnum.java index 20a772c..3137196 100644 --- a/kbqa-graph/src/main/java/com/supervision/enums/IdentifyIntentEnum.java +++ b/kbqa-graph/src/main/java/com/supervision/enums/IdentifyIntentEnum.java @@ -6,12 +6,12 @@ import java.util.ArrayList; import java.util.List; public enum IdentifyIntentEnum { - 业务的受理条件("业务的受理条件", "process_condition", "process_condition_edge", CollUtil.newArrayList("可不可以XXX", "可以办理XX","能不能够XXX?","是否可以XXX?","XXX我符合条件吗?", "办理XXX满足条件吗?")), - 业务的办理流程("业务的办理流程", "handler_process", "handler_process_edge", CollUtil.newArrayList("办理[]事项的流程是什么样的?")), - 业务的材料清单("业务的材料清单", "checklist", "checklist_edge", CollUtil.newArrayList("需要提交哪些具体文件或材料?", "如果材料不齐全或不符合要求,将如何处理?")), - 业务的受理范围("业务的受理范围", "accept_scope", "accept_scope_edge", CollUtil.newArrayList("什么人才能办理XX业务?")), - 业务的办理途径("业务的办理途径", "handler_channel", "handler_channel_edge", CollUtil.newArrayList("有什么途径可以办理XX业务?","可以线上办理XX吗?","可以线下办理XX吗?")), - 业务的办理窗口("业务的办理窗口", "handler_place", "handler_place_edge", CollUtil.newArrayList("XX的办理窗口在哪里?","线下办理XX去哪里?")); + 业务的受理条件("业务的受理条件", "process_condition", "process_condition_edge", CollUtil.newArrayList("事项办理的要求或限制,例如,年龄,职业,缴费年限要求等")), + 业务的办理流程("业务的办理流程", "handler_process", "handler_process_edge", CollUtil.newArrayList("一般指办理事项的流程是什么?比如先后顺序等")), + 业务的材料清单("业务的材料清单", "checklist", "checklist_edge", CollUtil.newArrayList("询问办理事项需要登记的业务材料,如申领表;或办理事项需要的个人凭证,如身份证、户口本等")), + 业务的受理范围("业务的受理范围", "accept_scope", "accept_scope_edge", CollUtil.newArrayList("适用政策的人群范围,比如什么人群才能办理")), + 业务的办理途径("业务的办理途径", "handler_channel", "handler_channel_edge", CollUtil.newArrayList("一般指询问是否支持线上办理以及是否支持线下办理")), + 业务的办理窗口("业务的办理窗口", "handler_place", "handler_place_edge", CollUtil.newArrayList("线下办理具体地点,属性包括服务窗口名称,地点、电话、办理时间,位置指引")); private final String intent; diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java index 10703c5..2eb12d2 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java @@ -60,4 +60,41 @@ public class IdentifyIntentHandler { log.info("未识别,走了默认意图,业务的受理条件"); return IdentifyIntentEnum.业务的受理条件.getIntent(); } + + public String identifyIntentExample(String question) { + String template = "作为一个 AI 助手,你的任务是尝试识别出问题中的意图。现在我给你一些意图以及意图的说明\n" + + "\"\"\"\n" + + "{}"+ + "\"\"\"\n" + + "请帮我识别接下来这句话:【{}】可能数据上面的哪种意图?请直接给我意图名称,例如:事项的XXXX。意图范围只在示例中出现的,如果未在示例中出现,则选择示例中最相近的意图。"; + StringBuilder stringBuilder = new StringBuilder(); + for (IdentifyIntentEnum value : IdentifyIntentEnum.values()) { + stringBuilder.append("意图是:").append(value.getIntent()).append(";").append("说明是:").append(CollUtil.join(value.getExplainList(), ";")).append("\n"); + } + + // 首先生成提示词 + List messageList = new ArrayList<>(); + messageList.add(new MessageDTO("user", StrUtil.format(template,stringBuilder.toString(),question))); + log.info("identifyIntent开始识别意图:{}", JSONUtil.toJsonStr(messageList)); + // 进行提问 + String intent = AiUtil.chatByMessage(messageList); + log.info("identifyIntent意图识别结果为:{}", intent); + // 尝试转为JSON的形式 + if (StrUtil.isBlank(intent) || StrUtil.equals("未识别", intent) || intent.contains("未识别")) { + log.info("未识别,走了默认意图,业务的受理条件"); + return IdentifyIntentEnum.业务的受理条件.getIntent(); + // 如果没有识别,默认是业务的受理条件 + //throw new IdentifyIntentException("意图未识别"); + } + for (IdentifyIntentEnum value : IdentifyIntentEnum.values()) { + if (intent.contains(value.getIntent())){ + return value.getIntent(); + } + } +// throw new IdentifyIntentException("意图未识别"); + // 如果没有识别,默认是业务的受理条件 + log.info("未识别,走了默认意图,业务的受理条件"); + return IdentifyIntentEnum.业务的受理条件.getIntent(); + } + } diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java index 0afe45b..07cb3a3 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/ItemExtractHandler.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; import java.util.*; /** - * 意图提取Handler + * 实体提取Handler */ @Slf4j @Component diff --git a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java index 240732e..74367b0 100644 --- a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java +++ b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java @@ -84,7 +84,7 @@ public class AskServiceImpl implements AskService { } // 判断意图是否为空,如果意图为空,进行识别意图 if (StrUtil.isBlank(sessionParamDTO.getIntent())) { - String intent = identifyIntentHandler.identifyIntent(roundTalkReqVO.getUserTalk()); + String intent = identifyIntentHandler.identifyIntentExample(roundTalkReqVO.getUserTalk()); sessionParamDTO.setIntent(intent); redisTemplate.opsForValue().set(SESSION_PARAM + sessionId, sessionParamDTO); } @@ -317,7 +317,7 @@ public class AskServiceImpl implements AskService { @Override public SingleTalkResVO singleTalk(SingleTalkReqVO singleTalkReqVO) { // 单轮对话,直接根据用户的问题去找意图 - String intent = identifyIntentHandler.identifyIntent(singleTalkReqVO.getUserTalk()); + String intent = identifyIntentHandler.identifyIntentExample(singleTalkReqVO.getUserTalk()); // 根据用户的意图找到对应的节点 IdentifyIntentEnum intentEnum = IdentifyIntentEnum.getEnumByIntent(intent); if (ObjectUtil.isEmpty(intentEnum) || null == intentEnum) { From 84597e5a6df03e007ab89d5516e34a6df22025ab Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 23 Apr 2024 16:23:14 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/supervision/ai/AiUtil.java | 15 +- .../com/supervision/ai/dto/ChatReqDTO.java | 4 + .../handler/gpt/IdentifyIntentHandler.java | 12 +- .../service/impl/AskServiceImpl.java | 4 +- kbqa-graph/src/main/resources/application.yml | 2 +- nGQL/update_data.ngql | 159 +++++++++--------- 6 files changed, 89 insertions(+), 107 deletions(-) diff --git a/kbqa-graph/src/main/java/com/supervision/ai/AiUtil.java b/kbqa-graph/src/main/java/com/supervision/ai/AiUtil.java index cb09d05..f9390e6 100644 --- a/kbqa-graph/src/main/java/com/supervision/ai/AiUtil.java +++ b/kbqa-graph/src/main/java/com/supervision/ai/AiUtil.java @@ -53,20 +53,6 @@ public class AiUtil { } } - public static String chat(String message) { - ChatReqDTO chatReqDTO = new ChatReqDTO(); - chatReqDTO.setModel("glm-3-turbo"); - MessageDTO messageDTO = new MessageDTO(); - messageDTO.setRole("user"); - messageDTO.setContent(message); - chatReqDTO.setMessages(CollUtil.newArrayList(messageDTO)); - HttpResponse response = HttpRequest.post("https://open.bigmodel.cn/api/paas/v4/chat/completions") - .body(JSONUtil.toJsonStr(chatReqDTO)).header("Authorization", TOKEN).execute(); - String body = response.body(); - ChatResDTO bean = JSONUtil.toBean(body, ChatResDTO.class); - return bean.getChoices().stream().findFirst().orElseThrow(() -> new RuntimeException("获取政策文件失败")).getMessage().getContent(); - } - public static String chatByMessage(List messageList) { ChatReqDTO chatReqDTO = new ChatReqDTO(); chatReqDTO.setModel("glm-3-turbo"); @@ -75,6 +61,7 @@ public class AiUtil { try (HttpResponse response = HttpRequest.post("https://open.bigmodel.cn/api/paas/v4/chat/completions") .body(JSONUtil.toJsonStr(chatReqDTO)).header("Authorization", TOKEN).execute()) { body = response.body(); + log.info(body); } ChatResDTO bean = JSONUtil.toBean(body, ChatResDTO.class); return bean.getChoices().stream().findFirst().orElseThrow(() -> new RuntimeException("获取政策文件失败")).getMessage().getContent(); diff --git a/kbqa-graph/src/main/java/com/supervision/ai/dto/ChatReqDTO.java b/kbqa-graph/src/main/java/com/supervision/ai/dto/ChatReqDTO.java index e738faf..6bf78b1 100644 --- a/kbqa-graph/src/main/java/com/supervision/ai/dto/ChatReqDTO.java +++ b/kbqa-graph/src/main/java/com/supervision/ai/dto/ChatReqDTO.java @@ -9,5 +9,9 @@ public class ChatReqDTO { private String model; + private Boolean do_sample = true; + + private Float temperature = 0.01f; + private List messages; } diff --git a/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java b/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java index 2eb12d2..57cbfe9 100644 --- a/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java +++ b/kbqa-graph/src/main/java/com/supervision/handler/gpt/IdentifyIntentHandler.java @@ -66,7 +66,7 @@ public class IdentifyIntentHandler { "\"\"\"\n" + "{}"+ "\"\"\"\n" + - "请帮我识别接下来这句话:【{}】可能数据上面的哪种意图?请直接给我意图名称,例如:事项的XXXX。意图范围只在示例中出现的,如果未在示例中出现,则选择示例中最相近的意图。"; + "请帮我识别接下来这句话:【{}】可能数据上面的哪种意图?意图范围只在示例中出现的,如果未在示例中出现,则选择示例中最相近的意图。请直接给我意图名称,例:事项的XXXX"; StringBuilder stringBuilder = new StringBuilder(); for (IdentifyIntentEnum value : IdentifyIntentEnum.values()) { stringBuilder.append("意图是:").append(value.getIntent()).append(";").append("说明是:").append(CollUtil.join(value.getExplainList(), ";")).append("\n"); @@ -79,19 +79,15 @@ public class IdentifyIntentHandler { // 进行提问 String intent = AiUtil.chatByMessage(messageList); log.info("identifyIntent意图识别结果为:{}", intent); - // 尝试转为JSON的形式 - if (StrUtil.isBlank(intent) || StrUtil.equals("未识别", intent) || intent.contains("未识别")) { - log.info("未识别,走了默认意图,业务的受理条件"); - return IdentifyIntentEnum.业务的受理条件.getIntent(); - // 如果没有识别,默认是业务的受理条件 - //throw new IdentifyIntentException("意图未识别"); + // 大模型有可能回答:意图是:xxx,这时就需要进行截取 + if (intent.contains("意图是:")){ + intent = StrUtil.subAfter(intent,"意图是:",true); } for (IdentifyIntentEnum value : IdentifyIntentEnum.values()) { if (intent.contains(value.getIntent())){ return value.getIntent(); } } -// throw new IdentifyIntentException("意图未识别"); // 如果没有识别,默认是业务的受理条件 log.info("未识别,走了默认意图,业务的受理条件"); return IdentifyIntentEnum.业务的受理条件.getIntent(); diff --git a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java index 74367b0..9957e6b 100644 --- a/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java +++ b/kbqa-graph/src/main/java/com/supervision/service/impl/AskServiceImpl.java @@ -91,7 +91,7 @@ public class AskServiceImpl implements AskService { // 识别出来意图之后,再去判断是否识别过实体 if (CollUtil.isEmpty(sessionParamDTO.getEntityValueByExtract())) { // 识别实体(先从图中获取所有的节点名称,然后识别) - List allItemNode = findItemNodeHandler.findAllItemNode(); + List allItemNode = findItemNodeHandler.findAllItemNode(); List extractValue = itemExtractHandler.itemExtractByPossibleItemWithExample(sessionParamDTO.getOriginalQuestion(), allItemNode); // 识别问题中,用户可能问的业务是什么 // String extractValue = itemExtractHandler.itemExtractBusiness(sessionParamDTO.getOriginalQuestion()); @@ -327,7 +327,7 @@ public class AskServiceImpl implements AskService { List extractValue; try { extractValue = itemExtractHandler.itemExtractByPossibleItemWithExample(singleTalkReqVO.getUserTalk(), allItemNode); - }catch (ItemExtractException e){ + } catch (ItemExtractException e) { log.info("为提取到相关实体,暂时还不会回答这个问题"); return SingleTalkResVO.builder().answerText("您好,我暂时还不会回答这个问题哦!").build(); } diff --git a/kbqa-graph/src/main/resources/application.yml b/kbqa-graph/src/main/resources/application.yml index 5628966..01ef35b 100644 --- a/kbqa-graph/src/main/resources/application.yml +++ b/kbqa-graph/src/main/resources/application.yml @@ -99,7 +99,7 @@ cql: logging: level: - org.nebula.contrib: DEBUG + org.nebula.contrib: INFO youdao: qanthing: diff --git a/nGQL/update_data.ngql b/nGQL/update_data.ngql index d314ce8..ff75620 100644 --- a/nGQL/update_data.ngql +++ b/nGQL/update_data.ngql @@ -1,50 +1,44 @@ # 深圳城乡居民退休条件 -UPDATE VERTEX ON process_condition "1-1-1-1" SET detail = "城乡居民养老保险待遇领取条件参保人达到下列条件之一的,可以按月领取养老金。 - (一)当地实施原广东省新型农村社会养老保险 (以下简称新农保) 和城镇居民社会养老保险 (以下简称城居保) 制度时,已年满60周岁,未享受职工基本养老保险待遇以及国家规定的其他养老待遇的,不用缴费,可以按月领取基础养老金。 - (二) 参加了原新农保或城居保的参保人,按照其原参加制度的规定年限缴费,年满60周岁后,可以按月领取养老金。 - (三)参保人缴费案计达到15年,年满60周岁的,可以按月领取养老金。 - (四)参保人年满60周岁但案计缴费年限没有达到规定缴费年限的,可继实逐年缴费,并享受相应的政府缴费补贴。逐年缴费至65周岁仍然没有达到规定缴费年限的,可以一次性补缴养老保险费至规定的缴费年限后,按月领取养老金,但一次性补缴不享受政府的缴费补贴。 - (五)参保人年满60周岁、累计缴费年限没有达到规定缴费年限的,如不继续逐年缴费或补缴至规定的缴费年限的,不发基础养老金,可以申请按月领取个人账户养老金,发完为止。"; +UPDATE VERTEX ON process_condition "1-1-1-1" SET detail = "参保人达到下列条件之一的,可以按月领取养老金。\n +(一)当地实施原广东省新型农村社会养老保险(以下简称新农保)和城镇居民社会养老保险(以下简称城居保)制度时,已年满60周岁,未享受职工基本养老保险待遇以及国家规定的其他养老待遇的,不用缴费,可以按月领取基础养老金。\n +(二)参加了原新农保或城居保的参保人,按照其原参加制度的规定年限缴费,年满60周岁后,可以按月领取养老金。\n +(三)参保人缴费累计达到15年,年满60周岁的,可以按月领取养老金。\n +(四)参保人年满60周岁但累计缴费年限没有达到规定缴费年限的,可继续逐年缴费,并享受相应的政府缴费补贴。逐年缴费至65周岁仍然没有达到规定缴费年限的,可以一次性补缴养老保险费至规定的缴费年限后,按月领取养老金,但一次性补缴不享受政府的缴费补贴。\n +(五)参保人年满60周岁、累计缴费年限没有达到规定缴费年限的,如不继续逐年缴费或补缴至规定的缴费年限的,不发基础养老金,可以申请按月领取个人账户养老金,发完为止。"; # 港澳台和外籍人员城乡居民退休城乡居民退休条件 -UPDATE VERTEX ON process_condition "1-1-2-1" SET detail = "港澳台和外籍人员城乡居民退休城乡居民养老保险待遇领取条件参保人达到下列条件之一的,可以按月领取养老金 - (一)当地实施原广东省新型农村社会养老保险 (以下简称新农保)和城镇居民社会养老保险 (以下简称城居保) 制度时,已年满60周岁,未享受职工基本养老保险待遇以及国家规定的其他养老待遇的,不用缴费,可以按月领取基础养老金, - (二)参加了原新农保或城居保的参保人,按照其原参加制度的规定年限缴费,年满60周岁后,可以按月领取养老金 - (三)参保人缴费累计达到15年,年满60周岁的,可以按月领取养老金。 - (四)参保人年满60周岁但累计缴费年限没有达到规定缴费年限的,可继续逐年缴费,并享受相应的政府缴费补贴。逐年缴费至65周岁仍然没有达到规定缴费年限的,可以一次性补缴养老保险费至规定的缴费年限后,按月领取养老金,但一次性补缴不享受政府的缴费补贴。 - (五)参保人年满60周岁、累计缴费年限没有达到规定缴费年限的,如不继续逐年缴费或补缴至规定的缴费年限的,不发基础养老金,可以申请按月领取个人账户养老金,发完为止."; +UPDATE VERTEX ON process_condition "1-1-2-1" SET detail = "城乡居民养老保险待遇领取条件参保人达到下列条件之一的,可以按月领取养老金\n +(一)当地实施原广东省新型农村社会养老保险 (以下简称新农保)和城镇居民社会养老保险 (以下简称城居保) 制度时,已年满60周岁,未享受职工基本养老保险待遇以及国家规定的其他养老待遇的,不用缴费,可以按月领取基础养老金,\n +(二)参加了原新农保或城居保的参保人,按照其原参加制度的规定年限缴费,年满60周岁后,可以按月领取养老金\n +(三)参保人缴费累计达到15年,年满60周岁的,可以按月领取养老金。\n +(四)参保人年满60周岁但累计缴费年限没有达到规定缴费年限的,可继续逐年缴费,并享受相应的政府缴费补贴。逐年缴费至65周岁仍然没有达到规定缴费年限的,可以一次性补缴养老保险费至规定的缴费年限后,按月领取养老金,但一次性补缴不享受政府的缴费补贴。\n +(五)参保人年满60周岁、累计缴费年限没有达到规定缴费年限的,如不继续逐年缴费或补缴至规定的缴费年限的,不发基础养老金,可以申请按月领取个人账户养老金,发完为止."; # 深圳企业职工退休条件 -UPDATE VERTEX ON process_condition "1-2-1-1" SET detail = "如已达到退休年龄,且养老缴费年限满15年,且异地社保已转入,可以在深圳办理退休; - 如养老保险缴费未满15年 (实际缴费年限+视同缴费年限)则不满足退休条件;您可由请社保延缴或一次性趸缴:养老保险缴费年限满15年后,再办理退休申请。 - 如您还有异地社保没有转入的话,需要您先办理社保转入"; +UPDATE VERTEX ON process_condition "1-2-1-1" SET detail = "1.男年满60周岁,女干部(管理技术岗位)年满55周岁,女工人(生产操作岗位)年满50周岁。\n +2.参加基本养老保险的个人,达到法定退休年龄时累计缴费满15年的,可按月领取基本养老"; # 广东省其他地区企业职工退休条件 -UPDATE VERTEX ON process_condition "1-2-2-1" SET detail = "如已达到退休年龄,且养老缴费年限满15年,且异地社保已转入,可以在深圳办理退休; - 如养老保险缴费未满15年 (实际缴费年限+视同缴费年限)则不满足退休条件;您可由请社保延缴或一次性趸缴:养老保险缴费年限满15年后,再办理退休申请。 - 如您还有异地社保没有转入的话,需要您先办理社保转入"; +UPDATE VERTEX ON process_condition "1-2-2-1" SET detail = "1.男年满60周岁,女干部(管理技术岗位)年满55周岁,女工人(生产操作岗位)年满50周岁。\n +2.参加基本养老保险的个人,达到法定退休年龄时累计缴费满15年的,可按月领取基本养老"; # 省外户口企业职工退休条件 -UPDATE VERTEX ON process_condition "1-2-3-1" SET detail = "如已达到退休年龄,且养老缴费年限满15年,且异地社保已转入,可以在深圳办理退休; - 如养老保险缴费未满15年 (实际缴费年限+视同缴费年限)则不满足退休条件;您可由请社保延缴或一次性趸缴:养老保险缴费年限满15年后,再办理退休申请。 - 如您还有异地社保没有转入的话,需要您先办理社保转入"; +UPDATE VERTEX ON process_condition "1-2-3-1" SET detail = "1.男年满60周岁,女干部(管理技术岗位)年满55周岁,女工人(生产操作岗位)年满50周岁。\n +2.参加基本养老保险的个人,达到法定退休年龄时累计缴费满15年的,可按月领取基本养老"; # 港澳台和外籍人员企业职工退休条件 -UPDATE VERTEX ON process_condition "1-2-4-1" SET detail = "如已达到退休年龄,且养老缴费年限满15年,且异地社保已转入,可以在深圳办理退休; - 如养老保险缴费未满15年 (实际缴费年限+视同缴费年限)则不满足退休条件;您可由请社保延缴或一次性趸缴:养老保险缴费年限满15年后,再办理退休申请。 - 如您还有异地社保没有转入的话,需要您先办理社保转入"; +UPDATE VERTEX ON process_condition "1-2-4-1" SET detail = "1.男年满60周岁,女干部(管理技术岗位)年满55周岁,女工人(生产操作岗位)年满50周岁。\n +2.参加基本养老保险的个人,达到法定退休年龄时累计缴费满15年的,可按月领取基本养老"; -##############################深圳城乡居民退休条件##################################### +##############################深圳城乡居民退休##################################### -insert vertex `handler_process` ( `detail`) values "1-1-1-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明 - 2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。 - 3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); +# 办理流程 +insert vertex `handler_process` ( `detail`) values "1-1-1-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明\n +2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。\n +3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。\n"); # 插入叶子节点和办理流程节点之间的关系 insert edge `handler_process_edge`() values "1-1-1"->"1-1-1-2":(); # 材料清单 -insert vertex `checklist` ( `detail`) values "1-1-1-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件; - 2.居民身份证; - 3.申请人户口簿; - 4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); +insert vertex `checklist` ( `detail`) values "1-1-1-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件;2.居民身份证;3.申请人户口簿;4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); # 插入叶子节点和材料清单节点之间的关系 insert edge `checklist_edge`() values "1-1-1"->"1-1-1-3":(); @@ -56,36 +50,62 @@ insert vertex `accept_scope` ( `detail`) values "1-1-1-4":("自然人"); insert edge `accept_scope_edge`() values "1-1-1"->"1-1-1-4":(); # 办理途径 -insert vertex `handler_channel` ( `detail`) values "1-1-1-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务 - 2、窗口办理"); +insert vertex `handler_channel` ( `detail`) values "1-1-1-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); # 插入叶子节点和办理途径节点之间的关系 insert edge `handler_channel_edge`() values "1-1-1"->"1-1-1-4":(); # 办理窗口 -insert vertex `handler_place` ( `detail`) values "1-1-1-4":("办理地点:就近的社保经办机构。 - 办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); +insert vertex `handler_place` ( `detail`) values "1-1-1-4":("办理地点:就近的社保经办机构。\n办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); # 插入叶子节点和办理窗口节点之间的关系 insert edge `handler_place_edge`() values "1-1-1"->"1-1-1-4":(); +##############################港澳台和外籍人员城乡居民退休##################################### + +# 办理流程 +insert vertex `handler_process` ( `detail`) values "1-1-2-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明\n +2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。\n +3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。\n"); +# 插入叶子节点和办理流程节点之间的关系 +insert edge `handler_process_edge`() values "1-1-2"->"1-1-2-2":(); + +# 材料清单 +insert vertex `checklist` ( `detail`) values "1-1-2-3":("1、深圳市企业职工养老保险养老金申请表;2、港澳通行证或香港身份证;3、人事档案;4、授权委托书。"); + +# 插入叶子节点和材料清单节点之间的关系 +insert edge `checklist_edge`() values "1-1-2"->"1-1-2-3":(); + +# 受理范围 +insert vertex `accept_scope` ( `detail`) values "1-1-2-4":("港澳台和外籍人员"); + +# 插入叶子节点和受理范围节点之间的关系 +insert edge `accept_scope_edge`() values "1-1-2"->"1-1-2-4":(); + +# 办理途径 +insert vertex `handler_channel` ( `detail`) values "1-1-2-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); + +# 插入叶子节点和办理途径节点之间的关系 +insert edge `handler_channel_edge`() values "1-1-2"->"1-1-2-4":(); + +# 办理窗口 +insert vertex `handler_place` ( `detail`) values "1-1-2-4":("办理地点:就近的社保经办机构。\n办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); + +# 插入叶子节点和办理窗口节点之间的关系 +insert edge `handler_place_edge`() values "1-1-2"->"1-1-2-4":(); + ###########################深圳企业职工退休######################################## -insert vertex `handler_process` ( `detail`) values "1-2-1-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明 - 2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。 - 3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); +insert vertex `handler_process` ( `detail`) values "1-2-1-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明\n2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。\n3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); # 插入叶子节点和办理流程节点之间的关系 insert edge `handler_process_edge`() values "1-2-1"->"1-2-1-2":(); # 材料清单 -insert vertex `checklist` ( `detail`) values "1-2-1-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件; - 2.居民身份证; - 3.申请人户口簿; - 4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); +insert vertex `checklist` ( `detail`) values "1-2-1-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件;2.居民身份证;3.申请人户口簿;4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); # 插入叶子节点和材料清单节点之间的关系 insert edge `checklist_edge`() values "1-2-1"->"1-2-1-3":(); @@ -97,32 +117,25 @@ insert vertex `accept_scope` ( `detail`) values "1-2-1-4":("自然人"); insert edge `accept_scope_edge`() values "1-2-1"->"1-2-1-4":(); # 办理途径 -insert vertex `handler_channel` ( `detail`) values "1-2-1-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务 - 2、窗口办理"); +insert vertex `handler_channel` ( `detail`) values "1-2-1-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); # 插入叶子节点和办理途径节点之间的关系 insert edge `handler_channel_edge`() values "1-2-1"->"1-2-1-4":(); # 办理窗口 -insert vertex `handler_place` ( `detail`) values "1-2-1-4":("办理地点:就近的社保经办机构。 - 办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); +insert vertex `handler_place` ( `detail`) values "1-2-1-4":("办理地点:就近的社保经办机构。办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); # 插入叶子节点和办理窗口节点之间的关系 insert edge `handler_place_edge`() values "1-2-1"->"1-2-1-4":(); ###########################广东省其他地区企业职工退休######################################## -insert vertex `handler_process` ( `detail`) values "1-2-2-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明 - 2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。 - 3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); +insert vertex `handler_process` ( `detail`) values "1-2-2-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); # 插入叶子节点和办理流程节点之间的关系 insert edge `handler_process_edge`() values "1-2-2"->"1-2-2-2":(); # 材料清单 -insert vertex `checklist` ( `detail`) values "1-2-2-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件; - 2.居民身份证; - 3.申请人户口簿; - 4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); +insert vertex `checklist` ( `detail`) values "1-2-2-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件; 2.居民身份证;3.申请人户口簿;4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); # 插入叶子节点和材料清单节点之间的关系 insert edge `checklist_edge`() values "1-2-2"->"1-2-2-3":(); @@ -134,32 +147,25 @@ insert vertex `accept_scope` ( `detail`) values "1-2-2-4":("自然人"); insert edge `accept_scope_edge`() values "1-2-2"->"1-2-2-4":(); # 办理途径 -insert vertex `handler_channel` ( `detail`) values "1-2-2-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务 - 2、窗口办理"); +insert vertex `handler_channel` ( `detail`) values "1-2-2-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); # 插入叶子节点和办理途径节点之间的关系 insert edge `handler_channel_edge`() values "1-2-2"->"1-2-2-4":(); # 办理窗口 -insert vertex `handler_place` ( `detail`) values "1-2-2-4":("办理地点:就近的社保经办机构。 - 办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); +insert vertex `handler_place` ( `detail`) values "1-2-2-4":("办理地点:就近的社保经办机构。办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); # 插入叶子节点和办理窗口节点之间的关系 insert edge `handler_place_edge`() values "1-2-2"->"1-2-2-4":(); ###########################省外户口企业职工退休######################################## -insert vertex `handler_process` ( `detail`) values "1-2-3-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明 - 2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。 - 3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); +insert vertex `handler_process` ( `detail`) values "1-2-3-2":("1、参保人为干部身份且已申领失业保险金,办理女干部在工人岗位退休不需要提供离职证明2、达龄月台账未出:单位正常缴费、单位延缴、个人缴费、个人延缴等情况的缴费人员,可先正常申请办理退休。3、参保人档案如果通过机要转至我局的,由我局工作人员通知当事人前来办理退休手续。在退休员工签领《养老保险待遇决定书》的同时就可以领回员工档案材料。"); # 插入叶子节点和办理流程节点之间的关系 insert edge `handler_process_edge`() values "1-2-3"->"1-2-3-2":(); # 材料清单 -insert vertex `checklist` ( `detail`) values "1-2-3-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件; - 2.居民身份证; - 3.申请人户口簿; - 4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); +insert vertex `checklist` ( `detail`) values "1-2-3-3":("1.深圳市城乡居民养老保险养老金申请表(深圳)原件;2.居民身份证;3.申请人户口簿;4.深圳市养老保险业务办理委托书(深圳)原件(申请人委托他人代办的,应提供代办人身份证及授权委托书)。"); # 插入叶子节点和材料清单节点之间的关系 insert edge `checklist_edge`() values "1-2-3"->"1-2-3-3":(); @@ -171,34 +177,25 @@ insert vertex `accept_scope` ( `detail`) values "1-2-3-4":("自然人"); insert edge `accept_scope_edge`() values "1-2-3"->"1-2-3-4":(); # 办理途径 -insert vertex `handler_channel` ( `detail`) values "1-2-3-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务 - 2、窗口办理"); +insert vertex `handler_channel` ( `detail`) values "1-2-3-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); # 插入叶子节点和办理途径节点之间的关系 insert edge `handler_channel_edge`() values "1-2-3"->"1-2-3-4":(); # 办理窗口 -insert vertex `handler_place` ( `detail`) values "1-2-3-4":("办理地点:就近的社保经办机构。 - 办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); +insert vertex `handler_place` ( `detail`) values "1-2-3-4":("办理地点:就近的社保经办机构。办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); # 插入叶子节点和办理窗口节点之间的关系 insert edge `handler_place_edge`() values "1-2-3"->"1-2-3-4":(); ###########################港澳台和外籍人员企业职工退休######################################## -insert vertex `handler_process` ( `detail`) values "1-2-4-2":("1、深圳市企业职工养老保险养老金申请表; - 2、港澳通行证或香港身份证; - 3、人事档案; - 4、授权委托书。 - 办理地点:就近的社保经办机构。"); +insert vertex `handler_process` ( `detail`) values "1-2-4-2":("1、深圳市企业职工养老保险养老金申请表;2、港澳通行证或香港身份证;3、人事档案;4、授权委托书。办理地点:就近的社保经办机构。"); # 插入叶子节点和办理流程节点之间的关系 insert edge `handler_process_edge`() values "1-2-4"->"1-2-4-2":(); # 材料清单 -insert vertex `checklist` ( `detail`) values "1-2-4-3":("1、深圳市企业职工养老保险养老金申请表; - 2、港澳通行证或香港身份证; - 3、人事档案; - 4、授权委托书。"); +insert vertex `checklist` ( `detail`) values "1-2-4-3":("1、深圳市企业职工养老保险养老金申请表; 2、港澳通行证或香港身份证; 3、人事档案;4、授权委托书。"); # 插入叶子节点和材料清单节点之间的关系 insert edge `checklist_edge`() values "1-2-4"->"1-2-4-3":(); @@ -210,15 +207,13 @@ insert vertex `accept_scope` ( `detail`) values "1-2-4-4":("自然人"); insert edge `accept_scope_edge`() values "1-2-4"->"1-2-4-4":(); # 办理途径 -insert vertex `handler_channel` ( `detail`) values "1-2-4-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务 - 2、窗口办理"); +insert vertex `handler_channel` ( `detail`) values "1-2-4-4":("1、线上办理:养老待遇线上办理途径:关注“深圳社保”公众号-便民服务-个人业务办理-办事(查看更多)-养老业务-选择您需要办理的养老待遇业务2、窗口办理"); # 插入叶子节点和办理途径节点之间的关系 insert edge `handler_channel_edge`() values "1-2-4"->"1-2-4-4":(); # 办理窗口 -insert vertex `handler_place` ( `detail`) values "1-2-4-4":("办理地点:就近的社保经办机构。 - 办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); +insert vertex `handler_place` ( `detail`) values "1-2-4-4":("办理地点:就近的社保经办机构。办理时间:在员工达到待遇领取条件时当月的任一工作日到社会保险机构办理退休手续。"); # 插入叶子节点和办理窗口节点之间的关系 insert edge `handler_place_edge`() values "1-2-4"->"1-2-4-4":();