package spark import ( "encoding/json" "fmt" "log" "strings" ) type ModerateResult struct { OK bool `json:"ok"` Reason string `json:"reason"` } // ModerateText 审核姓名与内容。AI 未配置时放行。 func (c *Client) ModerateText(name, content string) (ok bool, reason string, err error) { if !c.Enabled() { log.Println("spark moderate skipped: SPARK_API_PASSWORD empty") return true, "", nil } sys := `你是婚礼请柬内容安全审核助手。判断姓名与祝福/弹幕是否包含违法违规、色情、政治敏感、人身攻击、脏话辱骂、歧视仇恨等内容。 只输出一个 JSON 对象,不要 markdown,不要其它文字,格式严格为: {"ok":true,"reason":""} 或 {"ok":false,"reason":"简短中文原因"} ok=true 表示可公开展示;ok=false 表示应拦截。` user := fmt.Sprintf("姓名:%s\n内容:%s", strings.TrimSpace(name), strings.TrimSpace(content)) raw, err := c.Chat([]Message{ {Role: "system", Content: sys}, {Role: "user", Content: user}, }) if err != nil { return false, "", err } raw = strings.TrimSpace(raw) raw = strings.TrimPrefix(raw, "```json") raw = strings.TrimPrefix(raw, "```") raw = strings.TrimSuffix(raw, "```") raw = strings.TrimSpace(raw) var res ModerateResult if err := json.Unmarshal([]byte(raw), &res); err != nil { // 尝试截取第一个 JSON 对象 start := strings.Index(raw, "{") end := strings.LastIndex(raw, "}") if start >= 0 && end > start { if err2 := json.Unmarshal([]byte(raw[start:end+1]), &res); err2 != nil { return false, "", fmt.Errorf("解析审核结果失败: %v; raw=%s", err, truncate(raw, 120)) } } else { return false, "", fmt.Errorf("解析审核结果失败: %v", err) } } if !res.OK && strings.TrimSpace(res.Reason) == "" { res.Reason = "内容未通过审核" } return res.OK, strings.TrimSpace(res.Reason), nil }