Files
slogan/styleagent/agent/output.go
T

72 lines
2.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 agent
import (
"encoding/json"
"fmt"
"strings"
)
// PlanOutput 大模型输出的穿搭方案集合
type PlanOutput struct {
Plans []PlanCandidate `json:"plans"`
}
// PlanCandidate 一套穿搭方案
type PlanCandidate struct {
Title string `json:"title"`
Hairstyle string `json:"hairstyle"` // 发型名称(匹配资产库)
HairColor string `json:"hair_color"` // 如 #A0522D
Items []PlanItemOut `json:"items"`
}
// PlanItemOut 方案内一件单品
type PlanItemOut struct {
Slot string `json:"slot"` // 上衣/下装/鞋/配饰
ItemId int64 `json:"item_id,omitempty"` // 衣橱条目(wardrobe 来源)
Name string `json:"name"` // 单品名
Desc string `json:"desc"` // 搭配说明
NewItem bool `json:"new_item"` // 是否为推荐新服装
}
// ParsePlanOutput 解析并校验 LLM 输出(去除 markdown 代码围栏后 json.Unmarshal
func ParsePlanOutput(raw string) (*PlanOutput, error) {
text := strings.TrimSpace(raw)
// 容忍 ```json ... ``` 代码围栏
if strings.HasPrefix(text, "```") {
text = strings.TrimPrefix(text, "```")
if idx := strings.Index(text, "\n"); idx >= 0 {
text = text[idx+1:]
}
text = strings.TrimSuffix(strings.TrimSpace(text), "```")
}
var out PlanOutput
if err := json.Unmarshal([]byte(text), &out); err != nil {
return nil, fmt.Errorf("方案 JSON 解析失败: %w", err)
}
if len(out.Plans) == 0 {
return nil, fmt.Errorf("方案输出为空(plans 缺失)")
}
for i, p := range out.Plans {
if strings.TrimSpace(p.Title) == "" {
return nil, fmt.Errorf("方案 %d 缺少 title", i+1)
}
if len(p.Items) == 0 {
return nil, fmt.Errorf("方案 %d 缺少 items", i+1)
}
for _, it := range p.Items {
if !isValidSlot(it.Slot) {
return nil, fmt.Errorf("方案 %d 含非法 slot: %s", i+1, it.Slot)
}
}
}
return &out, nil
}
func isValidSlot(slot string) bool {
switch slot {
case "上衣", "下装", "鞋", "配饰":
return true
}
return false
}