项目实训——后端篇6:基于MING模型的简单智能对话服务MingAPIService的实现

MING本身作为医疗大模型,其对于医疗领域问题的回答质量要比Qwen好,专业性也更强(毕竟是基于Qwen微调的),因此使用智能问诊反而显得有点冗余。但即便如此,搜集病人的病历信息加入对话信息里,仍然是增强对话质量的选择之一。

1、对话的实现

query函数首先将必要参数以及用户的问答文本格式化为能被api_server接受的json格式。这里可以通过将这些参数使用Map包装起来,并放入request Body中,并使用FastJson进行转化

JSONObject result = ClientUtil.sendPostRequest(mingURL,params);

之前的发送Post请求的功能,修改之后放到ClientUtil中,以和地理信息增强的功能进行解耦

messageCacheList起到一个消息缓存的作用,当其为空时,首先从数据库中按顺序拉取消息历史记录出来,发送请求时,会将messageCacheList中的所有消息作为参数发送

        MessageWrapper userMessage = new MessageWrapper("user",queryContent);
        messageCacheList.add(userMessage);

        params.put("messages",messageCacheList);

解析得到的json,并从中提取消息,加入消息缓存列表和数据库中

JSONArray choices = result.getJSONArray("choices");

        if(choices==null){

            return "choice == null"+result.toJSONString();
        }

        MessageWrapper responseMessage = new MessageWrapper();
        for(int i =0;i<choices.size();++i){
            JSONObject messageJson = choices.getJSONObject(i).getJSONObject("message");

            String role  = messageJson.getString("role");
            String content = messageJson.getString("content");

            responseMessage.setRole(role);
            responseMessage.setContent(content);
        }
        messageCacheList.add(responseMessage);
        saveUserChatHistory(userId,messageCacheList);

        String resultContent = responseMessage.getContent();

2、消息的存储与删除

将消息缓存列表中的MessageWrapper转化成ChatMessage并插入数据库中,取出则反之

需要注意的是取出消息时可能会出现role为null的情况,推测是save时出了bug,这种情况下要排除,因为role为null时ming_api_server无法解析

 private void saveUserChatHistory(Integer userId,List<MessageWrapper> messageList){
        for(MessageWrapper message: messageList){
            ChatMessage chatMessage = new ChatMessage(null, userId, message.getRole(), message.getContent());
            chatMessageMapper.insert(chatMessage);
        }

    }
    private void fetchUserChatHistory(int userId){
        List<ChatMessage> userChatHistory = chatMessageMapper.findChatMessageByUserId(userId);
        if(userChatHistory==null){
            System.out.println("fetch chat history failed");
            return ;
        }
        for(ChatMessage chatMessage:userChatHistory){
            MessageWrapper messageWrapper = new MessageWrapper(chatMessage.getRole(),chatMessage.getContent());
            if(messageWrapper.getRole() !=null&& messageWrapper.getContent()!=null){
                messageCacheList.add(messageWrapper);
            }
        }
    }

3、信息增强

正如前面提到的,在函数createQueryContent函数中,加入了用户的病历信息辅助判断

当病人第一次与ming对话时,加入用户病历信息辅助判断。

还有一个点就是前面博客提到的地理信息提供,这里通过正则表达式判断用户的问题里有没有关键词“医院”,若有,在模型的回答文本中加入所在区域的医院信息

private boolean checkIfNeedHospitalLocationInfo(String content){
        String keyword = "医院";
     
        Pattern pattern = Pattern.compile(keyword);
        
        Matcher matcher = pattern.matcher(content);
       
        boolean containsKeyword = matcher.find();

        if (containsKeyword) {
            return true;
        }
        else{
            return false;
        }
    }

MingAPIService完整代码如下

package com.SmartMed_Connect.service;

