update
This commit is contained in:
parent
361c133c9c
commit
82848d4dc3
@ -15,7 +15,7 @@ func main() {
|
||||
log.Fatalf("Failed to load configuration: %v", err)
|
||||
}
|
||||
|
||||
// Initialize handler
|
||||
// Initialize handlers
|
||||
ocrHandler := handler.NewOCRHandler(
|
||||
cfg.TencentSecretID,
|
||||
cfg.TencentSecretKey,
|
||||
@ -23,11 +23,17 @@ func main() {
|
||||
cfg.APIKey,
|
||||
)
|
||||
|
||||
rateHandler := handler.NewRateHandler(
|
||||
cfg.GeminiAPIKey,
|
||||
cfg.APIKey,
|
||||
)
|
||||
|
||||
// Setup Gin router
|
||||
r := gin.Default()
|
||||
|
||||
// Register routes
|
||||
r.POST("/ocr", ocrHandler.HandleOCR)
|
||||
r.POST("/rate", rateHandler.HandleRate)
|
||||
|
||||
// Start server
|
||||
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