thread-master/internal/library/viral/analyze_viral.go

102 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package viral
import (
"encoding/json"
"fmt"
"strings"
)
type ViralAnalysis struct {
HookPattern string `json:"hookPattern"`
StructurePattern string `json:"structurePattern"`
EmotionalTrigger string `json:"emotionalTrigger"`
ReplicationStrategy string `json:"replicationStrategy"`
KeyTakeaways []string `json:"keyTakeaways"`
}
type AnalyzeViralInput struct {
PostText string
AuthorName string
LikeCount int
ReplyCount int
SearchTag string
TopicLabel string
TopicBrief string
Persona string
}
func BuildAnalyzeViralSystemPrompt() string {
return strings.TrimSpace(`你是 Threads 爆款結構分析師。拆解貼文為什麼會紅、怎麼仿寫結構,不要建議抄襲原文。
只回傳 JSONhookPattern, structurePattern, emotionalTrigger, replicationStrategy, keyTakeaways字串陣列 35 項)。繁體中文。`)
}
func BuildAnalyzeViralUserPrompt(in AnalyzeViralInput) string {
var b strings.Builder
b.WriteString("主題:")
b.WriteString(strings.TrimSpace(in.TopicLabel))
b.WriteString("\n")
if brief := strings.TrimSpace(in.TopicBrief); brief != "" {
b.WriteString("Brief")
b.WriteString(brief)
b.WriteString("\n")
}
if tag := strings.TrimSpace(in.SearchTag); tag != "" {
b.WriteString("搜尋標籤:")
b.WriteString(tag)
b.WriteString("\n")
}
author := strings.TrimSpace(in.AuthorName)
if author == "" {
author = "匿名"
}
b.WriteString(fmt.Sprintf("\n作者 @%s · %d 讚 · %d 留言\n", author, in.LikeCount, in.ReplyCount))
b.WriteString("\n貼文\n")
b.WriteString(strings.TrimSpace(in.PostText))
return b.String()
}
func ParseAnalyzeViralOutput(raw string) (ViralAnalysis, error) {
payload, err := extractCopyMapJSON(raw)
if err != nil {
return ViralAnalysis{}, err
}
var out ViralAnalysis
if err := json.Unmarshal(payload, &out); err != nil {
return ViralAnalysis{}, fmt.Errorf("parse viral analysis: %w", err)
}
if strings.TrimSpace(out.HookPattern) == "" && strings.TrimSpace(out.StructurePattern) == "" {
return ViralAnalysis{}, fmt.Errorf("viral analysis missing content")
}
return out, nil
}
func FormatAnalysisForReplicate(analysis ViralAnalysis) string {
var b strings.Builder
if hook := strings.TrimSpace(analysis.HookPattern); hook != "" {
b.WriteString("Hook 模式:")
b.WriteString(hook)
b.WriteString("\n")
}
if structure := strings.TrimSpace(analysis.StructurePattern); structure != "" {
b.WriteString("結構節奏:")
b.WriteString(structure)
b.WriteString("\n")
}
if emotion := strings.TrimSpace(analysis.EmotionalTrigger); emotion != "" {
b.WriteString("情緒觸發:")
b.WriteString(emotion)
b.WriteString("\n")
}
if strategy := strings.TrimSpace(analysis.ReplicationStrategy); strategy != "" {
b.WriteString("仿寫策略:")
b.WriteString(strategy)
b.WriteString("\n")
}
if len(analysis.KeyTakeaways) > 0 {
b.WriteString("重點:")
b.WriteString(strings.Join(analysis.KeyTakeaways, ""))
}
return strings.TrimSpace(b.String())
}