AiController.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package org.lp.medicalai.controller;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import org.lp.medicalai.component.MemoryUserRecordSpace;
  5. import org.lp.medicalai.component.XfXhStreamClient;
  6. import org.lp.medicalai.config.XfXhConfig;
  7. import org.lp.medicalai.dto.InteractMsg;
  8. import org.lp.medicalai.dto.MsgDTO;
  9. import org.lp.medicalai.dto.RecordsArray;
  10. import org.lp.medicalai.listener.XfXhWebSocketListener;
  11. import okhttp3.WebSocket;
  12. import org.lp.medicalai.pojo.Result;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.web.bind.annotation.*;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.Map;
  18. import java.util.UUID;
  19. import java.util.concurrent.ConcurrentHashMap;
  20. @RestController
  21. @RequestMapping("/medical-ai")
  22. public class AiController {
  23. @Autowired
  24. private XfXhConfig xfXhConfig;
  25. @Autowired
  26. private XfXhStreamClient xfXhStreamClient;
  27. @Autowired
  28. private MemoryUserRecordSpace memoryUserRecordSpace;
  29. // 使用 id 作为唯一用户的标识(区分不同用户)
  30. @GetMapping("/sendQuestion")
  31. public Result question(@RequestAttribute("id") Integer id,String question) throws InterruptedException {
  32. if (StrUtil.isBlank(question)) {
  33. return Result.error("NO_QUESTION");//无效问题,请重新输入
  34. }
  35. // 尝试锁定用户
  36. if (!memoryUserRecordSpace.tryLock(id)) {
  37. return Result.error("WAIT");//正在处理上次问题,请稍后再试
  38. }
  39. // 获取连接令牌
  40. if(!xfXhStreamClient.operateToken(XfXhStreamClient.GET_TOKEN_STATUS)){
  41. // 释放锁
  42. memoryUserRecordSpace.unLock(id);
  43. return Result.error("BUSY");//当前大模型连接数过多,请稍后再试
  44. }
  45. MsgDTO msgDTO = MsgDTO.createUserMsg(question);
  46. String tip = "你是一位专业且耐心的医生,专注于提供医疗建议。非医疗问题请礼貌拒绝。";
  47. MsgDTO tipDTO = MsgDTO.createSystemMsg(tip);
  48. XfXhWebSocketListener listener = new XfXhWebSocketListener();
  49. // 组装上下文内容发送
  50. List<MsgDTO> msgList = memoryUserRecordSpace.getAllInteractMsg(id);
  51. msgList.add(tipDTO);
  52. msgList.add(msgDTO);
  53. WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), msgList, listener);
  54. if (webSocket == null) {
  55. // 归还令牌
  56. xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
  57. // 释放锁
  58. memoryUserRecordSpace.unLock(id);
  59. return Result.error("ERROR");//系统内部错误,请联系管理员
  60. }
  61. try {
  62. int count = 0;
  63. // 为了避免死循环,设置循环次数来定义超时时长
  64. int maxCount = xfXhConfig.getMaxResponseTime() * 5;
  65. while (count <= maxCount) {
  66. Thread.sleep(200);
  67. if (listener.isWsCloseFlag()) {
  68. break;
  69. }
  70. count++;
  71. }
  72. if (count > maxCount) {
  73. return Result.error("ERROR");//大模型响应超时,请联系管理员
  74. }
  75. // 将记录添加到 memoryUserRecordSpace
  76. String answer = listener.getAnswer().toString();
  77. memoryUserRecordSpace.storeInteractMsg(id, new InteractMsg(MsgDTO.createUserMsg(question), MsgDTO.createAssistantMsg(answer)));
  78. return Result.success(answer);//相应成功
  79. } finally {
  80. // 关闭连接
  81. webSocket.close(1000, "");
  82. // 释放锁
  83. memoryUserRecordSpace.unLock(id);
  84. // 归还令牌
  85. xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
  86. }
  87. }
  88. // 测试使用,查看内存空间中所有的用户记录信息
  89. @GetMapping("/spaceInfo")
  90. public List<JSONObject> spaceInfo(@RequestAttribute("id") Integer id){
  91. if(id == 1){
  92. ConcurrentHashMap<Long, RecordsArray> userRecordMap = memoryUserRecordSpace.getUserRecordMap();
  93. ArrayList<JSONObject> infoList = new ArrayList<>(userRecordMap.size());
  94. for (Map.Entry<Long, RecordsArray> entry : userRecordMap.entrySet()) {
  95. RecordsArray recordsArray = entry.getValue();
  96. JSONObject data = new JSONObject();
  97. data.put("id",entry.getKey());
  98. data.put("allInteractMsg",recordsArray.getAllInteractMsg());
  99. data.put("status",recordsArray.getStatus());
  100. data.put("lock",recordsArray.isLock());
  101. infoList.add(data);
  102. }
  103. return infoList;
  104. }
  105. return null;
  106. }
  107. }