山东大学软件学院创新实训-----后端开发16 整合病历的智慧多轮问诊模式

整合病历的智慧多轮问诊模式的创新点与意义:

        智慧问诊模式是一种利用人工智能技术,通过与患者的对话,自动收集和分析患者病情的智能系统。该系统通过分析患者的对话内容,判断是否需要进入智能问诊模式,并引导患者逐步提供完整的病情信息,得到完整病情信息之后,还会整合用户的病历信息来给出考虑更加周到的建议。这种模式的创新点在于:

  1. 智能化的问诊流程:通过预设的问诊步骤,系统能够引导患者提供包括个人信息、症状、病情发作细节、生活方式、病史、药物过敏史和正在使用的药物等全面的信息,确保病情信息的完整性和准确性。

  2. 高效的病情判断:系统能够通过调用大模型来判断用户是否正在咨询自身病情,并以此决定是否进入智能问诊模式,大大提高了问诊的效率和准确性。

  3. 个性化医疗建议:结合患者的病史和当前症状,系统能够提供个性化的医疗建议,帮助患者更好地理解自己的病情,并给予相应的医疗指导。

实现方式

智慧问诊模式的实现主要包括以下几个步骤:

  1. 消息初始化与管理:系统在初始状态下会添加一条系统消息,说明智能医生的角色和职责。通过消息管理器对用户与系统的对话进行管理和存储。

  2. 智能问诊模式触发判断:系统会判断用户的问题是否会触发智能问诊模式,如果触发,系统会进入问诊模式,并通过预设的问题逐步引导患者提供病情信息。

  3. 病情信息收集与存储:在问诊过程中,系统会根据预设的问诊步骤逐步收集患者的信息,并将这些信息存储在临时的PatientInfo对象中。

  4. 病历整合与保存:当问诊步骤完成后,系统会整合患者的当前症状和病史信息,并调用大模型生成医疗建议。最后,系统会将当前病症保存为病史,方便未来的查询和分析。

改进:

新增加了整合病历,这使得大模型回答用户问题的时候考虑的的内容会更加全面。

//查找病史
List<PatientHistory> PatientHistoryList = patientHistoryService.findByUserId(userController.loginUser.getId());
// 将病史列表中的元素转换成字符串并连接起来
String historyString = PatientHistoryList.stream()
                            .map(PatientHistory::toString)
                            .collect(Collectors.joining("。      "));
                    //打印查看病史列表
System.out.println(historyString);
patientInfo.toString();
//整合病史和当前病情
messages.add(createMessage(Role.USER,"我的的以往病史是:"+historyString+
                            "            " +
                            "我的当前的病症是:"+patientInfo.toString()+
                            "            " +
                            "请你针对我的的当前症状给出相应的建议,如果当前病症和我的病史相关那就需要考虑一下病史"));

智慧轮询的问题更加人格化,清切自然,并且为用户提供了更加明确的回答方向,这样收集的信息回更加准确,同时也能提高用户的使用体验。

    private String getNextQueryMessage() {
        queryStep++;
        switch (queryStep) {
            case 1:
                return "提供一下你最近的身高和体重信息";
            case 2:
                return "你目前有哪些症状?能详细和我说一下";
            case 3:
                return "病情发作的细节你有留意吗?,比如发作时间、持续时间和发作频率。";
            case 4:
                return "你的平时生活习惯怎样?比如饮食、运动、睡眠等方面。";
            case 5:
                return "请大致描述一下你的病史,包括曾经患过的疾病、手术史等。";
            case 6:
                return "你是否对某些药物过敏?如果有,请说一下你过敏的药物信息";
            case 7:
                return "你目前有那些正在使用的药物?请提供正在使用的药物清单。";
            default:
                break;
        }
        return null;
    }

完整实现代码:

package com.SmartMed_Connect.service;

