Fallback to raw LLM content when JSON parsing fails
这个提交包含在:
@@ -16,6 +16,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -733,11 +734,8 @@ func (c *LLMClient) FormatAndGrade(ctx context.Context, title, ocrText string) (
|
|||||||
|
|
||||||
result := LLMResult{}
|
result := LLMResult{}
|
||||||
if err := decodeLLMResult(content, &result); err != nil {
|
if err := decodeLLMResult(content, &result); err != nil {
|
||||||
fallback := strings.TrimSpace(content)
|
markdown, feedback, score := fallbackFromContent(content, ocrText)
|
||||||
if fallback == "" {
|
return markdown, feedback, score, nil
|
||||||
fallback = ocrText
|
|
||||||
}
|
|
||||||
return fallback, "LLM 返回无法解析为 JSON,已返回原始内容。", 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
markdown := strings.TrimSpace(result.Markdown)
|
markdown := strings.TrimSpace(result.Markdown)
|
||||||
@@ -792,7 +790,8 @@ func (c *LLMClient) FormatAndGradeFromImages(ctx context.Context, title string,
|
|||||||
|
|
||||||
result := LLMResult{}
|
result := LLMResult{}
|
||||||
if err := decodeLLMResult(content, &result); err != nil {
|
if err := decodeLLMResult(content, &result); err != nil {
|
||||||
return "", "LLM 返回无法解析为 JSON。", 0, nil
|
markdown, feedback, score := fallbackFromContent(content, "未识别到有效内容。")
|
||||||
|
return markdown, feedback, score, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
markdown := strings.TrimSpace(result.Markdown)
|
markdown := strings.TrimSpace(result.Markdown)
|
||||||
@@ -896,6 +895,35 @@ func decodeLLMResult(content string, out *LLMResult) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scorePattern = regexp.MustCompile(`(?i)(?:评分|score)[::]?\s*([0-9]{1,3})`)
|
||||||
|
|
||||||
|
func parseScoreFromText(text string) int {
|
||||||
|
matches := scorePattern.FindStringSubmatch(text)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
value, err := strconv.Atoi(matches[1])
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if value < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if value > 100 {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func fallbackFromContent(content, defaultMarkdown string) (string, string, int) {
|
||||||
|
markdown := strings.TrimSpace(content)
|
||||||
|
if markdown == "" {
|
||||||
|
markdown = defaultMarkdown
|
||||||
|
}
|
||||||
|
score := parseScoreFromText(markdown)
|
||||||
|
return markdown, "", score
|
||||||
|
}
|
||||||
|
|
||||||
func ensureColumn(db *sql.DB, table, column, columnType string) error {
|
func ensureColumn(db *sql.DB, table, column, columnType string) error {
|
||||||
rows, err := db.Query(fmt.Sprintf("PRAGMA table_info(%s);", table))
|
rows, err := db.Query(fmt.Sprintf("PRAGMA table_info(%s);", table))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户