update
This commit is contained in:
parent
361c133c9c
commit
82848d4dc3
@ -15,7 +15,7 @@ func main() {
|
|||||||
log.Fatalf("Failed to load configuration: %v", err)
|
log.Fatalf("Failed to load configuration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize handler
|
// Initialize handlers
|
||||||
ocrHandler := handler.NewOCRHandler(
|
ocrHandler := handler.NewOCRHandler(
|
||||||
cfg.TencentSecretID,
|
cfg.TencentSecretID,
|
||||||
cfg.TencentSecretKey,
|
cfg.TencentSecretKey,
|
||||||
@ -23,11 +23,17 @@ func main() {
|
|||||||
cfg.APIKey,
|
cfg.APIKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
rateHandler := handler.NewRateHandler(
|
||||||
|
cfg.GeminiAPIKey,
|
||||||
|
cfg.APIKey,
|
||||||
|
)
|
||||||
|
|
||||||
// Setup Gin router
|
// Setup Gin router
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
// Register routes
|
// Register routes
|
||||||
r.POST("/ocr", ocrHandler.HandleOCR)
|
r.POST("/ocr", ocrHandler.HandleOCR)
|
||||||
|
r.POST("/rate", rateHandler.HandleRate)
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
if err := r.Run("localhost:8080"); err != nil {
|
if err := r.Run("localhost:8080"); err != nil {
|
||||||
|
|||||||
176
pkg/handler/rate.go
Normal file
176
pkg/handler/rate.go
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user