|
|
@@ -103,10 +103,10 @@ public class MedicalRecordQc123Service {
|
|
|
* 病历字段 → sectionLabel / 对应质控规则分类
|
|
|
*/
|
|
|
private static final Map<String, String> SECTION_LABEL_MAP = Map.ofEntries(
|
|
|
- Map.entry("admission_note", "入院记录"), // 入院记录
|
|
|
- Map.entry("first_course_record", "病程记录"), // 首次病程记录
|
|
|
- Map.entry("course_records", "病程记录"), // 病程记录
|
|
|
- Map.entry("stage_summary", "病程记录"), // 阶段小结
|
|
|
+ Map.entry("admission_note", "主诉记录不完整,不能支持第一诊断"), // 入院记录
|
|
|
+ Map.entry("first_course_record", "首次病程记录规则清单"), // 首次病程记录
|
|
|
+ Map.entry("course_records", "病程记录规则清单"), // 病程记录
|
|
|
+ Map.entry("stage_summary", "阶段小结规则清单"), // 阶段小结
|
|
|
Map.entry("ward_rounds", "查房记录"), // 查房记录
|
|
|
Map.entry("consultation_records", "病程记录"), // 会诊记录
|
|
|
Map.entry("difficult_case_discussion", "病程记录"), // 疑难病例讨论记录
|
|
|
@@ -114,10 +114,10 @@ public class MedicalRecordQc123Service {
|
|
|
Map.entry("death_case_discussion", "病程记录"), // 死亡病例讨论记录
|
|
|
Map.entry("rescue_records", "病程记录"), // 抢救记录
|
|
|
Map.entry("surgery_records", "其他"), // 手术记录
|
|
|
- Map.entry("lab_reports", "检查检验"), // 检验报告单
|
|
|
- Map.entry("exam_reports", "检查检验"), // 检查报告单
|
|
|
- Map.entry("orders", "治疗"), // 医嘱记录
|
|
|
- Map.entry("discharge_summary", "出院(死亡)记录"), // 出院小结
|
|
|
+ Map.entry("lab_reports", "检查检验规则清单"), // 检验报告单
|
|
|
+ Map.entry("exam_reports", "检查检验规则清单"), // 检查报告单
|
|
|
+ Map.entry("orders", "医嘱规则清单"), // 医嘱记录
|
|
|
+ Map.entry("discharge_summary", "出院(死亡)记录规则清单"), // 出院小结
|
|
|
Map.entry("consent_forms", "知情同意书") // 知情同意书
|
|
|
);
|
|
|
|
|
|
@@ -125,7 +125,7 @@ public class MedicalRecordQc123Service {
|
|
|
* 整份病历流水线质控
|
|
|
*/
|
|
|
|
|
|
- @Transactional
|
|
|
+// @Transactional
|
|
|
public void performFullRecordQc(String recordId) {
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
|
|
@@ -322,19 +322,17 @@ public class MedicalRecordQc123Service {
|
|
|
sb.append("【质控规则】:\n")
|
|
|
.append(ragResult).append("\n\n");
|
|
|
|
|
|
- sb.append("请根据以上内容,对病历进行质控,严格输出 **JSON 数组**,不得输出任何解释、总结或多余文字。\n\n");
|
|
|
+ sb.append("1.输出格式:\n");
|
|
|
+ sb.append("请严格按照以下要求输出:\n");
|
|
|
+ sb.append("如果病历完全符合所有规则:[{\"result\": \"pass\", \"message\": \"病例校验通过\"}]\n");
|
|
|
|
|
|
- sb.append("输出格式要求如下:\n");
|
|
|
- sb.append("1. 如果病历完全符合所有规则:\n");
|
|
|
- sb.append("[{\"result\": \"pass\", \"message\": \"病例校验通过\"}]\n\n");
|
|
|
-
|
|
|
- sb.append("2. 如果存在不符合规则:逐条输出 JSON 对象,数组形式,每个对象包含以下字段:\n");
|
|
|
+ sb.append("如果存在不符合规则:逐条输出 JSON 对象,数组形式,每个对象包含以下字段:\n");
|
|
|
sb.append("- result: 固定为 \"fail\"\n");
|
|
|
- sb.append("- detail: 病历详情(指出病历的哪一部分,如:张三的入院记录-主诉)\n");
|
|
|
- sb.append("- content: 取一段违反规则的病历原文中的部分(四到六个字符,与病历原文中完全一致)\n");
|
|
|
- sb.append("- ruleCode: 规则编码(如:RYJL0001,必须与提供的质控规则中的编码一致)\n");
|
|
|
- sb.append("- ruleContent: 规则描述(必须与提供的质控规则中的规则详情一致)\n");
|
|
|
- sb.append("- qcResult: 质控结论(指出违反该条规则的原因)\n\n");
|
|
|
+ sb.append("- detail: 违规位置及内容(如“首次病程记录-主诉”)\n");
|
|
|
+ sb.append("- 从病历原文中提取 违规内容所在的一句话或一小段(约10–20字),保持完整语义,便于定位。\n");
|
|
|
+ sb.append("- ruleCode: 对应规则编号(如 \"BCJL001\")\n");
|
|
|
+ sb.append("- ruleContent: 对应规则详情,必须与质控规则完全一致,不要显示()里面的内容\n");
|
|
|
+ sb.append("- qcResult: 结论,给出违反规则的原因,简要描述。\n\n");
|
|
|
|
|
|
sb.append("示例:\n");
|
|
|
sb.append("[\n");
|
|
|
@@ -342,13 +340,15 @@ public class MedicalRecordQc123Service {
|
|
|
sb.append(" {\"result\": \"fail\", \"detail\": \"李四的入院记录-现病史\", \"content\": \"脾气大2年\", \"ruleCode\": \"RYJL0002\", \"ruleContent\": \"现病史记录不完整\", \"qcResult\": \"缺少诊治经过\"}\n");
|
|
|
sb.append("]\n\n");
|
|
|
|
|
|
- sb.append("⚠️ 注意:\n");
|
|
|
- sb.append("1. 必须输出有效 JSON 数组,不能有多余的符号或文字。\n");
|
|
|
- sb.append("2. 输出的规则部分必须严格来源于提供的规则,不得自行拟造\n");
|
|
|
- sb.append("3. 所有 key 必须用双引号。\n");
|
|
|
- sb.append("4. 如果没有违规,必须只输出 pass 的 JSON 数组。\n");
|
|
|
- sb.append("5. content 字段必须是从病历原文中提取的4-6个连续字符,与原文完全一致。\n");
|
|
|
- sb.append("6. 禁止使用任何 Markdown 格式(如 ```json 或 ```),只能输出纯 JSON 数组。\n");
|
|
|
+ sb.append("2.违规情况:\n");
|
|
|
+ sb.append("每条违规单独输出一个 JSON 对象 \n");
|
|
|
+ sb.append("必须严格匹配质控规则,不得编造额外规则 \n");
|
|
|
+ sb.append("字段必须取自病历原文,且保持完整语义(不必限制为固定字数) \n");
|
|
|
+ sb.append("3.禁止事项:\n");
|
|
|
+ sb.append("禁止输出 Markdown 代码块符号(如 ```json)\n");
|
|
|
+ sb.append("禁止生成与质控规则不一致的规则编号\n");
|
|
|
+
|
|
|
+
|
|
|
|
|
|
return sb.toString();
|
|
|
}
|
|
|
@@ -358,24 +358,24 @@ public class MedicalRecordQc123Service {
|
|
|
* 调用大模型 API (保持不变)
|
|
|
*/
|
|
|
private String callLLM(String prompt) {
|
|
|
- Map<String, Object> request = new HashMap<>();
|
|
|
- request.put("model", "deepseek-r1-70B");
|
|
|
- request.put("stream", false);
|
|
|
+
|
|
|
|
|
|
List<Map<String, String>> messages = new ArrayList<>();
|
|
|
- messages.add(Map.of("role", "system", "content", "你是一个医疗文书质控助手,输出语言为中文。"));
|
|
|
+ messages.add(Map.of("role", "system", "content", "严格按照【质控规则】逐条判断,仅检查病历中是否记录相关内容。有则通过,无则违规。禁止推断适应症、合理性或处理依据,不得增加规则中未写明的要求。输出必须与【规则内容】完全对应,不得扩展或改写。"));
|
|
|
messages.add(Map.of("role", "user", "content", prompt));
|
|
|
|
|
|
String jsonBody = JSON.toJSONString(
|
|
|
new HashMap<String, Object>() {{
|
|
|
put("model", "qwen3-32B");
|
|
|
put("stream", false);
|
|
|
+ put("temperature", 0.0);
|
|
|
put("messages", messages);
|
|
|
- put("max_tokens", 10240); // ✅ 限制最大输出token数
|
|
|
+ put("max_tokens", 5120); // ✅ 限制最大输出token数
|
|
|
put("chat_template_kwargs", "{\"enable_thinking\": false}");
|
|
|
}}
|
|
|
);
|
|
|
String modelUrl = getLlmModelUrl();
|
|
|
+ System.out.println("模型路径:"+ modelUrl);
|
|
|
|
|
|
String response = HttpUtils.sendHttpPostByJson(modelUrl, jsonBody);
|
|
|
|