haixunMaster/haixun-backend/internal/library/knowledge/graph.go

92 lines
2.3 KiB
Go
Raw Normal View History

2026-06-24 10:02:42 +00:00
package knowledge
import "strings"
type DerivedTags struct {
Relevance []string `json:"relevance"`
Recency []string `json:"recency"`
}
type Evidence struct {
URL string `json:"url"`
Snippet string `json:"snippet"`
Query string `json:"query,omitempty"`
}
type Node struct {
ID string `json:"id"`
Label string `json:"label"`
NodeKind string `json:"nodeKind"` // pain | knowledge | cause | symptom
Type string `json:"type"` // core | cause | symptom | mechanism
Layer int `json:"layer"`
Relation string `json:"relation,omitempty"`
2026-06-24 16:48:56 +00:00
PlacementValue string `json:"placementValue,omitempty"` // 為何與產品置入相關(完整句子)
2026-06-24 10:02:42 +00:00
ProductFitScore int `json:"productFitScore"`
SelectedForScan bool `json:"selectedForScan"`
2026-06-24 16:48:56 +00:00
PatrolRelevance []string `json:"patrolRelevance,omitempty"`
PatrolRecency []string `json:"patrolRecency,omitempty"`
2026-06-24 10:02:42 +00:00
Evidence []Evidence `json:"evidence"`
DerivedTags DerivedTags `json:"derivedTags"`
}
type Edge struct {
From string `json:"from"`
To string `json:"to"`
Relation string `json:"relation"`
}
type BraveSource struct {
Query string `json:"query"`
Snippet string `json:"snippet"`
URL string `json:"url"`
Title string `json:"title,omitempty"`
}
type Graph struct {
Seed string `json:"seed"`
Nodes []Node `json:"nodes"`
Edges []Edge `json:"edges"`
BraveSources []BraveSource `json:"braveSources"`
PainTagCount int `json:"painTagCount"`
}
func IsPainNode(node Node) bool {
switch strings.TrimSpace(node.NodeKind) {
case "pain", "symptom", "cause":
return true
default:
return false
}
}
func CountPainTagCandidates(nodes []Node) int {
count := 0
for _, node := range nodes {
if !IsPainNode(node) {
continue
}
if len(node.DerivedTags.Relevance) > 0 || len(node.DerivedTags.Recency) > 0 {
count++
}
}
return count
}
func TotalTagCandidates(nodes []Node) int {
count := 0
for _, node := range nodes {
count += len(node.DerivedTags.Relevance) + len(node.DerivedTags.Recency)
}
return count
}
func NodeByID(nodes []Node, id string) (Node, bool) {
id = strings.TrimSpace(id)
for _, node := range nodes {
if node.ID == id {
return node, true
}
}
return Node{}, false
}