|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
package com.supervision.police.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import com.alibaba.druid.util.StringUtils;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
|
@ -116,6 +117,9 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<TripleInfo> getThreeInfo(String caseId, String name, String recordId) {
|
|
|
|
|
if (StrUtil.isBlank(recordId)){
|
|
|
|
|
throw new RuntimeException("笔录ID不能为空");
|
|
|
|
|
}
|
|
|
|
|
boolean taskStatus = taskExtractStatusCheck(caseId, recordId);
|
|
|
|
|
// 如果校验结果为false,则说明需要进行提取三元组操作
|
|
|
|
|
if (!taskStatus) {
|
|
|
|
@ -130,7 +134,8 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
*/
|
|
|
|
|
private boolean taskExtractStatusCheck(String caseId, String recordId) {
|
|
|
|
|
// 首先查询是否存在任务,如果不存在,就新建
|
|
|
|
|
Optional<CaseTaskRecord> caseTaskRecordOpt = caseTaskRecordService.lambdaQuery().eq(CaseTaskRecord::getType, 2).eq(CaseTaskRecord::getCaseId, caseId).eq(CaseTaskRecord::getRecordId, recordId).oneOpt();
|
|
|
|
|
Optional<CaseTaskRecord> caseTaskRecordOpt = caseTaskRecordService.lambdaQuery()
|
|
|
|
|
.eq(CaseTaskRecord::getType, 2).eq(CaseTaskRecord::getCaseId, caseId).eq(CaseTaskRecord::getRecordId, recordId).oneOpt();
|
|
|
|
|
if (caseTaskRecordOpt.isEmpty()) {
|
|
|
|
|
CaseTaskRecord newCaseTaskRecord = new CaseTaskRecord();
|
|
|
|
|
newCaseTaskRecord.setType(2);
|
|
|
|
@ -144,6 +149,13 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
|
|
|
|
|
// 如果存在,则校验时间是否已经超过1天,如果超过了1天还没有执行完毕,就重新提交这个任务
|
|
|
|
|
CaseTaskRecord caseTaskRecord = caseTaskRecordOpt.get();
|
|
|
|
|
// 如果未执行,则提交执行
|
|
|
|
|
if (caseTaskRecordOpt.get().getStatus() == 0) {
|
|
|
|
|
caseTaskRecord.setStatus(1);
|
|
|
|
|
caseTaskRecord.setSubmitTime(LocalDateTime.now());
|
|
|
|
|
caseTaskRecordService.updateById(caseTaskRecord);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (caseTaskRecordOpt.get().getStatus() == 1 && LocalDateTime.now().isAfter(caseTaskRecord.getSubmitTime().plusDays(1))) {
|
|
|
|
|
// 如果已经超过1天,则重新提交任务
|
|
|
|
|
caseTaskRecord.setStatus(1);
|
|
|
|
@ -151,6 +163,7 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
caseTaskRecordService.updateById(caseTaskRecord);
|
|
|
|
|
return false;
|
|
|
|
|
} else if (caseTaskRecordOpt.get().getStatus() == 2) {
|
|
|
|
|
// 如果执行成功,就返回true,取反之后就可以返回三元组信息了
|
|
|
|
|
return true;
|
|
|
|
|
} else if (caseTaskRecordOpt.get().getStatus() == 3) {
|
|
|
|
|
caseTaskRecord.setStatus(1);
|
|
|
|
@ -167,19 +180,100 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void testExtractThreeInfo() {
|
|
|
|
|
// -------------------------
|
|
|
|
|
// DEMO_0:山东团队的版本,每次提取多个三元组,经过测试,提取质量较差,基本无法正常提取.需要改成每次提取一个,进行TEST_DEMO_1尝试
|
|
|
|
|
// 请分析以下内容中所有规定的三元组信息并补充完整,
|
|
|
|
|
// 要求:1.返回式:
|
|
|
|
|
// {result:
|
|
|
|
|
// [
|
|
|
|
|
// {startNodeType:'LawActor',entity:'',endNodeType:'FictionalOrgan',property:'',value:'冒充' },
|
|
|
|
|
// {startNodeType:'LawActor',entity:'',endNodeType:'Seal',property:'',value:'伪造'},
|
|
|
|
|
// {startNodeType:'LawActor',entity:'',endNodeType:'BusinessLicense',property:'',value:'伪造'}
|
|
|
|
|
// ]
|
|
|
|
|
// }。
|
|
|
|
|
// 2.必须考虑上下文语境分析。
|
|
|
|
|
// 3.对话中不包含此类型三元组则返回{ "result": [] }。
|
|
|
|
|
// 例子1:办案警官问:你为了骗取更多的钱都做了哪些准备?裴金禄回答:我刚开始我就是自己想了一些关于骗钱的点子,后面为了更不容易让别人识破我为了更佳逼真,我就从网上随便搜了一家租赁公司,我就搜到了兰州胜利机械租赁有限公司,被讯问人:裴金禄我又想到了我管理的中铁北京局和中铁电气化局施工公司。我先是通过百度搜索了“办证”之后就在网页上面弹出了一个页面上面有一个QQ号,我就加上了。加上之后我就将我的要求给他说了,要求他给我刻两个假的公章,一个是兰州胜利机械租赁有限公司合同专用章,另一个是中铁北京局集团有限公司合同专用章。我还要求他给我伪造了一张兰州胜利机械租赁有限公司的营业执照。
|
|
|
|
|
// 回答:{"result":[{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"FictionalOrgan","property":"兰州胜利机械租赁有限公司","value":"冒充"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"兰州胜利机械租赁有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"中铁北京局集团有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"BusinessLicense","property":"兰州胜利机械租赁有限公司营业执照","value":"伪造"}]}。
|
|
|
|
|
// 例子2:办案警官问:你为什么要在中卫市沙坡头区签订这些合同?裴金禄回答:因为我在这边上班,我在中卫市沙坡头区签订合同更能有说服力,这样才能更好地骗到钱。回答:{ "result": [] }。
|
|
|
|
|
|
|
|
|
|
// -------------------------
|
|
|
|
|
// TEST_DEMO_1:结果:效果较差,容易出现混淆,会把例子中的实体给返回出来.如果提取不到,会把定义的关系返回出来,所以不行.PASS
|
|
|
|
|
// 请从
|
|
|
|
|
// ---
|
|
|
|
|
// 办案警官问:你是如何想到这个方法骗钱的? 裴金禄回答:因为我是在中卫市沙坡头区中兰铁路上做监理人员,我这样说的话别人会更容易相信。
|
|
|
|
|
// ---
|
|
|
|
|
// 这段话中按(主体类型:行为人姓名;关系:伪造;客体类型:合同名称)提取特定的三元组信息。
|
|
|
|
|
// 如果未提取到或关系不匹配或客体类型不匹配,则返回空的json即可。
|
|
|
|
|
// 如果可以提取到三元组关系,则返回格式为{"主体":"主体名称","关系":"关系名称","客体":"客体名称"}。
|
|
|
|
|
// 例如‘办案警官问:描述一下事情的经过。行为人小明答:我做了一份假的租车合同,然后骗小刚签了这个合同’,该示例存在给定的三元组关系.则结果为:{"主体":"小明","关系":"伪造","客体":"租车合同"}。
|
|
|
|
|
// 例如‘办案警官问:办案警官问:讲一下那个软件的名称?小明回答:现在叫畅聊。‘该示例不存在给定的三元组关系,则结果为:{}
|
|
|
|
|
// 请保证提取准确且完整,主体和客体要具体明确,不能是宽泛的概念。提取的客体要必须属于客体类型!
|
|
|
|
|
// -------------------------
|
|
|
|
|
// TEST_DEMO_2:结果:有一些结果可以,但总体正确率较低,问题:不能有效的对给定的三元组进行提取,会出现给定三元组关系之外的三元组.会出现文章中不存在的三元组或错误的三元组
|
|
|
|
|
// 三元组提取任务:从给定对话中根据给定实体类型和关系提取对应的三元组。
|
|
|
|
|
// 给定的头实体类型为"{headEntityType}";给定的尾实体类型为"{relation}",给定的关系为"{tailEntityType}"。
|
|
|
|
|
// 请仔细分析以下的文本内容,精准找出符合给定关系且头尾实体类型相符的三元组,并进行提取。如果没有识别给定的三元组关系,请返回json:{"result":[]}。
|
|
|
|
|
// ---
|
|
|
|
|
// 为您提供一个示例供学习:
|
|
|
|
|
// 例如给定关系:给定三元组类型为:头实体类型:"行为人"关系:"伪造",尾实体类型:"合同"
|
|
|
|
|
// 例如QA:办案警官问:描述一下事情的经过。 行为人小明答:我做了一份假的购房合同。
|
|
|
|
|
// 本示例中应提取给定关系为"伪造"的三元组,则最终应提取的三元组为:{"result":[{"headEntity": {"type": "行为人","name":"小明"},"relation": "伪造","tailEntity": {"type": "合同","name": "假的购房合同"}}]}。
|
|
|
|
|
// ---
|
|
|
|
|
// 需要分析提取的QA对如下:
|
|
|
|
|
// {question}
|
|
|
|
|
// {answer}
|
|
|
|
|
// ---
|
|
|
|
|
// 在提取三元组时,请务必严格遵循以下要求:
|
|
|
|
|
// 1. 确保提取的三元组包括**给定的头实体类型**和**尾实体类型**。
|
|
|
|
|
// 2. 提取的三元组必须明确体现给定的**关系**。
|
|
|
|
|
// 3. 头实体和尾实体的名称必须在对话文本中找到。
|
|
|
|
|
// 4. 对于每个提取出的三元组,确保关系({relation})与实体类型完全匹配。
|
|
|
|
|
// 5. 如果文本中没有符合要求的三元组,请确保返回空结果,即 {"result": []}。
|
|
|
|
|
// 返回格式为必须为以下的json格式:
|
|
|
|
|
// {"result":[{"headEntity": {"type": "给定头类型","name":"提取到的头实体内容1"},"relation": "给定关系","tailEntity": {"type": "给定尾类型","name": "提取到的尾实体内容1"}}]}
|
|
|
|
|
// -------------------------
|
|
|
|
|
// TEST_DEMO_3:尝试给定所有关系和头实体,只提取尾实体.结论:效果差,会把不相关的不符合的都提取出来,PASS.回退到DEMO2继续调整吧!
|
|
|
|
|
// 给定指标的存在性判断任务:给定一个指标,对给定QA进行判断是否符合,符合则为true,并把符合需实体类型的实体返回,不符合则为false
|
|
|
|
|
// 指标为:裴金禄是否{relation}{tailEntityType}(需提取实体类型为:{tailEntityType})
|
|
|
|
|
// ---
|
|
|
|
|
// 为你提供一个实例进行学习:
|
|
|
|
|
// 示例QA:办案警官问:描述一下事情的经过。 行为人小明答:我做了一份假的购房合同。
|
|
|
|
|
// 示例指标:小明是否伪造合同(需提取实体为:合同)
|
|
|
|
|
// 示例结果:{"result":ture,"entity":["购房合同"]}
|
|
|
|
|
// ---
|
|
|
|
|
// 需要分析的QA对如下:
|
|
|
|
|
// {question}
|
|
|
|
|
// {answer}
|
|
|
|
|
// ---
|
|
|
|
|
// 请从需要分析的QA中进行判断提取!!!
|
|
|
|
|
// 在判断时,请务必仔细理解需要分析的QA文本的含义,确保提取的信息准确、合理。同时,尽量遵循常见的语义和逻辑规则,避免过度解读或不合理的关系推断。
|
|
|
|
|
// 返回格式为必须json格式,格式定义如下:
|
|
|
|
|
// {"result":ture/false,"entity":["对应实体类型的实体"]}
|
|
|
|
|
|
|
|
|
|
String prompt = """
|
|
|
|
|
请从
|
|
|
|
|
三元组提取任务:从给定对话中根据给定实体类型和关系提取对应的三元组。
|
|
|
|
|
给定的头实体类型为"{headEntityType}";给定的尾实体类型为"{relation}",给定的关系为"{tailEntityType}"。
|
|
|
|
|
请仔细分析以下的文本内容,精准找出符合给定关系且头尾实体类型相符的三元组,并进行提取。如果没有识别给定的三元组关系,请返回json:{"result":[]}。
|
|
|
|
|
---
|
|
|
|
|
为您提供一个示例供学习:
|
|
|
|
|
例如给定关系:给定三元组类型为:头实体类型:"行为人"关系:"伪造",尾实体类型:"合同"
|
|
|
|
|
例如QA:办案警官问:描述一下事情的经过。 行为人小明答:我做了一份假的购房合同。
|
|
|
|
|
本示例中应提取给定关系为"伪造"的三元组,则最终应提取的三元组为:{"result":[{"headEntity": {"type": "行为人","name":"小明"},"relation": "伪造","tailEntity": {"type": "合同","name": "假的购房合同"}}]}。
|
|
|
|
|
---
|
|
|
|
|
办案警官问:你是如何想到这个方法骗钱的? 裴金禄回答:因为我是在中卫市沙坡头区中兰铁路上做监理人员,我这样说的话别人会更容易相信。
|
|
|
|
|
需要分析提取的QA对如下:
|
|
|
|
|
{question}
|
|
|
|
|
{answer}
|
|
|
|
|
---
|
|
|
|
|
这段话中按(主体类型:行为人姓名;关系:伪造;客体类型:合同名称)提取特定的三元组信息。
|
|
|
|
|
如果未提取到或关系不匹配或客体类型不匹配,则返回空的json即可。
|
|
|
|
|
如果可以提取到三元组关系,则返回格式为{"主体":"主体名称","关系":"关系名称","客体":"客体名称"}。
|
|
|
|
|
例如‘办案警官问:描述一下事情的经过。行为人小明答:我做了一份假的租车合同,然后骗小刚签了这个合同’,该示例存在给定的三元组关系.则结果为:{"主体":"小明","关系":"伪造","客体":"租车合同"}。
|
|
|
|
|
例如‘办案警官问:办案警官问:讲一下那个软件的名称?小明回答:现在叫畅聊。‘该示例不存在给定的三元组关系,则结果为:{}
|
|
|
|
|
请保证提取准确且完整,主体和客体要具体明确,不能是宽泛的概念。提取的客体要必须属于客体类型!
|
|
|
|
|
|
|
|
|
|
以只返回JSON数据
|
|
|
|
|
在提取三元组时,请务必严格遵循以下要求:
|
|
|
|
|
1. 确保提取的三元组包括**给定的头实体类型**和**尾实体类型**。
|
|
|
|
|
2. 提取的三元组必须明确体现给定的**关系**。
|
|
|
|
|
3. 头实体和尾实体的名称必须在对话文本中找到。
|
|
|
|
|
4. 对于每个提取出的三元组,确保提取到的实体与给定实体类型完全匹配。
|
|
|
|
|
5. 对于每个提取出的三元组,确保提取到的关系完全等于给定关系,如不等于,则提取错误。
|
|
|
|
|
5. 如果文本中没有符合要求的三元组,请确保返回空结果,即 {"result": []}。
|
|
|
|
|
返回格式为必须为以下的json格式:
|
|
|
|
|
{"result":[{"headEntity": {"type": "给定头实体类型","name":"提取到的对应头实体内容1"},"relation": "给定关系","tailEntity": {"type": "给定实体尾类型","name": "提取到的对应尾实体内容1"}}]}
|
|
|
|
|
""";
|
|
|
|
|
// 抽取的客体名称一定属于给定的客体类型分类,且抽取的关系完全等于给定的关系。
|
|
|
|
|
Prompt ask = new Prompt(new UserMessage(prompt));
|
|
|
|
@ -191,23 +285,6 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
log.info("耗时:{}", stopWatch.getTotalTimeSeconds());
|
|
|
|
|
String content = call.getResult().getOutput().getContent();
|
|
|
|
|
log.info("分析的结果是:{}", content);
|
|
|
|
|
|
|
|
|
|
String oldPrompt = """
|
|
|
|
|
请分析以下内容中所有规定的三元组信息并补充完整,
|
|
|
|
|
要求:1.返回式:
|
|
|
|
|
{result:
|
|
|
|
|
[
|
|
|
|
|
{startNodeType:'LawActor',entity:'',endNodeType:'FictionalOrgan',property:'',value:'冒充' },
|
|
|
|
|
{startNodeType:'LawActor',entity:'',endNodeType:'Seal',property:'',value:'伪造'},
|
|
|
|
|
{startNodeType:'LawActor',entity:'',endNodeType:'BusinessLicense',property:'',value:'伪造'}
|
|
|
|
|
]
|
|
|
|
|
}。
|
|
|
|
|
2.必须考虑上下文语境分析。
|
|
|
|
|
3.对话中不包含此类型三元组则返回{ "result": [] }。
|
|
|
|
|
例子1:办案警官问:你为了骗取更多的钱都做了哪些准备?裴金禄回答:我刚开始我就是自己想了一些关于骗钱的点子,后面为了更不容易让别人识破我为了更佳逼真,我就从网上随便搜了一家租赁公司,我就搜到了兰州胜利机械租赁有限公司,被讯问人:裴金禄我又想到了我管理的中铁北京局和中铁电气化局施工公司。我先是通过百度搜索了“办证”之后就在网页上面弹出了一个页面上面有一个QQ号,我就加上了。加上之后我就将我的要求给他说了,要求他给我刻两个假的公章,一个是兰州胜利机械租赁有限公司合同专用章,另一个是中铁北京局集团有限公司合同专用章。我还要求他给我伪造了一张兰州胜利机械租赁有限公司的营业执照。
|
|
|
|
|
回答:{"result":[{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"FictionalOrgan","property":"兰州胜利机械租赁有限公司","value":"冒充"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"兰州胜利机械租赁有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"Seal","property":"中铁北京局集团有限公司合同专用章","value":"伪造"},{"startNodeType":"LawActor","entity":"裴金禄","endNodeType":"BusinessLicense","property":"兰州胜利机械租赁有限公司营业执照","value":"伪造"}]}。
|
|
|
|
|
例子2:办案警官问:你为什么要在中卫市沙坡头区签订这些合同?裴金禄回答:因为我在这边上班,我在中卫市沙坡头区签订合同更能有说服力,这样才能更好地骗到钱。回答:{ "result": [] }。
|
|
|
|
|
""";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -241,6 +318,8 @@ public class ModelRecordTypeServiceImpl extends ServiceImpl<ModelRecordTypeMappe
|
|
|
|
|
neo4jService.saveRelation(rel);
|
|
|
|
|
}
|
|
|
|
|
tripleInfo.setAddNeo4j("1");
|
|
|
|
|
tripleInfo.setStartNodeGraphId(startNode.getId());
|
|
|
|
|
tripleInfo.setEndNodeGraphId(endNode.getId());
|
|
|
|
|
boolean updateResult = tripleInfoService.updateById(tripleInfo);
|
|
|
|
|
if (updateResult) {
|
|
|
|
|
i++;
|
|
|
|
|