59 lines
1.9 KiB
Go
59 lines
1.9 KiB
Go
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
|
||
}
|