import com.SmartMed_Connect.controller.UserController;
import com.SmartMed_Connect.dao.ChatMessageDao;
import com.SmartMed_Connect.dto.MessageWrapper;
import com.SmartMed_Connect.entity.ChatMessage;
import com.SmartMed_Connect.entity.PatientHistory;
import com.SmartMed_Connect.utils.ClientUtil;
import com.SmartMed_Connect.utils.IpUtil;
import com.SmartMed_Connect.utils.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class MingAPIService {


    @Autowired
    protected PatientHistoryService patientHistoryService;

    @Autowired
    private UserController userController;

    @Autowired
    protected UserService userService;

    @Autowired
    private ChatMessageDao chatMessageMapper;
    @Autowired
    private HttpServletRequest request;
    @Value("${ming.url}")
    String mingURL;
    private final List<MessageWrapper> messageCacheList = new ArrayList<>();

    private String createQueryContent(Integer userId,String queryMessage){

        PatientHistory patientHistory = patientHistoryService.findByUserId(userId).get(0);

        String historyString = patientHistory.toString();
        String patientHistoryInfo = "病人的以往病史是:"+historyString+"请你结合这些信息给出相应的建议";

        return queryMessage+patientHistoryInfo;


    }
    public String query(String queryMessage){
        Map<String,Object> params = new HashMap<>();

        params.put("model","ming-moe-4B");
        params.put("n",1);
        params.put("temperature",0.5);
        params.put("max_tokens",3072);

        Integer userId = userController.loginUser.getId();
        String queryContent = queryMessage;
//        List<MessageWrapper> messages;
        if(messageCacheList.isEmpty()){
            fetchUserChatHistory(userId);
            if(messageCacheList.isEmpty()){
                queryContent = createQueryContent(userId,queryMessage);
            }
        }


        if(queryMessage.equals("/newchat")){
            messageCacheList.clear();
            clearUserChatHistory(userId);
            return "已清空聊天记录";
        }

        MessageWrapper userMessage = new MessageWrapper("user",queryContent);
        messageCacheList.add(userMessage);

        params.put("messages",messageCacheList);
        for(MessageWrapper messageWrapper:messageCacheList){
            System.out.println(messageWrapper);
        }

        JSONObject result = ClientUtil.sendPostRequest(mingURL,params);

        System.out.println(result);
        if(result==null){
            return "错误:连接失败";
        }

        JSONArray choices = result.getJSONArray("choices");

        if(choices==null){

            return "choice == null"+result.toJSONString();
        }


        MessageWrapper responseMessage = new MessageWrapper();
        for(int i =0;i<choices.size();++i){
            JSONObject messageJson = choices.getJSONObject(i).getJSONObject("message");

            String role  = messageJson.getString("role");
            String content = messageJson.getString("content");

            responseMessage.setRole(role);
            responseMessage.setContent(content);
        }
        messageCacheList.add(responseMessage);
        saveUserChatHistory(userId,messageCacheList);

        String resultContent = responseMessage.getContent();
        if(checkIfNeedHospitalLocationInfo(queryMessage)){
            String userIP = IpUtil.getIpAddress(request);
            String mapInfo = MapUtil.getAddressByIP(userIP);
            resultContent += mapInfo;
        }
        return resultContent;
    }
    private boolean checkIfNeedHospitalLocationInfo(String content){
        String keyword = "医院";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(keyword);
        // 创建匹配器对象
        Matcher matcher = pattern.matcher(content);
        // 使用 find() 方法查找是否包含关键词
        boolean containsKeyword = matcher.find();

        if (containsKeyword) {
            return true;
        }
        else{
            return false;
        }
    }


    private void clearUserChatHistory(int userId){
        chatMessageMapper.clearChatMessageByUserId(userId);
    }
    private void saveUserChatHistory(Integer userId,List<MessageWrapper> messageList){
        for(MessageWrapper message: messageList){
            ChatMessage chatMessage = new ChatMessage(null, userId, message.getRole(), message.getContent());
            chatMessageMapper.insert(chatMessage);
        }

    }
    private void fetchUserChatHistory(int userId){
        List<ChatMessage> userChatHistory = chatMessageMapper.findChatMessageByUserId(userId);
//        List<MessageWrapper> messageCache = new ArrayList<>();
        if(userChatHistory==null){
            System.out.println("fetch chat history failed");
            return ;
        }
        for(ChatMessage chatMessage:userChatHistory){
            MessageWrapper messageWrapper = new MessageWrapper(chatMessage.getRole(),chatMessage.getContent());
            if(messageWrapper.getRole() !=null&& messageWrapper.getContent()!=null){
                messageCacheList.add(messageWrapper);
            }

        }
    }
}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值