package util import ( "encoding/json" "fmt" ) // ValidatePromptResult 完整的校验逻辑 func ValidatePromptResult(raw map[string]any, requestMapping map[string]any) error { contentStr, ok := raw["content"].(string) if !ok || contentStr == "" { return fmt.Errorf("content 字段为空或不是字符串") } var rounds []map[string]any if err := json.Unmarshal([]byte(contentStr), &rounds); err != nil { return fmt.Errorf("解析 content JSON 数组失败: %w", err) } if len(rounds) == 0 { return fmt.Errorf("content 数组为空") } // 对 rounds 中的每一个元素进行结构校验 for i, round := range rounds { if err := validateStructure(requestMapping, round); err != nil { return fmt.Errorf("rounds[%d] 结构校验失败: %w", i, err) } } return nil } // validateStructure 递归校验 actual 是否包含 expected 定义的所有字段路径 func validateStructure(expected any, actual any) error { switch exp := expected.(type) { case map[string]any: act, ok := actual.(map[string]any) if !ok { return fmt.Errorf("期望对象,实际类型 %T", actual) } for key, expVal := range exp { actVal, exists := act[key] if !exists { return fmt.Errorf("缺少字段: %s", key) } if err := validateStructure(expVal, actVal); err != nil { return fmt.Errorf("%s: %w", key, err) } } return nil case []any: act, ok := actual.([]any) if !ok { return fmt.Errorf("期望数组,实际类型 %T", actual) } if len(exp) == 0 { return nil // 空数组模板,只校验类型 } // 用第一个元素的结构去校验每个实际元素 for i, actItem := range act { if err := validateStructure(exp[0], actItem); err != nil { return fmt.Errorf("[%d]: %w", i, err) } } return nil default: // 基本类型,不校验具体值,只检查存在 return nil } }