diff --git a/bin/deploy.sh b/bin/deploy.sh index 637dad6..c1920ed 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -11,6 +11,9 @@ TIMESTAMP=$(date +"%Y%m%d_%H%M%S") ENV=${1:-prod} # 运行时可以传入 `dev` 或 `prod` CONFIG_FILE="conf/config.${ENV}.toml" +# 切换到上一级目录执行 +cd ../ + # 检查本地文件是否存在 if [[ ! -f "bin/aigrammar" || ! -f "bin/service.sh" || ! -f "$CONFIG_FILE" ]]; then echo "❌ 关键文件不存在,请检查 bin/aigrammar, bin/service.sh, $CONFIG_FILE" diff --git a/conf/config.prod.toml b/conf/config.prod.toml index 6efe0b1..1b0065c 100644 --- a/conf/config.prod.toml +++ b/conf/config.prod.toml @@ -1,6 +1,6 @@ [base] jwt_secret = "mCTf-JhNRnhaaGJy_x" -bind_addr = ":8090" +bind_addr = ":1090" [log] echo_log_file = "../log/echo.log" @@ -11,8 +11,13 @@ max_age = 28 compress = true level = "debug" - [azure_openai] +endpoint = "https://tokenhub-intl.tencentmaas.com/v1/chat/completions" +keys = "sk-ZPq9H7eLHEDoK1mCeyBXtgDlGkj3XBAsTkJHsvASwwRxeARs" +gpt4_model = "hy3-preview" +gpt35_model = "hy3-preview" + +[azure_openai_1] endpoint = "https://grammar.openai.azure.com/" keys = "8b68c235b737488ab9a99983a14f8cca,0274ccde58aa47b189f0d13349885ad3" gpt4_model = "gpt4" diff --git a/conf/config.toml b/conf/config.toml index 217774d..4d3ad30 100644 --- a/conf/config.toml +++ b/conf/config.toml @@ -12,8 +12,13 @@ max_age = 28 compress = true level = "debug" - [azure_openai] +endpoint = "https://tokenhub-intl.tencentmaas.com/v1/chat/completions" +keys = "sk-ZPq9H7eLHEDoK1mCeyBXtgDlGkj3XBAsTkJHsvASwwRxeARs" +gpt4_model = "hy3-preview" +gpt35_model = "hy3-preview" + +[azure_openai_1] endpoint = "https://grammar.openai.azure.com/" keys = "8b68c235b737488ab9a99983a14f8cca,0274ccde58aa47b189f0d13349885ad3" gpt4_model = "gpt4" diff --git a/src/translate.go b/src/translate.go index fd427d8..150d0a8 100644 --- a/src/translate.go +++ b/src/translate.go @@ -7,6 +7,8 @@ import ( "fmt" "net/http" "strings" + "io" + "bytes" "github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai" "github.com/Azure/azure-sdk-for-go/sdk/azcore" @@ -167,7 +169,7 @@ func TranslateFeedBackHandler(c echo.Context) error { } -// gTranslate 调用Azure OpenAI的翻译接口 +// gTranslate 调用openai 格式翻译接口 func gTranslate(input string, prompt string) (string, error, int) { // get azure openai config configManager, err := GetConfigManager() @@ -181,6 +183,106 @@ func gTranslate(input string, prompt string) (string, error, int) { modelDeploymentID := azureConfig.GPT4Model azureOpenAIEndpoint := azureConfig.Endpoint + body, _ := json.Marshal(map[string]interface{}{ + "model": modelDeploymentID, + "messages": []map[string]string{ + {"role": "system", "content": prompt}, + {"role": "user", "content": input}, + }, + "temperature": 0.9, + }) + + req, _ := http.NewRequest("POST", + azureOpenAIEndpoint, + bytes.NewBuffer(body)) + req.Header.Set("Authorization", "Bearer "+azureOpenAIKey) + req.Header.Set("Content-Type", "application/json") + // 增加异常判断 + + resp, err := http.DefaultClient.Do(req) + if err != nil { + logger.Error("send openai request failed", zap.Error(err)) + return "", errors.New("request openai failed"), ERR_COMM_SVR_WRONG + } + defer resp.Body.Close() // 确保一定关闭 + + // 4. HTTP 状态码判断(非 200 都算异常) + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + logger.Error("openai response status code error", zap.Int("code", resp.StatusCode)) + return "", fmt.Errorf("http status code: %d", resp.StatusCode), ERR_COMM_SVR_WRONG + } + + // 5. 读取 body 错误处理 + data, err := io.ReadAll(resp.Body) + if err != nil { + logger.Error("read response body failed", zap.Error(err)) + return "", errors.New("read response error"), ERR_COMM_SVR_WRONG + } + // ===================== 核心修改:解析 OpenAI 返回 JSON ===================== + type ChatMessage struct { + Role string `json:"role"` + Content string `json:"content"` + } + + type Choice struct { + Index int `json:"index"` + Message ChatMessage `json:"message"` + FinishReason string `json:"finish_reason"` + } + + type OpenAIResponse struct { + Choices []Choice `json:"choices"` + } + + var respData OpenAIResponse + // 校验是否合法 JSON + if err := json.Unmarshal(data, &respData); err != nil { + logger.Error("parse openai response json failed", zap.Error(err), zap.String("response", string(data))) + return "", errors.New("invalid response json"), ERR_COMM_SVR_WRONG + } + + // 无结果 + if len(respData.Choices) == 0 { + logger.Error("openai response choices is empty", zap.String("response", string(data))) + return "", errors.New("no choices in response"), ERR_COMM_SVR_WRONG + } + + // 按 index 顺序拼接 assistant content + var result string + for _, choice := range respData.Choices { + if choice.Message.Role == "assistant" { + result += choice.Message.Content + } + } + + // 获取最后一个 finish_reason + lastChoice := respData.Choices[len(respData.Choices)-1] + if lastChoice.FinishReason != "stop" { + logger.Error("openai response not finished normally", + zap.String("finish_reason", lastChoice.FinishReason), + zap.String("result", result)) + return "", fmt.Errorf("abnormal finish reason: %s", lastChoice.FinishReason), ERR_COMM_SVR_WRONG + } + + // 正常返回 + logger.Info("openai translate success", zap.Int("choice_count", len(respData.Choices))) + return result, nil, 0 +} + +// gTranslate 调用Azure OpenAI的翻译接口 +func gTranslate_openai(input string, prompt string) (string, error, int) { + // get azure openai config + configManager, err := GetConfigManager() + if err != nil { + logger.Error("GetConfigManager error.", zap.Error(err)) + return "", errors.New("Get Config error."), ERR_COMM_SVR_WRONG + } + azureConfig := configManager.GetAzureConfig() + + azureOpenAIKey := azureConfig.Keys[0] + modelDeploymentID := azureConfig.GPT4Model + azureOpenAIEndpoint := azureConfig.Endpoint + // API密钥认证 cred := azcore.NewKeyCredential(azureOpenAIKey)