package aiSearch import ( "aiChat/api/aiSearch/v1" "aiChat/internal/model" "aiChat/internal/model/bidSearch" "context" "fmt" "io/ioutil" "strings" "time" "github.com/gogf/gf/v2/util/gconv" . "app.yhyue.com/moapp/jybase/encrypt" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) func (c *ControllerV1) Chat(ctx context.Context, req *v1.ChatReq) (res *v1.ChatRes, err error) { res = &v1.ChatRes{ErrorCode: 0} sid := gconv.Int64(SE.Decode4HexByCheck(req.SId)) if sid == 0 { g.Log().Error(ctx, "无效的sid参数", req.SId) return } startTime := gtime.Now().Format("Y-m-d h:m:s.u") success := 0 prompt := fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoPrompt").String(), gtime.Now().Format("Ymd"), req.Question) large_model := "doubao" callLogs := g.List{} content, largeModelReply, err, isLimit := c.doubao(ctx, prompt) if !isLimit { large_model_success := 1 error_msg := "" if err != nil { error_msg = err.Error() large_model_success = 0 } callLogs = append(callLogs, g.Map{ "large_model": large_model, "large_model_reply": largeModelReply, "large_model_starttime": startTime, "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"), "large_model_success": large_model_success, "error_msg": error_msg, }) } if isLimit || err != nil { prompt = fmt.Sprintf(g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuPrompt").String(), gtime.Now().Format("Ymd"), req.Question) content, largeModelReply, err, _ = c.zhipu(ctx, prompt) large_model = "zhipu" large_model_success := 1 error_msg := "" if err != nil { error_msg = err.Error() large_model_success = 0 } callLogs = append(callLogs, g.Map{ "large_model": large_model, "large_model_reply": largeModelReply, "large_model_starttime": startTime, "large_model_endtime": gtime.Now().Format("Y-m-d h:m:s.u"), "large_model_success": large_model_success, "error_msg": error_msg, }) } large_model_endtime := gtime.Now().Format("Y-m-d h:m:s.u") if err == nil { success = 1 } else { large_model = "" } sess, sessErr := model.GetSession(g.RequestFromCtx(ctx)) if sessErr != nil { return } bs, bsErr := bidSearch.NewBidSearch(ctx, sess.PersonId, content) if bsErr != nil { return } query, list := bs.Search() answer := "" if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { chatId, chatErr := tx.InsertAndGetId("ai_search_chat", g.Map{ "position_id": sess.PositionId, "item": req.Item, "question": req.Question, "answer": answer, "starttime": startTime, "large_model_endtime": large_model_endtime, "endtime": gtime.Now().Format("Y-m-d h:m:s.u"), "success": success, "es_query": query, "list_count": len(list), "session_id": sid, "status": 1, "large_model": large_model, "create_time": gtime.Datetime(), }) if chatErr != nil { g.Log().Error(ctx, "ai_search_chat保存出错", chatErr) return chatErr } // // bids := g.List{} // for _, v := range list { // bids = append(bids, g.Map{ // "position_id": sess.PositionId, // "chat_id": chatId, // }) // } // for _, v := range callLogs { v["chat_id"] = chatId v["create_time"] = gtime.Datetime() } return nil }); err == nil { res.ErrorCode = 1 res.List = list } else { g.Log().Error(ctx, sess.PositionId, "保存数据库出错", err) } return } //调用豆包大模型 func (c *ControllerV1) doubao(ctx context.Context, content string) (string, string, error, bool) { count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_doubaoCall_%s", gtime.Now().Format("Ymd"))) if err != nil { g.Log().Error(ctx, "从redis获取doubao调用次数出错", err) return "", "", err, true } else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "doubaoCallMax").Int64(); count > doubaoCallMax { g.Log().Info(ctx, "doubao调用次数达到上限", doubaoCallMax, count) return "", "", nil, true } // 构造请求数据 messages := []map[string]interface{}{} messages = append(messages, map[string]interface{}{ "role": "user", "content": content, }) //glm-4-air glm-4-0520 glm-4-flash requestData := map[string]interface{}{ "model": "ep-20250207170552-g8dsx", "temperature": 0.1, "top_p": 0.7, "messages": messages, } return c.post(ctx, "doubao", "https://ark.cn-beijing.volces.com/api/v3/chat/completions", "3dd861bf-b8a7-41d4-bb0b-5076362c572d", requestData) } //调用智普大模型 func (c *ControllerV1) zhipu(ctx context.Context, content string) (string, string, error, bool) { count, err := g.Redis("main").Incr(ctx, fmt.Sprintf("aiSearch_zhipuCall_%s", gtime.Now().Format("YYYYmmdd"))) if err != nil { g.Log().Error(ctx, "从redis获取zhipu调用次数出错", err) return "", "", err, true } else if doubaoCallMax := g.Cfg("ai_search.yaml").MustGet(ctx, "zhipuCallMax").Int64(); count > doubaoCallMax { g.Log().Info(ctx, "zhipu调用次数达到上限", doubaoCallMax, count) return "", "", nil, true } // 构造请求数据 messages := []map[string]interface{}{} messages = append(messages, map[string]interface{}{ "role": "user", "content": content, }) //glm-4-air glm-4-0520 glm-4-flash requestData := map[string]interface{}{ "model": "glm-4-flash", "messages": messages, "temperature": 0.1, "max_tokens": 4096, } return c.post(ctx, "zhipu", "https://open.bigmodel.cn/api/paas/v4/chat/completions", "3d84d30b7ab4c94dbf71853cb7e44719.hLLS4CA2MqVQs6kR", requestData) } func (c *ControllerV1) post(ctx context.Context, t, apiURL, pass string, requestData map[string]interface{}) (string, string, error, bool) { ddd := `{ "关键词": { "选择": ["软件"], "排除": [] }, "发布时间范围": "20210126-20250226", "搜索范围": ["标题", "正文"], "匹配模式": "精准匹配", "信息类型": "招标公告", "地区": { "选择": ["广东", "广西", "海南","北京"], "排除": [] }, "金额": "0-2000万", "采购单位联系方式": "不限", "中标单位联系方式": "不限", "附件": "不限", "采购单位": "不限", "中标单位": "不限", "招标代理": "不限" }` return ddd, "", nil, false resp, err := g.Client().Timeout(time.Duration(g.Cfg("ai_search.yaml").MustGet(ctx, "timeout").Int())*time.Second). SetHeader("Authorization", fmt.Sprintf("Bearer %s", pass)). ContentType("application/json"). Post(ctx, apiURL, requestData) if err != nil { g.Log().Error(ctx, t, "请求出错", err) return "", "", err, false } defer resp.Body.Close() b, be := ioutil.ReadAll(resp.Body) if be != nil { g.Log().Error(ctx, t, "gjson.LoadJson出错", be) return "", "", err, false } largeModelReply := string(b) g.Log().Info(ctx, t, "请求回复", largeModelReply) r, re := gjson.LoadJson(b) if re != nil { g.Log().Error(ctx, t, largeModelReply, "gjson.LoadJson出错", re) return "", largeModelReply, err, false } content := "" choices := r.GetJsons("choices") if len(choices) == 0 { return "", largeModelReply, err, false } message := choices[0].GetJson("message") if message == nil { return "", largeModelReply, err, false } content = message.Get("content").String() content = strings.ReplaceAll(content, "```json", "") content = strings.ReplaceAll(content, "```", "") return content, largeModelReply, nil, false }