tencent_ocr/.history/pkg/handler/rate_20250115160350.go
2025-01-15 16:09:25 +08:00

177 lines
5.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/generative-ai-go/genai"
"google.golang.org/api/option"
"encoding/json"
"strings"
"git.disbaidu.com/maxwell/tencent_ocr/src/branch/main/pkg/service"
)
type RateHandler struct {
geminiAPIKey string
apiKey string
}
type RateRequest struct {
Content string `json:"content" binding:"required"`
Criteria string `json:"criteria"`
WritingRequirement string `json:"writing_requirement"`
APIKey string `json:"apikey" binding:"required"`
}
type RateResponse struct {
Rate int `json:"rate"`
Summary string `json:"summary"`
DetailedReview string `json:"detailed_review"`
Success bool `json:"success"`
}
func NewRateHandler(geminiAPIKey, apiKey string) *RateHandler {
return &RateHandler{
geminiAPIKey: geminiAPIKey,
apiKey: apiKey,
}
}
func (h *RateHandler) HandleRate(c *gin.Context) {
var req RateRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, RateResponse{
Success: false,
})
return
}
// Validate API key
if req.APIKey != h.apiKey {
c.JSON(http.StatusUnauthorized, RateResponse{
Success: false,
})
return
}
// Initialize Gemini client
ctx := c.Request.Context()
client, err := genai.NewClient(ctx, option.WithAPIKey(h.geminiAPIKey))
if err != nil {
c.JSON(http.StatusInternalServerError, RateResponse{
Success: false,
})
return
}
defer client.Close()
// Prepare criteria
criteria := req.Criteria
if criteria == "" {
criteria = `你是一名语文老师。你正在给学生的作文打分。根据以下中考作文评分标准,给作文打分。
## 评分总分值100分。
### 88-100分 符合题意;写作目的和对象明确;思考充分,立意深刻,感情真挚;选材精当,内容充实;中心突出,条理清晰;表达准确,语言流畅。
### 75-87分 符合题意;写作目的和对象较明确;思考较充分,立意清楚,感情真实;选材合理,内容具体;中心明确,有一定条理;表达较准确,语言通畅。
### 60-74分 符合题意;写作目的和对象较模糊;有一定思考,感情真实;有一定内容;结构基本完整;语言尚通畅。
### 60分以下 不符合题意;缺乏写作目的和对象;基本没有思考,感情虚假;内容空洞;结构混乱;不成篇。`
}
writing_requirement := req.WritingRequirement
if writing_requirement == "" {
writing_requirement = "写一篇不少于600字的作文体裁不限。"
}
// 规定输出格式是json包含rate, summary, detailed_review放入prompt的最后
format := `请按照以下JSON格式输出
{
"rate": 分数, // 最多100分制的分数int类型
"summary": "总体评价", // 100字以内的总体评价string类型
"detailed_review": "详细点评" // 300字以内的详细点评包含优点和建议string类型
}`
// Prepare prompt
prompt := "作文要求:\n" + writing_requirement + "\n\n" + "评分标准:\n" + criteria + format + "\n\n" + "\n\n作文内容\n" + req.Content
// Generate content
model := client.GenerativeModel("gemini-2.0-flash-exp")
resp, err := model.GenerateContent(ctx, genai.Text(prompt))
if err != nil {
c.JSON(http.StatusInternalServerError, RateResponse{
Success: false,
})
return
}
if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 {
if textPart, ok := resp.Candidates[0].Content.Parts[0].(genai.Text); ok {
// Parse the response to extract rate, summary, and detailed review
result := parseRateResponse(string(textPart))
c.JSON(http.StatusOK, RateResponse{
Rate: result.Rate,
Summary: result.Summary,
DetailedReview: result.Detailed,
Success: true,
})
return
}
}
c.JSON(http.StatusInternalServerError, RateResponse{
Success: false,
})
}
type rateResult struct {
Rate int `json:"rate"`
Summary string `json:"summary"`
Detailed string `json:"detailed_review"`
}
func parseRateResponse(response string) rateResult {
var result rateResult
//去除所有\n
response = strings.ReplaceAll(response, "\n", "")
//去除所有\t
response = strings.ReplaceAll(response, "\t", "")
// 去除response中的```json前缀和```后缀
response = strings.TrimSpace(response)
response = strings.TrimPrefix(response, "```json")
response = strings.TrimSuffix(response, "```")
// 检查response是否是json格式
if !strings.HasPrefix(response, "{") {
return rateResult{
Rate: 0,
Summary: "解析失败",
Detailed: "没有左括号",
}
}
if !strings.HasSuffix(response, "}") {
return rateResult{
Rate: 0,
Summary: "解析失败",
Detailed: "没有右括号",
}
}
// 解析json
err := json.Unmarshal([]byte(response), &result)
if err != nil {
return rateResult{
Rate: 0,
Summary: "解析失败",
Detailed: "反序列化失败",
}
}
// 合并所有验证条件
if result.Rate <= 0 || result.Rate > 100 ||
result.Summary == "" || result.Detailed == "" {
return rateResult{
Rate: 0,
Summary: "解析失败",
Detailed: "字段验证条件不满足",
}
}
return result
}