package com.supervision.springaidemo.controller; import cn.hutool.core.io.FileUtil; import com.supervision.police.domain.ModelRecordType; import com.supervision.police.domain.NoteRecordSplit; import com.supervision.springaidemo.dto.QARecordNodeDTO; import com.supervision.police.mapper.ModelRecordTypeMapper; import com.supervision.police.mapper.NoteRecordSplitMapper; import com.supervision.police.service.ModelRecordTypeService; import com.supervision.springaidemo.service.ModelMetricService; import com.supervision.police.service.RecordService; import com.supervision.police.service.NoteCheckRecordService; import com.supervision.springaidemo.util.RecordRegexUtil; import com.supervision.springaidemo.util.WordReadUtil; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.annotations.Param; import org.json.JSONObject; import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.Generation; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.ollama.OllamaChatClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StopWatch; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.File; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** * 目前这是效果最好的方案,暂时先用这个 */ @RestController @Slf4j @RequestMapping("exampleChat") public class ExampleChatController { private final OllamaChatClient chatClient; @Autowired private ModelMetricService modelMetricService; @Autowired private NoteCheckRecordService noteCheckRecordService; @Autowired private ModelRecordTypeMapper modelRecordTypeMapper; @Autowired private NoteRecordSplitMapper noteRecordSplitMapper; @Autowired public ExampleChatController(OllamaChatClient chatClient) { this.chatClient = chatClient; } @Autowired private RecordService recordService; @Autowired private ModelRecordTypeService modelRecordTypeService; private static final String exampleTemplate = """ 我们现在需要以step by step的方式进行笔录的指标分析工作,得到最终的结果并返回。 step1:分析笔录的内容; 以下是笔录的内容: --- {context} --- step2:现在给你指标以及指标的释义或例子可协助你参考: 指标释义或例子及判断标准: 指标名称:{metricName} 我现在给你为true的例子可供参考:{example}; 如果和例子这种情况相反或偏差较大则为false; 如果笔录中,没有任何笔录内容涉及到该项指标,无法进行判断,则为empty。 step3:现在需要你根据上面提供的所有信息,尽可能实事求是完成判断: 1.判断结论:true/false/empty 2.得到结论的笔录原话:从笔录的对话中,得到该结论的原文(一定是摘抄的原文且为中文)。如果结论为true,则必须要有原文佐证! 3.得到结论的原因:分析得出该结论的原因,需明确说明为什么得到该结论,需要参考例子的格式且为中文回复。如果结论为true/false,则必须有原因! step4:必须以json格式回复, JSON的value内容我给你的提示,在实际输出的时候不需要带上: --- {"result":"结论", "originalContext":"笔录对应原话","reason":"原因"} --- 好了,现在可以回复了! """; @GetMapping("exampleChat") public void exampleChat() { File file = FileUtil.file("E:\\jc\\宁夏\\Fw_裴金禄\\裴金禄第一次.docx"); String context = WordReadUtil.readWord(file.getPath()); List qaList = RecordRegexUtil.recordRegex(context, "裴金禄"); for (QARecordNodeDTO qa : qaList) { NoteRecordSplit noteRecord = new NoteRecordSplit(); noteRecord.setNoteName(file.getName()); noteRecord.setPersonName("裴金禄"); noteRecord.setQuestion(qa.getQuestion()); noteRecord.setAnswer(qa.getAnswer()); noteRecord.setCreateTime(LocalDateTime.now()); // if (qa.getAnswer().length() > 500) { // continue; // } //根据提示词分析类型 并保存 // String test = "你现在是一个笔录分析人员,请用四个字描述一下下述内容属于哪种类型的对话?"; String test = "你是一个善于归纳分析问讯笔录的大模型,请用四个字描述下述内容属于哪种类型的对话?对话内容为:"; String tip = "你的回答必须严格控制为四个字。"; String example = "示例1:办案警官问:我们是中卫市公安局沙坡头区分局经侦大队的民警(出示工作证件),现依法对你进行讯问,你应当如实回答我们的提问,对与案件无关的问题,你有拒绝回答的权利。你听明白了吗? 张某答:听明白了。回复:{\"type\":\"权利义务\"}。" + "示例2:办案警官问:你的个人情况?张某答:我叫裴金禄,男,1984年01月10日出生,藏族,大学文化,户籍所在地陕西省西安市雁塔区丈八四路6号7号楼1单元 2304室,现住陕西省西安市雁塔区丈八四路6号7号楼1单元 2304室,无业,居民身份证号码622326198401100090,联系电话15829319393。回复:{\"type\":\"个人情况\"}。" + "示例3:办案警官问:你的家庭情况?张某答:我父亲叫:裴国智,今年:67岁,退休,电话:13519353723; 母亲:李金芬,今年:61岁,无业;我弟弟裴金生,今年: 34岁,在中石油运输公司上班。回复:{\"type\":\"家庭情况\"}。"; List messages = new ArrayList<>(List.of(new SystemMessage(test + qa.getQuestion() + qa.getAnswer() + tip + example))); Prompt prompt = new Prompt(messages); StopWatch stopWatch = new StopWatch(); stopWatch.start(); // log.info("开始分析:"); ChatResponse call = chatClient.call(prompt); stopWatch.stop(); // log.info("耗时:{}", stopWatch.getTotalTimeSeconds()); Generation result = call.getResult(); String content = result.getOutput().getContent(); // log.info("问:{}, 答:{}", qa.getQuestion(), qa.getAnswer()); // log.info("分析的结果是:{}", content); JSONObject jsonObject = new JSONObject(content); String type = jsonObject.getString("type").trim(); System.out.println("问:"+qa.getQuestion()+"答:"+qa.getAnswer()); System.out.println("分析的结果是:"+ type); //保存笔录 noteRecord.setRecordType(type); recordService.save(noteRecord); ModelRecordType exist = modelRecordTypeService.queryByName(type); if (exist == null) { ModelRecordType modelRecordType = new ModelRecordType(); modelRecordType.setRecordType(type); modelRecordTypeService.save(modelRecordType); } } // for (QARecordNodeDTO qaRecordNodeDTO : qaList) { // // 只查入罪指标 // List list = modelMetricService.lambdaQuery().likeRight(ModelMetric::getMetricCode, "RZ").list(); // for (ModelMetric modelMetric : list) { // String systemPrompt = """ // 你是一个善于分析办案笔录的模型,能够根据办案笔录的回答内容,结合给定的例子,实事求是的判断给定指标是否满足。注意,仅根据笔录进行分析,不要做笔录之外的推断。笔录内容可能比较长,可能分多次提交给你。Think step by step // """; // List messages = new ArrayList<>(List.of(new SystemMessage(systemPrompt))); // Map param = new HashMap<>(); // param.put("context", qaRecordNodeDTO.toString()); // param.put("metricName", modelMetric.getMetricName()); // param.put("example", StrUtil.format(modelMetric.getExample(), MapUtil.of("action", "裴金禄"))); // String format = StrUtil.format(exampleTemplate, param); // List userMessageList = new ArrayList<>(); // if (format.length() > 8000) { // log.info("分段提交"); // for (String s : StrUtil.split(format, 6000)) { // userMessageList.add(new UserMessage(s)); // userMessageList.add(new AssistantMessage("继续")); // } // userMessageList.remove(userMessageList.size() - 1); // } else { // userMessageList.add(new UserMessage(format)); // } // messages.addAll(userMessageList); // // RunCheckThread runCheck = new RunCheckThread("裴金禄尝试正则来做", chatClient, noteCheckRecordService, new Prompt(messages), FileUtil.getName(file), format, systemPrompt, modelMetric, 0); // RunCheckThreadPool.chatExecutor.submit(runCheck); // } // } } @GetMapping("test") public List test(@Param("test") String test) { List list = new ArrayList<>(); List messages = new ArrayList<>(List.of(new SystemMessage(test))); Prompt prompt = new Prompt(messages); StopWatch stopWatch = new StopWatch(); stopWatch.start(); log.info("开始分析:"); ChatResponse call = chatClient.call(prompt); stopWatch.stop(); log.info("耗时:{}", stopWatch.getTotalTimeSeconds()); Generation result = call.getResult(); String content = result.getOutput().getContent(); log.info("分析的结果是:{}", content); Map resultMap = new HashMap<>(); resultMap.put("result", content); list.add(resultMap); return list; } @GetMapping("queryRecordType") public List queryRecordType() { List types = modelRecordTypeMapper.selectList(null); String allType = types.stream().map(ModelRecordType::getRecordType).collect(Collectors.joining(".")); List list = noteRecordSplitMapper.selectList(null); for (NoteRecordSplit record : list) { record.setRecordType(""); String test = "你是一个善于总结问讯内容的大模型,请判断以下对话属于【" + allType + "】哪个分类?对话内容为:"; String tip = "你的回答必须在所给范围内。"; String example = "示例:办案警官问:你的家庭情况?答:裴金禄回答:我父亲叫:裴国智,今年:67岁,退休,电话:13519353723;母亲:李金芬,今年:61岁,无业;我弟弟裴金生,今年:34岁,在中石油运输公司上班。回复:{\"type\":\"家庭情况\"}。"; List messages = new ArrayList<>(List.of(new SystemMessage(test + record.getQuestion() + record.getAnswer() + tip + example))); Prompt prompt = new Prompt(messages); StopWatch stopWatch = new StopWatch(); stopWatch.start(); // log.info("开始分析:"); ChatResponse call = chatClient.call(prompt); stopWatch.stop(); // log.info("耗时:{}", stopWatch.getTotalTimeSeconds()); Generation result = call.getResult(); String content = result.getOutput().getContent(); // log.info("问:{}, 答:{}", qa.getQuestion(), qa.getAnswer()); // log.info("分析的结果是:{}", content); System.out.println("问:"+record.getQuestion()+"答:"+record.getAnswer()); System.out.println("分析的结果是:"+ content); record.setRecordType(content); } return list; } @GetMapping("test1") public void test2(@Param("id") String id) { NoteRecordSplit noteRecord = recordService.getById(id); String question = noteRecord.getQuestion(); String answer = noteRecord.getAnswer(); String test = "请从以下对话中提取所有关于" + noteRecord.getRecordType() + "的所有三元组"; // String test = "请从以下对话中提取所有三元组,对话内容为:"; String example = "。示例:办案警官问:你的家庭情况?答:裴金禄回答:我父亲叫:裴国智,今年:67岁,电话:13519353723;母亲:李金芬,今年:61岁;我弟弟裴金生,今年:34岁。" + "回复:{\"result\":[{\"主体\":\"裴金禄\",\"关系\":\"父子\",\"客体\":\"裴国智\"},{\"主体\":\"裴金禄\",\"关系\":\"母子\",\"客体\":\"李金芬\"},{\"主体\":\"裴金禄\",\"关系\":\"兄弟\",\"客体\":\"裴金生\"},{\"主体\":\"裴国智\",\"关系\":\"年龄\",\"客体\":67},{\"主体\":\"李金芬\",\"关系\":\"年龄\",\"客体\":61},{\"主体\":\"裴金生\",\"关系\":\"年龄\",\"客体\":34}]}。"; String a = "你是一个问讯笔录分析师,请分析以下内容中所有规定的三元组信息并补充完整,规定的三元组信息如下:[{startNodeType:'Person',entity:'',endNodeType:'Person',property:'',value:'' },{startNodeType:'Person',entity:'',endNodeType:'Organ',property:'',value:''}],要求返回格式{result:[三元组信息]}。"; List messages = new ArrayList<>(List.of(new SystemMessage(a + question+answer))); // List messages = new ArrayList<>(List.of(new SystemMessage(test + question+answer+example))); Prompt prompt = new Prompt(messages); StopWatch stopWatch = new StopWatch(); stopWatch.start(); log.info("开始分析:"); ChatResponse call = chatClient.call(prompt); stopWatch.stop(); log.info("耗时:{}", stopWatch.getTotalTimeSeconds()); Generation result = call.getResult(); String content = result.getOutput().getContent(); log.info("分析的结果是:{}", content); } }