answer.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package model
  2. import (
  3. v1 "aiChat/api/aiChat/v1"
  4. "aiChat/utility/fsw"
  5. . "app.yhyue.com/moapp/jybase/common"
  6. "app.yhyue.com/moapp/jybase/date"
  7. "app.yhyue.com/moapp/jybase/encrypt"
  8. "bufio"
  9. "context"
  10. "fmt"
  11. "github.com/gogf/gf/v2/frame/g"
  12. "github.com/gogf/gf/v2/util/gconv"
  13. "io"
  14. "strings"
  15. "time"
  16. )
  17. var (
  18. Answer = &cAnswer{}
  19. )
  20. type cAnswer struct {
  21. }
  22. // FindAnswer 获取答案
  23. func (l *cAnswer) FindAnswer(ctx context.Context, answerReq *v1.FindAnswerReq) (rs *v1.FindAnswerRes, err error) {
  24. defer Catch()
  25. jSession := SessionCtx.Get(ctx).JSession
  26. second := g.Cfg().MustGet(ctx, "history.time").Int()
  27. limit := g.Cfg().MustGet(ctx, "history.limit").Int()
  28. historyData := getHistory(ctx, jSession.PositionId, second, limit)
  29. // 查一分钟内的10条 历史信息
  30. req, from := &QuestionReq{
  31. Href: answerReq.Href,
  32. BaseQuestion: &BaseQuestion{
  33. Prompt: answerReq.Prompt,
  34. History: historyData,
  35. },
  36. }, 0
  37. questionId := ChatHistory.Save(ctx, &ChatRecord{
  38. Content: req.Prompt,
  39. Type: 1,
  40. Refer: req.Href,
  41. PersonId: jSession.PositionId,
  42. CreateTime: time.Now().Format(date.Date_Full_Layout),
  43. })
  44. content, res, replyId, errMsg := func() (string, io.ReadCloser, int64, error) {
  45. var (
  46. err error
  47. res io.ReadCloser
  48. reply string
  49. )
  50. errReply := func() string {
  51. // 校验是否在黑名单,黑名单不返回内容
  52. if UserBlackList.CheckBlackList(ctx, jSession.PositionId) {
  53. return g.Cfg().MustGet(ctx, "limit.blackMsg").String()
  54. }
  55. // 校验问答频率
  56. if ChatLimit.GetBucket(ctx, jSession.PositionId).TakeAvailable(1) == 0 {
  57. return g.Cfg().MustGet(ctx, "limit.exceedMsg").String()
  58. }
  59. // 问题敏感词过滤
  60. if fsw.Match(req.Prompt) {
  61. return g.Cfg().MustGet(ctx, "limit.fswMsg").String()
  62. }
  63. return ""
  64. }()
  65. if errReply != "" {
  66. reply, from = errReply, -1
  67. } else {
  68. reply, res, from, err = Question.DetailQuestion(ctx, req)
  69. if err != nil {
  70. g.Log().Error(ctx, "问答异常", err)
  71. reply = g.Cfg().MustGet(ctx, "limit.errMsg").String()
  72. errReply = g.Cfg().MustGet(ctx, "limit.errMsg").String()
  73. }
  74. }
  75. if from == Answer_ChatGPT {
  76. return reply, res, 0, nil
  77. }
  78. if reply == "" {
  79. reply = g.Cfg().MustGet(ctx, "limit.emptyMsg").String()
  80. errReply = g.Cfg().MustGet(ctx, "limit.emptyMsg").String()
  81. }
  82. replyId := ChatHistory.Save(ctx, &ChatRecord{
  83. Content: reply,
  84. Type: 2,
  85. Actions: gconv.Int(If(errReply == "", 1, 0)),
  86. QuestionId: questionId,
  87. PersonId: jSession.PositionId,
  88. Item: from,
  89. CreateTime: time.Now().Format(date.Date_Full_Layout),
  90. })
  91. if replyId <= 0 {
  92. g.Log().Error(ctx, "问答存储存储异常")
  93. }
  94. if errReply != "" {
  95. return reply, nil, replyId, fmt.Errorf(errReply)
  96. }
  97. return reply, nil, replyId, nil
  98. }()
  99. if res != nil {
  100. defer res.Close()
  101. }
  102. if from != Answer_ChatGPT {
  103. if errMsg != nil {
  104. rs = &v1.FindAnswerRes{ErrorCode: -1, ErrorMsg: errMsg.Error(), Data: nil}
  105. } else {
  106. rs = &v1.FindAnswerRes{ErrorCode: 0, ErrorMsg: "", Data: g.Map{"id": encrypt.SE.Encode2Hex(fmt.Sprintf("%d", replyId)), "reply": content, "isEnd": true}}
  107. }
  108. } else if res != nil {
  109. buf, lastData := bufio.NewReader(res), &BufRes{}
  110. isEmpty := true
  111. for {
  112. line, _, err := buf.ReadLine()
  113. if err == nil {
  114. break
  115. }
  116. if _, data := parseEventStream(line); data != nil && strings.TrimSpace(data.Response) != "" {
  117. data.Response = fsw.Repl(data.Response)
  118. lastData, isEmpty = data, false
  119. rs = &v1.FindAnswerRes{ErrorCode: 0, ErrorMsg: "", Data: g.Map{"reply": lastData.Response, "isEnd": false}}
  120. }
  121. }
  122. ChatGptPool.Add() //放回链接池
  123. finalReply := If(isEmpty, g.Cfg().MustGet(ctx, "limit.emptyMsg").String(), lastData.Response).(string)
  124. replyId := ChatHistory.Save(ctx, &ChatRecord{
  125. Content: finalReply,
  126. Type: 2,
  127. Actions: gconv.Int(If(isEmpty, 0, 1)),
  128. QuestionId: questionId,
  129. PersonId: jSession.PositionId,
  130. Item: Answer_ChatGPT,
  131. CreateTime: time.Now().Format(date.Date_Full_Layout),
  132. })
  133. if !isEmpty {
  134. rs = &v1.FindAnswerRes{ErrorCode: 0, ErrorMsg: "", Data: g.Map{"id": encrypt.SE.Encode2Hex(fmt.Sprintf("%d", replyId)), "reply": finalReply, "isEnd": true}}
  135. } else {
  136. rs = &v1.FindAnswerRes{ErrorCode: -1, ErrorMsg: finalReply}
  137. }
  138. }
  139. if rs.ErrorMsg != "" {
  140. exceedMsg := g.Cfg().MustGet(ctx, "limit.exceedMsg").String()
  141. fswMsg := g.Cfg().MustGet(ctx, "limit.fswMsg").String()
  142. blackMsg := g.Cfg().MustGet(ctx, "limit.blackMsg").String()
  143. errMsg := g.Cfg().MustGet(ctx, "limit.errMsg").String()
  144. emptyMsg := g.Cfg().MustGet(ctx, "limit.emptyMsg").String()
  145. if rs.ErrorMsg == exceedMsg || rs.ErrorMsg == fswMsg || rs.ErrorMsg == blackMsg || rs.ErrorMsg == errMsg || rs.ErrorMsg == emptyMsg {
  146. rs.ErrorCode = 0
  147. }
  148. }
  149. return rs, nil
  150. }
  151. type historyData struct {
  152. Question string
  153. Answer string
  154. }
  155. func getHistory(ctx context.Context, personId int64, second, limit int) [][]string {
  156. qStr := `SELECT a. content as question,b.content as answer FROM base_service.ai_message_history a, ai_message_history b where a.person_id=%d and a.create_time>"%s" and b.question_id = a.id order by a.create_time desc limit %d`
  157. st, _ := time.ParseDuration(fmt.Sprintf("-%ds", second))
  158. rs_ := []historyData{}
  159. time_ := time.Now().Add(st)
  160. createTime := date.FormatDate(&time_, date.Date_Full_Layout)
  161. query := fmt.Sprintf(qStr, personId, createTime, limit)
  162. err := g.Model("ai_message_history").Raw(query).Scan(&rs_)
  163. if err != nil {
  164. g.Log().Errorf(ctx, "获取历史记录失败:%v", err)
  165. }
  166. rs := [][]string{}
  167. for i := 0; i < len(rs_); i++ {
  168. rs = append(rs, []string{rs_[i].Question, rs_[i].Answer})
  169. }
  170. return rs
  171. }