import com.SmartMed_Connect.controller.UserController;
import com.SmartMed_Connect.entity.PatientHistory;
import com.SmartMed_Connect.entity.User;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationOutput;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageManager;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApiService {


    @Autowired
    protected PatientHistoryService patientHistoryService;

    @Autowired
    private UserController userController;

    @Autowired
    protected UserService userService;

    //病史实体类
    private PatientHistory patientHistory = new PatientHistory();

    static {
        // 设置 API key
        com.alibaba.dashscope.utils.Constants.apiKey = "sk-d70a6efd593a4d72b91a1cecd4408411";
    }
    // 消息列表
    private final List<Message> messages = new ArrayList<>();
    //智能问诊模式到了第几步
    private int queryStep = 0;
    //用于临时存储智能问诊模式得到的信息
    private PatientInfo patientInfo = new PatientInfo();
    //是否正在触发智能问诊模式
    private boolean isTriggering=false;


    //处理用户与 Qwen 对话的函数
    public String query(String queryMessage) {
        try {
            // 初始消息为空时,添加系统消息
            if(messages.isEmpty())
            {
                messages.add(createMessage(Role.SYSTEM, "你是一名智能医生,请结合上下文,回答病人的问题,不许回答其他问题。"));
//                System.out.println("用户Id"+userController.loginUser.getId());
//                patientHistoryService.findByUserId(userController.loginUser.getId());
            }
            //如果当前不在问诊模式
            if(!isTriggering)
            {
                isTriggering=isMedicalQuery(queryMessage); //判断用户的问题是否触发问诊模式
                //如果用户的问题会触发问诊模式,调用触发问诊模式第一步询问
                if(isTriggering)
                {
                    System.out.println("触发问诊模式");
                    patientInfo= new PatientInfo();
                    savePatientInfo(queryMessage);
                    String response=getNextQueryMessage();
                    return response;
                }
                //否则,使用通义千问的一般问答模式
                else
                {
                    messages.add(createMessage(Role.USER, queryMessage));
                    GenerationParam param = createGenerationParam(messages);
                    GenerationResult result = callGenerationWithMessages(param);
                    messages.add(result.getOutput().getChoices().get(0).getMessage());
                    GenerationOutput output = result.getOutput();
                    return output.getChoices().get(0).getMessage().getContent();
                }
            }
            else //已经进入问诊模式了
            {
                if(queryStep==7)
                {
                    savePatientInfo(queryMessage);//保存用户最后一次回答
                    isTriggering=false;//重置触发标志
                    queryStep=0;//重置问诊步骤



                    //查找病史
                    List<PatientHistory> PatientHistoryList = patientHistoryService.findByUserId(userController.loginUser.getId());
                    // 将病史列表中的元素转换成字符串并连接起来
                    String historyString = PatientHistoryList.stream()
                            .map(PatientHistory::toString)
                            .collect(Collectors.joining("。      "));
                    //打印查看病史列表
                    System.out.println(historyString);
                    patientInfo.toString();
                    //整合病史和当前病情
                    messages.add(createMessage(Role.USER,"我的的以往病史是:"+historyString+
                            "            " +
                            "我的当前的病症是:"+patientInfo.toString()+
                            "            " +
                            "请你针对我的的当前症状给出相应的建议,如果当前病症和我的病史相关那就需要考虑一下病史"));
                    GenerationParam param = createGenerationParam(messages);
                    GenerationResult result = callGenerationWithMessages(param);
                    messages.add(result.getOutput().getChoices().get(0).getMessage());
                    GenerationOutput output = result.getOutput();

//                    printMessages();
//                    System.out.println(output.getChoices().get(0).getMessage().getContent());
                    patientHistory=PatientInfoToPatientHistory(patientInfo,output.getChoices().get(0).getMessage().getContent());
                    //把当前的病症保存为病史
                    patientHistoryService.save(patientHistory);
//

                    return "考虑到您的病史和当前症状得到的诊断结果是:                   "+output.getChoices().get(0).getMessage().getContent();
                }
                savePatientInfo(queryMessage);//保存上一次提问的用户回答
                String response = getNextQueryMessage();//获得AI下一次的问题
                return response;
            }
        } catch (Exception e) {
            return "发生错误,请稍后再试。";
        }
    }

    public void printMessages() {
        for (Message message : messages) {
            System.out.println("Role: " + message.getRole() + ", Content: " + message.getContent());
        }
    }

    private String getNextQueryMessage() {
        queryStep++;
        switch (queryStep) {
            case 1:
                return "提供一下你最近的身高和体重信息";
            case 2:
                return "你目前有哪些症状?能详细和我说一下";
            case 3:
                return "病情发作的细节你有留意吗?,比如发作时间、持续时间和发作频率。";
            case 4:
                return "你的平时生活习惯怎样?比如饮食、运动、睡眠等方面。";
            case 5:
                return "请大致描述一下你的病史,包括曾经患过的疾病、手术史等。";
            case 6:
                return "你是否对某些药物过敏?如果有,请说一下你过敏的药物信息";
            case 7:
                return "你目前有那些正在使用的药物?请提供正在使用的药物清单。";
            default:
                break;
        }
        return null;
    }

    private void savePatientInfo(String queryMessage) {
        switch (queryStep) {
            case 0:
                patientInfo.setFirstQuery(queryMessage);// 第一次询问信息
                break;
            case 1:
                patientInfo.setPersonalInfo(queryMessage);// 个人基本信息,身高、体重
                break;
            case 2:
                patientInfo.setSymptoms(queryMessage);// 症状
                break;
            case 3:
                patientInfo.setEpisodeDetails(queryMessage);// 病情发作相关细节,如发作时间,持续时间,发作频率
                break;
            case 4:
                patientInfo.setLifestyleFactors(queryMessage);// 生活方式因素,包括饮食、运动、睡眠等
                break;
            case 5:
                patientInfo.setMedicalHistory(queryMessage);// 病史
                break;
            case 6:
                patientInfo.setAllergicDrugs(queryMessage);// 过敏药物
                break;
            case 7:
                queryStep++;
                patientInfo.setUsingDrugs(queryMessage);// 正在使用的药物
                break;
        }
    }

    private static GenerationParam createGenerationParam(List<Message> messages) {
        return GenerationParam.builder()
                .model("qwen-turbo")
                .messages(messages)
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .topP(0.8)
                .build();
    }

    private static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException
    {
        Generation gen = new Generation();
        return gen.call(param);
    }

    private static Message createMessage(Role role, String content) 
    {
        return Message.builder().role(role.getValue()).content(content).build();
    }


    //通过调用大模型来判断用户是否正在咨询自身病情。
    public  static boolean isMedicalQuery(String queryMessage) throws NoApiKeyException, InputRequiredException {
        Generation gen = new Generation();
        MessageManager msgManager = new MessageManager(10);
        Message systemMsg =
                Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.下面的问题只能回答一个0~1之间的小数,其余内容都不用回答").build();
        Message userMsg =
                Message.builder().role(Role.USER.getValue()).content(queryMessage+",请你根据用户的询问给出用户此时身体不舒服的概率(0~1之间的小数),依据是出现疾病之类的词,只需要返回一个小数就行").build();
        msgManager.add(systemMsg);
        msgManager.add(userMsg);
        QwenParam param =
                QwenParam.builder().model(Generation.Models.QWEN_TURBO).messages(msgManager.get())
                        .resultFormat(QwenParam.ResultFormat.MESSAGE)
                        .build();
        GenerationResult result = gen.call(param);
        System.out.println("获取概率内容"+result.getOutput().getChoices().get(0).getMessage().getContent());
        float probability= Float.parseFloat(result.getOutput().getChoices().get(0).getMessage().getContent());
        System.out.println("概率"+probability);
        return probability > 0.84;
    }

    private static class PatientInfo {
        private String firstQuery;//第一次询问信息
        private String personalInfo;//个人基本信息,如身高、体重
        private String symptoms;//症状
        private String episodeDetails;//病情发作相关细节,如发作时间,持续时间,发作频率
        private String lifestyleFactors;//表示生活方式因素,包括饮食、运动、睡眠等
        private String medicalHistory;//病史
        private String allergicDrugs;//过敏药物
        private String usingDrugs;//正在使用的药物

        @Override
        public String toString() {
            return "病人信息{" +
                    "病人第一次询问为:'" + firstQuery + '\'' +//第一次询问信息
                    ", 一般信息:'" + personalInfo + '\'' +//个人基本信息,如年龄、性别、身高、体重
                    ", 症状:'" + symptoms + '\'' +//症状
                    ", 发作细节:'" + episodeDetails + '\'' +//病情发作相关细节,如发作时间,持续时间,发作频率
                    ", 生活方式:'" + lifestyleFactors + '\'' +//表示生活方式因素,包括饮食、运动、睡眠等
                    ", 病史:'" + medicalHistory + '\'' +//病史
                    ", 过敏药物:'" + allergicDrugs + '\'' +//过敏药物
                    ", 正在使用的药物:'" + usingDrugs + '\'' +//正在使用的药物
                    '}';
        }

        public void setLifestyleFactors(String lifestyleFactors) {
            this.lifestyleFactors = lifestyleFactors;
        }

        public void setUsingDrugs(String usingDrugs) {
            this.usingDrugs = usingDrugs;
        }

        public void setAllergicDrugs(String allergicDrugs) {
            this.allergicDrugs = allergicDrugs;
        }

        public void setMedicalHistory(String medicalHistory) {
            this.medicalHistory = medicalHistory;
        }

        public void setEpisodeDetails(String episodeDetails) {
            this.episodeDetails = episodeDetails;
        }

        public void setSymptoms(String symptoms) {
            this.symptoms = symptoms;
        }

        public void setPersonalInfo(String personalInfo) {
            this.personalInfo = personalInfo;
        }

        public void setFirstQuery(String firstQuery) {
            this.firstQuery = firstQuery;
        }
    }

    private PatientHistory PatientInfoToPatientHistory(PatientInfo patientInfo,String currentDiagnosticResult) {
        System.out.println("执行到这里了");
        patientHistory.setId(null);
        //设置用户id
        patientHistory.setUserId(userController.loginUser.getId());

        //设置用户第一次询问的信息
        patientHistory.setFirstQuery(patientInfo.firstQuery);
        //设置用户年龄
        patientHistory.setUserAge(userController.loginUser.getUserAge());
        //设置用户性别
        patientHistory.setUserSex(userController.loginUser.getUserSex());
        //设置用户身高体重
        patientHistory.setHeightAndWeight(patientInfo.personalInfo);
        //设置用户症状
        patientHistory.setSymptoms(patientInfo.symptoms);
        //设置用户病情发作相关细节,如发作时间,持续时间,发作频率
        patientHistory.setEpisodeDetails(patientInfo.episodeDetails);
        //表示生活方式因素,包括饮食、运动、睡眠等
        patientHistory.setLifestyleFactors(patientInfo.lifestyleFactors);
        //病史
        patientHistory.setMedicalHistory(patientInfo.medicalHistory);
        //过敏药物
        patientHistory.setAllergicDrugs(patientInfo.allergicDrugs);
        //正在使用的药物
        patientHistory.setUsingDrugs(patientInfo.usingDrugs);
        //当前诊断结果
        patientHistory.setDiagnosticResult(currentDiagnosticResult);
        //查看保存内容
        System.out.println(patientHistory);
        return patientHistory;
    }
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值