aiSearch_v1_chat.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package aiSearch
  2. import (
  3. "aiChat/api/aiSearch/v1"
  4. "aiChat/internal/model"
  5. "aiChat/internal/model/bidSearch"
  6. "context"
  7. "fmt"
  8. "io/ioutil"
  9. "strings"
  10. "time"
  11. "github.com/gogf/gf/v2/util/gconv"
  12. . "app.yhyue.com/moapp/jybase/encrypt"
  13. "github.com/gogf/gf/v2/database/gdb"
  14. "github.com/gogf/gf/v2/encoding/gjson"
  15. "github.com/gogf/gf/v2/frame/g"
  16. "github.com/gogf/gf/v2/os/gtime"
  17. )
  18. func (c *ControllerV1) Chat(ctx context.Context, req *v1.ChatReq) (res *v1.ChatRes, err error) {
  19. res = &v1.ChatRes{ErrorCode: 0}
  20. sid := gconv.Int64(SE.Decode4HexByCheck(req.SId))
  21. if sid == 0 {
  22. g.Log().Error(ctx, "无效的sid参数", req.SId)
  23. return
  24. }
  25. startTime := gtime.Now().Format("Y-m-d h:m:s.u")
  26. success := 0
  27. prompt := fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoPrompt").String(), gtime.Now().Format("Ymd"), req.Question)
  28. large_model := "doubao"
  29. callLogs := g.List{}
  30. content, largeModelReply, err, isLimit := c.doubao(ctx, prompt)
  31. if !isLimit {
  32. large_model_success := 1
  33. error_msg := ""
  34. if err != nil {
  35. error_msg = err.Error()
  36. large_model_success = 0
  37. }
  38. callLogs = append(callLogs, g.Map{
  39. "large_model": large_model,
  40. "large_model_reply": largeModelReply,
  41. "large_model_starttime": startTime,
  42. "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
  43. "large_model_success": large_model_success,
  44. "error_msg": error_msg,
  45. })
  46. }
  47. if isLimit || err != nil {
  48. prompt = fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuPrompt").String(), gtime.Now().Format("Ymd"), req.Question)
  49. content, largeModelReply, err, _ = c.zhipu(ctx, prompt)
  50. large_model = "zhipu"
  51. large_model_success := 1
  52. error_msg := ""
  53. if err != nil {
  54. error_msg = err.Error()
  55. large_model_success = 0
  56. }
  57. callLogs = append(callLogs, g.Map{
  58. "large_model": large_model,
  59. "large_model_reply": largeModelReply,
  60. "large_model_starttime": startTime,
  61. "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
  62. "large_model_success": large_model_success,
  63. "error_msg": error_msg,
  64. })
  65. }
  66. large_model_endtime := gtime.Now().Format("Y-m-d h:m:s.u")
  67. if err == nil {
  68. success = 1
  69. } else {
  70. large_model = ""
  71. }
  72. sess, sessErr := model.GetSession(g.RequestFromCtx(ctx))
  73. if sessErr != nil {
  74. return
  75. }
  76. bs, bsErr := bidSearch.NewBidSearch(ctx, sess.PersonId, content)
  77. if bsErr != nil {
  78. return
  79. }
  80. query, list := bs.Search()
  81. answer := ""
  82. if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
  83. chatId, chatErr := tx.InsertAndGetId("ai_search_chat", g.Map{
  84. "position_id": sess.PositionId,
  85. "item": req.Item,
  86. "question": req.Question,
  87. "answer": answer,
  88. "starttime": startTime,
  89. "large_model_endtime": large_model_endtime,
  90. "endtime": gtime.Now().Format("Y-m-d h:m:s.u"),
  91. "success": success,
  92. "es_query": query,
  93. "list_count": len(list),
  94. "session_id": sid,
  95. "status": 1,
  96. "large_model": large_model,
  97. "create_time": gtime.Datetime(),
  98. })
  99. if chatErr != nil {
  100. g.Log().Error(ctx, "ai_search_chat保存出错", chatErr)
  101. return chatErr
  102. }
  103. //
  104. // bids := g.List{}
  105. // for _, v := range list {
  106. // bids = append(bids, g.Map{
  107. // "position_id": sess.PositionId,
  108. // "chat_id": chatId,
  109. // })
  110. // }
  111. //
  112. for _, v := range callLogs {
  113. v["chat_id"] = chatId
  114. v["create_time"] = gtime.Datetime()
  115. }
  116. return nil
  117. }); err == nil {
  118. res.ErrorCode = 1
  119. res.List = list
  120. } else {
  121. g.Log().Error(ctx, sess.PositionId, "保存数据库出错", err)
  122. }
  123. return
  124. }
  125. //调用豆包大模型
  126. func (c *ControllerV1) doubao(ctx context.Context, content string) (string, string, error, bool) {
  127. count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_doubaoCall_%s", gtime.Now().Format("Ymd")))
  128. if err != nil {
  129. g.Log().Error(ctx, "从redis获取doubao调用次数出错", err)
  130. return "", "", err, true
  131. } else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoCallMax").Int64(); count > doubaoCallMax {
  132. g.Log().Info(ctx, "doubao调用次数达到上限", doubaoCallMax, count)
  133. return "", "", nil, true
  134. }
  135. // 构造请求数据
  136. messages := []map[string]interface{}{}
  137. messages = append(messages, map[string]interface{}{
  138. "role": "user",
  139. "content": content,
  140. })
  141. //glm-4-air glm-4-0520 glm-4-flash
  142. requestData := map[string]interface{}{
  143. "model": "ep-20250207170552-g8dsx",
  144. "temperature": 0.1,
  145. "top_p": 0.7,
  146. "messages": messages,
  147. }
  148. return c.post(ctx, "doubao", "https://ark.cn-beijing.volces.com/api/v3/chat/completions", "3dd861bf-b8a7-41d4-bb0b-5076362c572d", requestData)
  149. }
  150. //调用智普大模型
  151. func (c *ControllerV1) zhipu(ctx context.Context, content string) (string, string, error, bool) {
  152. count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_zhipuCall_%s", gtime.Now().Format("YYYYmmdd")))
  153. if err != nil {
  154. g.Log().Error(ctx, "从redis获取zhipu调用次数出错", err)
  155. return "", "", err, true
  156. } else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuCallMax").Int64(); count > doubaoCallMax {
  157. g.Log().Info(ctx, "zhipu调用次数达到上限", doubaoCallMax, count)
  158. return "", "", nil, true
  159. }
  160. // 构造请求数据
  161. messages := []map[string]interface{}{}
  162. messages = append(messages, map[string]interface{}{
  163. "role": "user",
  164. "content": content,
  165. })
  166. //glm-4-air glm-4-0520 glm-4-flash
  167. requestData := map[string]interface{}{
  168. "model": "glm-4-flash",
  169. "messages": messages,
  170. "temperature": 0.1,
  171. "max_tokens": 4096,
  172. }
  173. return c.post(ctx, "zhipu", "https://open.bigmodel.cn/api/paas/v4/chat/completions", "3d84d30b7ab4c94dbf71853cb7e44719.hLLS4CA2MqVQs6kR", requestData)
  174. }
  175. func (c *ControllerV1) post(ctx context.Context, t, apiURL, pass string, requestData map[string]interface{}) (string, string, error, bool) {
  176. ddd := `{
  177. "关键词": {
  178. "选择": ["软件"],
  179. "排除": []
  180. },
  181. "发布时间范围": "20210126-20250226",
  182. "搜索范围": ["标题", "正文"],
  183. "匹配模式": "精准匹配",
  184. "信息类型": "招标公告",
  185. "地区": {
  186. "选择": ["广东", "广西", "海南","北京"],
  187. "排除": []
  188. },
  189. "金额": "0-2000万",
  190. "采购单位联系方式": "不限",
  191. "中标单位联系方式": "不限",
  192. "附件": "不限",
  193. "采购单位": "不限",
  194. "中标单位": "不限",
  195. "招标代理": "不限"
  196. }`
  197. return ddd, "", nil, false
  198. resp, err := g.Client().Timeout(time.Duration(g.Cfg("ai_search.yaml").MustGet(ctx, "timeout").Int())*time.Second).
  199. SetHeader("Authorization", fmt.Sprintf("Bearer %s", pass)).
  200. ContentType("application/json").
  201. Post(ctx, apiURL, requestData)
  202. if err != nil {
  203. g.Log().Error(ctx, t, "请求出错", err)
  204. return "", "", err, false
  205. }
  206. defer resp.Body.Close()
  207. b, be := ioutil.ReadAll(resp.Body)
  208. if be != nil {
  209. g.Log().Error(ctx, t, "gjson.LoadJson出错", be)
  210. return "", "", err, false
  211. }
  212. largeModelReply := string(b)
  213. g.Log().Info(ctx, t, "请求回复", largeModelReply)
  214. r, re := gjson.LoadJson(b)
  215. if re != nil {
  216. g.Log().Error(ctx, t, largeModelReply, "gjson.LoadJson出错", re)
  217. return "", largeModelReply, err, false
  218. }
  219. content := ""
  220. choices := r.GetJsons("choices")
  221. if len(choices) == 0 {
  222. return "", largeModelReply, err, false
  223. }
  224. message := choices[0].GetJson("message")
  225. if message == nil {
  226. return "", largeModelReply, err, false
  227. }
  228. content = message.Get("content").String()
  229. content = strings.ReplaceAll(content, "```json", "")
  230. content = strings.ReplaceAll(content, "```", "")
  231. return content, largeModelReply, nil, false
  232. }