package ai_model_cli import ( "context" "fmt" "goskeleton/app/global/variable" "os" "strings" "goskeleton/app/global/consts" "github.com/baidubce/bce-qianfan-sdk/go/qianfan" "github.com/gin-gonic/gin" ) func RequestStyle(c *gin.Context) (interface{}, error) { // userMsg := c.PostForm("user_input") userMsg := c.GetString(consts.ValidatorPrefix + "user_input") qianfan.GetConfig().AccessKey = variable.ConfigYml.GetString("BaiduCE.QianFanAccessKey") qianfan.GetConfig().SecretKey = variable.ConfigYml.GetString("BaiduCE.QianFanSecretKey") chat := qianfan.NewChatCompletion( qianfan.WithModel("ERNIE-4.0-8K"), ) chatHistory := []qianfan.ChatCompletionMessage{} // 读取prompt文件 systemMsgPath := variable.ConfigYml.GetString("BaiduCE.StyleGeneratePromptPath") // 读取文件内容 prompt, err := os.ReadFile(variable.BasePath + systemMsgPath) if err != nil || len(prompt) == 0 { variable.ZapLog.Error(fmt.Sprintf("读取提示词文件失败: %v", err)) return nil, err } // add user history to chat history userHistory, exist := c.Get(consts.ValidatorPrefix + "chat_history") if exist && userHistory != nil { // check if userHistory is of type []struct{Role string;Content string} historySlice, ok := userHistory.([]interface{}) if !ok || len(historySlice)%2 != 0 { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v", userHistory)) return nil, fmt.Errorf("用户历史对话格式错误") } // convert userHistory to []qianfan.ChatCompletionMessage var chatHistoryConverted []qianfan.ChatCompletionMessage for _, item := range historySlice { if itemMap, ok := item.(map[string]interface{}); ok { role, roleOk := itemMap["role"].(string) content, contentOk := itemMap["content"].(string) if roleOk && contentOk { chatHistoryConverted = append(chatHistoryConverted, qianfan.ChatCompletionMessage{ Role: role, Content: content, }) } else { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\nrole 或 content 类型断言失败", userHistory)) return nil, fmt.Errorf("用户历史对话格式错误") } } else { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\n无法将 item 转换为 map[string]interface{}", userHistory)) return nil, fmt.Errorf("用户历史对话格式错误") } } if len(chatHistoryConverted) > 0 && len(chatHistoryConverted)%2 == 0 { chatHistory = append(chatHistory, chatHistoryConverted...) } } // add user input to chat history chatHistory = append(chatHistory, qianfan.ChatCompletionUserMessage(userMsg)) response, err := chat.Do(context.TODO(), &qianfan.ChatCompletionRequest{System: string(prompt), Messages: chatHistory}) if err != nil { variable.ZapLog.Error(fmt.Sprintf("对话失败: %v", err)) return nil, err } return response.Result, nil } func RequestStyleStream(c *gin.Context) error { userMsg := c.GetString(consts.ValidatorPrefix + "user_input") chatHistory := []qianfan.ChatCompletionMessage{} systemMsgPath := variable.ConfigYml.GetString("BaiduCE.StyleGeneratePromptPath") prompt, err := os.ReadFile(variable.BasePath + systemMsgPath) if err != nil || len(prompt) == 0 { variable.ZapLog.Error(fmt.Sprintf("读取提示词文件失败: %v", err)) return err } userHistory, exist := c.Get(consts.ValidatorPrefix + "chat_history") if exist && userHistory != nil { historySlice, ok := userHistory.([]interface{}) if !ok || len(historySlice)%2 != 0 { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v", userHistory)) return fmt.Errorf("用户历史对话格式错误") } var chatHistoryConverted []qianfan.ChatCompletionMessage for _, item := range historySlice { if itemMap, ok := item.(map[string]interface{}); ok { role, roleOk := itemMap["role"].(string) content, contentOk := itemMap["content"].(string) if roleOk && contentOk { chatHistoryConverted = append(chatHistoryConverted, qianfan.ChatCompletionMessage{ Role: role, Content: content, }) } else { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\nrole 或 content 类型断言失败", userHistory)) return fmt.Errorf("用户历史对话格式错误") } } else { variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\n无法将 item 转换为 map[string]interface{}", userHistory)) return fmt.Errorf("用户历史对话格式错误") } } if len(chatHistoryConverted) > 0 && len(chatHistoryConverted)%2 == 0 { chatHistory = append(chatHistory, chatHistoryConverted...) } } chatHistory = append(chatHistory, qianfan.ChatCompletionUserMessage(userMsg)) return ChatByStream(c, string(prompt), chatHistory) } func RequestLayout(c *gin.Context) error { doc_content := c.GetString(consts.ValidatorPrefix + "doc_content") chatHistory := []qianfan.ChatCompletionMessage{} systemMsgPath := variable.ConfigYml.GetString("BaiduCE.LayoutGeneratePromptPath") prompt, err := os.ReadFile(variable.BasePath + systemMsgPath) if err != nil || len(prompt) == 0 { variable.ZapLog.Error(fmt.Sprintf("读取提示词文件失败: %v", err)) return err } chatHistory = append(chatHistory, qianfan.ChatCompletionUserMessage("待排版内容\n"+doc_content)) return ChatByStream(c, string(prompt), chatHistory) } func ChatByStream(c *gin.Context, prompt string, chatHistory []qianfan.ChatCompletionMessage) error{ qianfan.GetConfig().AccessKey = variable.ConfigYml.GetString("BaiduCE.QianFanAccessKey") qianfan.GetConfig().SecretKey = variable.ConfigYml.GetString("BaiduCE.QianFanSecretKey") chat := qianfan.NewChatCompletion( qianfan.WithModel("ERNIE-4.0-8K"), ) stream, err := chat.Stream(context.TODO(), &qianfan.ChatCompletionRequest{System: string(prompt), Messages: chatHistory}) if err != nil { variable.ZapLog.Error(fmt.Sprintf("对话失败: %v", err)) return err } defer stream.Close() c.Writer.Flush() defer c.Writer.Flush() outputMsg:=strings.Builder{} for { response, err := stream.Recv() if response.IsEnd { break // 流结束,退出循环 } if err != nil { variable.ZapLog.Error(fmt.Sprintf("接收流失败: %v", err)) return err } // 将结果写入到响应体 outputMsg.WriteString(response.Result) if _, err := fmt.Fprintf(c.Writer, "%s", response.Result); err != nil { variable.ZapLog.Error(fmt.Sprintf("写入流失败: %v", err)) return err } // 立即刷新缓冲区,以确保数据立即发送到客户端 c.Writer.Flush() } return nil // 正常结束,返回 nil }