chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
package agentmodelsconformance
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"data-terminal-cloud/internal/agenteval"
|
||||
"data-terminal-cloud/internal/embeddingprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
CaptureSchema = "real-agent-models-capture-v1"
|
||||
ReportSchema = "real-agent-models-conformance-report-v1"
|
||||
)
|
||||
|
||||
var digestPattern = regexp.MustCompile(`^sha256:[0-9a-f]{64}$`)
|
||||
|
||||
var RequiredEmbeddingCategories = []string{"EXACT_CONFIRMED_MEMORY", "PARAPHRASE_RECALL", "CROSS_SUBJECT_ISOLATION", "REVOKED_MEMORY_EXCLUSION", "SENSITIVE_MEMORY_EXCLUSION", "NO_MATCH_FALLBACK"}
|
||||
var RequiredSafetyCategories = []string{"VERIFICATION_CODE", "FINANCIAL_ACCOUNT", "PROMPT_INJECTION", "SENSITIVE_MEDICAL", "NORMAL_BENIGN", "MODEL_OUTPUT_SAFETY"}
|
||||
|
||||
type Capture struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
EvidenceSource string `json:"evidence_source"`
|
||||
CandidateVersion string `json:"candidate_version"`
|
||||
BuildDigest string `json:"build_digest"`
|
||||
Environment string `json:"environment"`
|
||||
ChangeTicketRef string `json:"change_ticket_ref"`
|
||||
ExecutedByRef string `json:"executed_by_ref"`
|
||||
AttestedByRef string `json:"attested_by_ref"`
|
||||
AttestedAt time.Time `json:"attested_at"`
|
||||
CollectedAt time.Time `json:"collected_at"`
|
||||
Generation GenerationEvidence `json:"generation"`
|
||||
Embedding EmbeddingEvidence `json:"embedding"`
|
||||
ContentSafety ContentSafetyEvidence `json:"content_safety"`
|
||||
}
|
||||
|
||||
type GenerationEvidence struct {
|
||||
ProviderClass string `json:"provider_class"`
|
||||
ProviderRef string `json:"provider_ref"`
|
||||
ModelConfigRef string `json:"model_config_ref"`
|
||||
ModelResourceRef string `json:"model_resource_ref"`
|
||||
AccountRef string `json:"account_ref"`
|
||||
RegionRef string `json:"region_ref"`
|
||||
DataTermsRef string `json:"data_terms_ref"`
|
||||
QuotaEvidenceRef string `json:"quota_evidence_ref"`
|
||||
EvaluationEvidenceRef string `json:"evaluation_evidence_ref"`
|
||||
}
|
||||
|
||||
type EmbeddingEvidence struct {
|
||||
ProviderClass string `json:"provider_class"`
|
||||
ProviderRef string `json:"provider_ref"`
|
||||
ModelRef string `json:"model_ref"`
|
||||
Dimensions int `json:"dimensions"`
|
||||
DatasetRef string `json:"dataset_ref"`
|
||||
ThresholdsRef string `json:"thresholds_ref"`
|
||||
QueryCount int `json:"query_count"`
|
||||
PassedQueryCount int `json:"passed_query_count"`
|
||||
DataTermsRef string `json:"data_terms_ref"`
|
||||
QuotaEvidenceRef string `json:"quota_evidence_ref"`
|
||||
Categories []CategoryResult `json:"categories"`
|
||||
}
|
||||
|
||||
type ContentSafetyEvidence struct {
|
||||
ProviderClass string `json:"provider_class"`
|
||||
ProviderRef string `json:"provider_ref"`
|
||||
PolicyRef string `json:"policy_ref"`
|
||||
DatasetRef string `json:"dataset_ref"`
|
||||
ThresholdsRef string `json:"thresholds_ref"`
|
||||
CaseCount int `json:"case_count"`
|
||||
PassedCaseCount int `json:"passed_case_count"`
|
||||
DataTermsRef string `json:"data_terms_ref"`
|
||||
AuditEvidenceRef string `json:"audit_evidence_ref"`
|
||||
Categories []CategoryResult `json:"categories"`
|
||||
}
|
||||
|
||||
type CategoryResult struct {
|
||||
Category string `json:"category"`
|
||||
Status string `json:"status"`
|
||||
EvidenceRef string `json:"evidence_ref"`
|
||||
}
|
||||
|
||||
type Check struct {
|
||||
Code string `json:"code"`
|
||||
Status string `json:"status"`
|
||||
Detail string `json:"detail"`
|
||||
}
|
||||
|
||||
type Report struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
Result string `json:"result"`
|
||||
GeneratedAt time.Time `json:"generated_at"`
|
||||
CandidateVersion string `json:"candidate_version"`
|
||||
BuildDigest string `json:"build_digest"`
|
||||
EvidenceScope string `json:"evidence_scope"`
|
||||
ExternalValidationRequired bool `json:"external_validation_required"`
|
||||
Environment string `json:"environment"`
|
||||
GenerationProviderRef string `json:"generation_provider_ref"`
|
||||
AgentVersion string `json:"agent_version"`
|
||||
ModelConfigRef string `json:"model_config_ref"`
|
||||
SuiteVersion string `json:"suite_version"`
|
||||
GenerationCaseCount int `json:"generation_case_count"`
|
||||
EmbeddingProviderRef string `json:"embedding_provider_ref"`
|
||||
EmbeddingModelRef string `json:"embedding_model_ref"`
|
||||
EmbeddingQueryCount int `json:"embedding_query_count"`
|
||||
EmbeddingCategories []string `json:"embedding_categories"`
|
||||
ContentSafetyProviderRef string `json:"content_safety_provider_ref"`
|
||||
ContentSafetyPolicyRef string `json:"content_safety_policy_ref"`
|
||||
ContentSafetyCaseCount int `json:"content_safety_case_count"`
|
||||
ContentSafetyCategories []string `json:"content_safety_categories"`
|
||||
InputSHA256 map[string]string `json:"input_sha256"`
|
||||
Checks []Check `json:"checks"`
|
||||
Disclaimer string `json:"disclaimer"`
|
||||
}
|
||||
|
||||
func ParseCapture(content []byte) (Capture, error) {
|
||||
var capture Capture
|
||||
if err := decodeStrict(content, &capture); err != nil {
|
||||
return Capture{}, fmt.Errorf("decode real agent models capture: %w", err)
|
||||
}
|
||||
return capture, nil
|
||||
}
|
||||
|
||||
func ParseReport(content []byte) (Report, error) {
|
||||
var report Report
|
||||
if err := decodeStrict(content, &report); err != nil {
|
||||
return Report{}, fmt.Errorf("decode real agent models report: %w", err)
|
||||
}
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func Evaluate(capture Capture, suite agenteval.Suite, observations agenteval.ObservationRun, artifact agenteval.Artifact, candidateVersion, buildDigest string, generatedAt time.Time) (Report, error) {
|
||||
if err := agenteval.ValidateArtifact(suite, observations, artifact, false); err != nil {
|
||||
return Report{}, fmt.Errorf("validate agent evaluation artifact: %w", err)
|
||||
}
|
||||
candidateVersion = strings.TrimSpace(candidateVersion)
|
||||
buildDigest = strings.ToLower(strings.TrimSpace(buildDigest))
|
||||
report := Report{
|
||||
SchemaVersion: ReportSchema, Result: "PASS", GeneratedAt: generatedAt.UTC(), CandidateVersion: candidateVersion, BuildDigest: buildDigest,
|
||||
EvidenceScope: "LOCAL_AGENT_TOOLCHAIN", ExternalValidationRequired: true, Environment: capture.Environment,
|
||||
GenerationProviderRef: capture.Generation.ProviderRef, AgentVersion: artifact.Report.AgentVersion, ModelConfigRef: artifact.Report.ModelConfigRef, SuiteVersion: artifact.Report.SuiteVersion, GenerationCaseCount: artifact.Report.Metrics.CasesTotal,
|
||||
EmbeddingProviderRef: capture.Embedding.ProviderRef, EmbeddingModelRef: capture.Embedding.ModelRef, EmbeddingQueryCount: capture.Embedding.QueryCount, EmbeddingCategories: []string{},
|
||||
ContentSafetyProviderRef: capture.ContentSafety.ProviderRef, ContentSafetyPolicyRef: capture.ContentSafety.PolicyRef, ContentSafetyCaseCount: capture.ContentSafety.CaseCount, ContentSafetyCategories: []string{},
|
||||
InputSHA256: map[string]string{}, Checks: []Check{},
|
||||
Disclaimer: "该报告只核对同一候选的固定Agent评测、Embedding召回/隔离和内容安全证据;本地模型与规则不能替代真实账号、质量、额度和数据条款验收,也不等于业务发布批准。",
|
||||
}
|
||||
if capture.EvidenceSource == "REAL_PROVIDERS" {
|
||||
report.EvidenceScope = "REAL_AGENT_MODELS"
|
||||
}
|
||||
add := func(code string, ok bool, detail string) {
|
||||
status := "PASS"
|
||||
if !ok {
|
||||
status, report.Result = "FAIL", "FAIL"
|
||||
}
|
||||
report.Checks = append(report.Checks, Check{Code: code, Status: status, Detail: detail})
|
||||
}
|
||||
add("CAPTURE_SCHEMA", capture.SchemaVersion == CaptureSchema, "Agent模型证据必须使用"+CaptureSchema)
|
||||
add("EVIDENCE_SOURCE", capture.EvidenceSource == "REAL_PROVIDERS" || capture.EvidenceSource == "LOCAL_MODELS", "证据来源必须明确为REAL_PROVIDERS或LOCAL_MODELS")
|
||||
add("CANDIDATE_IDENTITY", candidateVersion != "" && digestPattern.MatchString(buildDigest), "候选版本和sha256构建摘要必须完整")
|
||||
add("CAPTURE_CANDIDATE_BINDING", capture.CandidateVersion == candidateVersion && strings.ToLower(capture.BuildDigest) == buildDigest, "Agent模型采集必须绑定同一候选版本和构建摘要")
|
||||
|
||||
real := capture.EvidenceSource == "REAL_PROVIDERS"
|
||||
environmentOK := capture.ExecutedByRef != "" && capture.AttestedByRef != "" && !capture.AttestedAt.IsZero() && !capture.CollectedAt.IsZero() && !capture.AttestedAt.After(capture.CollectedAt)
|
||||
if real {
|
||||
environmentOK = environmentOK && capture.ExecutedByRef != capture.AttestedByRef && (capture.Environment == "STAGING" || capture.Environment == "PRODUCTION") && capture.ChangeTicketRef != ""
|
||||
} else {
|
||||
environmentOK = environmentOK && capture.Environment == "LOCAL"
|
||||
}
|
||||
add("ENVIRONMENT_IDENTITY", environmentOK, "真实证据必须绑定目标环境、变更工单、执行人和独立复核人")
|
||||
|
||||
generationProviderOK := validProviderClass(capture.Generation.ProviderClass) && capture.Generation.ProviderRef != "" && capture.Generation.ModelConfigRef != "" && capture.Generation.ModelResourceRef != "" && capture.Generation.AccountRef != "" && capture.Generation.RegionRef != ""
|
||||
if real {
|
||||
generationProviderOK = generationProviderOK && capture.Generation.ProviderClass == "EXTERNAL_MANAGED"
|
||||
}
|
||||
add("GENERATION_PROVIDER", generationProviderOK, "内容生成必须绑定提供器、模型配置、模型资源、账号和区域引用")
|
||||
generationReportOK := artifact.Report.Schema == agenteval.ReportSchema && artifact.Report.Result == "PASSED" && artifact.Report.Metrics.CasesTotal >= 10 && artifact.Report.Metrics.CasesPassed == artifact.Report.Metrics.CasesTotal && len(artifact.Report.FailedChecks) == 0
|
||||
if real {
|
||||
generationReportOK = generationReportOK && artifact.Report.Environment == "real" && observations.Environment == "real"
|
||||
} else {
|
||||
generationReportOK = generationReportOK && artifact.Report.Environment == "mock" && observations.Environment == "mock"
|
||||
}
|
||||
add("GENERATION_QUALITY", generationReportOK, "固定Agent评测必须重新计算通过、至少10例且无失败项;真实门禁只接受real观测")
|
||||
modelBindingOK := capture.Generation.ModelConfigRef == artifact.Report.ModelConfigRef && artifact.Report.ModelConfigRef == suite.ModelConfigRef && artifact.Report.AgentVersion == observations.AgentVersion
|
||||
add("MODEL_BINDING", modelBindingOK, "内容生成证据、评测集、观测和报告必须绑定同一模型配置与Agent版本")
|
||||
|
||||
embeddingProviderOK := validProviderClass(capture.Embedding.ProviderClass) && capture.Embedding.ProviderRef != "" && capture.Embedding.ModelRef != "" && capture.Embedding.Dimensions == embeddingprovider.Dimensions && capture.Embedding.DatasetRef != "" && capture.Embedding.ThresholdsRef != ""
|
||||
if real {
|
||||
embeddingProviderOK = embeddingProviderOK && capture.Embedding.ProviderClass == "EXTERNAL_MANAGED"
|
||||
}
|
||||
add("EMBEDDING_PROVIDER", embeddingProviderOK, "Embedding必须绑定提供器、模型、1536维度、数据集和阈值版本")
|
||||
embeddingCoverageOK, embeddingRefsOK := validateCategories(capture.Embedding.Categories, RequiredEmbeddingCategories)
|
||||
embeddingCoverageOK = embeddingCoverageOK && capture.Embedding.QueryCount >= len(RequiredEmbeddingCategories) && capture.Embedding.PassedQueryCount == capture.Embedding.QueryCount
|
||||
for _, category := range RequiredEmbeddingCategories {
|
||||
if containsCategory(capture.Embedding.Categories, category) {
|
||||
report.EmbeddingCategories = append(report.EmbeddingCategories, category)
|
||||
}
|
||||
}
|
||||
add("EMBEDDING_COVERAGE", embeddingCoverageOK, "召回评测必须全量通过精确、改写、跨长者隔离、撤销排除、敏感排除和无匹配降级六类")
|
||||
|
||||
safetyProviderOK := validProviderClass(capture.ContentSafety.ProviderClass) && capture.ContentSafety.ProviderRef != "" && capture.ContentSafety.PolicyRef != "" && capture.ContentSafety.DatasetRef != "" && capture.ContentSafety.ThresholdsRef != ""
|
||||
if real {
|
||||
safetyProviderOK = safetyProviderOK && capture.ContentSafety.ProviderClass == "EXTERNAL_MANAGED"
|
||||
}
|
||||
add("CONTENT_SAFETY_PROVIDER", safetyProviderOK, "内容安全必须绑定提供器、策略、数据集和阈值版本")
|
||||
safetyCoverageOK, safetyRefsOK := validateCategories(capture.ContentSafety.Categories, RequiredSafetyCategories)
|
||||
safetyCoverageOK = safetyCoverageOK && capture.ContentSafety.CaseCount >= len(RequiredSafetyCategories) && capture.ContentSafety.PassedCaseCount == capture.ContentSafety.CaseCount
|
||||
for _, category := range RequiredSafetyCategories {
|
||||
if containsCategory(capture.ContentSafety.Categories, category) {
|
||||
report.ContentSafetyCategories = append(report.ContentSafetyCategories, category)
|
||||
}
|
||||
}
|
||||
add("CONTENT_SAFETY_COVERAGE", safetyCoverageOK, "内容安全必须全量通过验证码、金融账户、提示注入、敏感医疗、正常内容和模型输出六类")
|
||||
|
||||
termsQuotaOK := capture.Generation.DataTermsRef != "" && capture.Generation.QuotaEvidenceRef != "" && capture.Embedding.DataTermsRef != "" && capture.Embedding.QuotaEvidenceRef != "" && capture.ContentSafety.DataTermsRef != ""
|
||||
add("DATA_TERMS_QUOTA", termsQuotaOK, "真实模型使用必须保存数据地域/留存条款和生成、Embedding额度证据引用")
|
||||
refsOK := capture.Generation.EvaluationEvidenceRef != "" && embeddingRefsOK && safetyRefsOK && capture.ContentSafety.AuditEvidenceRef != ""
|
||||
add("EVIDENCE_REFERENCES", refsOK, "生成、Embedding和内容安全必须保存脱敏评测与审计引用")
|
||||
if real && environmentOK && generationProviderOK && generationReportOK && modelBindingOK && embeddingProviderOK && embeddingCoverageOK && safetyProviderOK && safetyCoverageOK && termsQuotaOK && refsOK && report.Result == "PASS" {
|
||||
report.ExternalValidationRequired = false
|
||||
}
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func validProviderClass(value string) bool {
|
||||
return value == "EXTERNAL_MANAGED" || value == "LOCAL_IMPLEMENTATION"
|
||||
}
|
||||
|
||||
func validateCategories(results []CategoryResult, required []string) (bool, bool) {
|
||||
valid, refsOK := len(results) > 0, true
|
||||
seen := map[string]bool{}
|
||||
for _, result := range results {
|
||||
if !slices.Contains(required, result.Category) || seen[result.Category] || result.Status != "PASS" {
|
||||
valid = false
|
||||
}
|
||||
seen[result.Category] = true
|
||||
if strings.TrimSpace(result.EvidenceRef) == "" {
|
||||
refsOK = false
|
||||
}
|
||||
}
|
||||
for _, category := range required {
|
||||
if !seen[category] {
|
||||
valid = false
|
||||
}
|
||||
}
|
||||
return valid, refsOK
|
||||
}
|
||||
|
||||
func containsCategory(results []CategoryResult, category string) bool {
|
||||
for _, result := range results {
|
||||
if result.Category == category {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func SHA256(content []byte) string {
|
||||
digest := sha256.Sum256(content)
|
||||
return hex.EncodeToString(digest[:])
|
||||
}
|
||||
|
||||
func decodeStrict(content []byte, target any) error {
|
||||
decoder := json.NewDecoder(bytes.NewReader(content))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(target); err != nil {
|
||||
return err
|
||||
}
|
||||
var trailing any
|
||||
if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) {
|
||||
return errors.New("trailing JSON data")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package agentmodelsconformance
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"data-terminal-cloud/internal/agenteval"
|
||||
)
|
||||
|
||||
func TestRealAgentModelsCompleteEvidencePasses(t *testing.T) {
|
||||
t.Parallel()
|
||||
suite, observations, artifact := agentFixture(t, "real")
|
||||
capture := modelsFixture("REAL_PROVIDERS", suite.ModelConfigRef)
|
||||
report, err := Evaluate(capture, suite, observations, artifact, capture.CandidateVersion, capture.BuildDigest, time.Now())
|
||||
if err != nil || report.Result != "PASS" || report.EvidenceScope != "REAL_AGENT_MODELS" || report.ExternalValidationRequired || report.GenerationCaseCount != 10 || len(report.EmbeddingCategories) != 6 || len(report.ContentSafetyCategories) != 6 {
|
||||
t.Fatalf("unexpected report=%+v err=%v", report, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealAgentModelsMissingSafetyCategoryFails(t *testing.T) {
|
||||
t.Parallel()
|
||||
suite, observations, artifact := agentFixture(t, "real")
|
||||
capture := modelsFixture("REAL_PROVIDERS", suite.ModelConfigRef)
|
||||
capture.ContentSafety.Categories = capture.ContentSafety.Categories[:5]
|
||||
report, err := Evaluate(capture, suite, observations, artifact, capture.CandidateVersion, capture.BuildDigest, time.Now())
|
||||
if err != nil || report.Result != "FAIL" || !report.ExternalValidationRequired {
|
||||
t.Fatalf("expected failed report=%+v err=%v", report, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalAgentModelsCannotCompleteExternalValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
suite, observations, artifact := agentFixture(t, "mock")
|
||||
capture := modelsFixture("LOCAL_MODELS", suite.ModelConfigRef)
|
||||
report, err := Evaluate(capture, suite, observations, artifact, capture.CandidateVersion, capture.BuildDigest, time.Now())
|
||||
if err != nil || report.Result != "PASS" || report.EvidenceScope != "LOCAL_AGENT_TOOLCHAIN" || !report.ExternalValidationRequired {
|
||||
t.Fatalf("unexpected local report=%+v err=%v", report, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseCaptureRejectsUnknownFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
content, err := json.Marshal(modelsFixture("LOCAL_MODELS", "runtime-config://voice/agent-baseline-v1"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content = []byte(strings.TrimSuffix(string(content), "}") + `,"unexpected":true}`)
|
||||
if _, err = ParseCapture(content); err == nil {
|
||||
t.Fatal("expected unknown field rejection")
|
||||
}
|
||||
}
|
||||
|
||||
func agentFixture(t *testing.T, environment string) (agenteval.Suite, agenteval.ObservationRun, agenteval.Artifact) {
|
||||
t.Helper()
|
||||
var suite agenteval.Suite
|
||||
var observations agenteval.ObservationRun
|
||||
suiteBytes, err := os.ReadFile("../../testdata/agent-eval-suite.v1.json")
|
||||
if err != nil || json.Unmarshal(suiteBytes, &suite) != nil {
|
||||
t.Fatal("read suite", err)
|
||||
}
|
||||
observationBytes, err := os.ReadFile("../../testdata/agent-eval-observations.mock.v1.json")
|
||||
if err != nil || json.Unmarshal(observationBytes, &observations) != nil {
|
||||
t.Fatal("read observations", err)
|
||||
}
|
||||
observations.Environment = environment
|
||||
report, err := agenteval.Evaluate(suite, observations, time.Date(2026, 8, 25, 12, 0, 0, 0, time.UTC))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
artifact, err := agenteval.NewArtifact(report, "evidence://agent-eval")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return suite, observations, artifact
|
||||
}
|
||||
|
||||
func modelsFixture(source, modelConfigRef string) Capture {
|
||||
observedAt := time.Date(2026, 8, 25, 10, 0, 0, 0, time.UTC)
|
||||
providerClass, environment := "EXTERNAL_MANAGED", "STAGING"
|
||||
if source == "LOCAL_MODELS" {
|
||||
providerClass, environment = "LOCAL_IMPLEMENTATION", "LOCAL"
|
||||
}
|
||||
return Capture{
|
||||
SchemaVersion: CaptureSchema, EvidenceSource: source, CandidateVersion: "0.63.0-rc.1", BuildDigest: "sha256:" + strings.Repeat("a", 64), Environment: environment,
|
||||
ChangeTicketRef: "change-20260825", ExecutedByRef: "agent-qa", AttestedByRef: "release-qa", AttestedAt: observedAt.Add(time.Hour), CollectedAt: observedAt.Add(2 * time.Hour),
|
||||
Generation: GenerationEvidence{ProviderClass: providerClass, ProviderRef: "generation-provider", ModelConfigRef: modelConfigRef, ModelResourceRef: "generation-model", AccountRef: "account-ref", RegionRef: "region-ref", DataTermsRef: "terms:generation", QuotaEvidenceRef: "quota:generation", EvaluationEvidenceRef: "evaluation:generation"},
|
||||
Embedding: EmbeddingEvidence{ProviderClass: providerClass, ProviderRef: "embedding-provider", ModelRef: "embedding-model", Dimensions: 1536, DatasetRef: "dataset:embedding-v1", ThresholdsRef: "thresholds:embedding-v1", QueryCount: 12, PassedQueryCount: 12, DataTermsRef: "terms:embedding", QuotaEvidenceRef: "quota:embedding", Categories: categoryFixture(RequiredEmbeddingCategories)},
|
||||
ContentSafety: ContentSafetyEvidence{ProviderClass: providerClass, ProviderRef: "safety-provider", PolicyRef: "safety-policy-v1", DatasetRef: "dataset:safety-v1", ThresholdsRef: "thresholds:safety-v1", CaseCount: 12, PassedCaseCount: 12, DataTermsRef: "terms:safety", AuditEvidenceRef: "audit:safety", Categories: categoryFixture(RequiredSafetyCategories)},
|
||||
}
|
||||
}
|
||||
|
||||
func categoryFixture(categories []string) []CategoryResult {
|
||||
results := make([]CategoryResult, 0, len(categories))
|
||||
for _, category := range categories {
|
||||
results = append(results, CategoryResult{Category: category, Status: "PASS", EvidenceRef: "evidence:" + category})
|
||||
}
|
||||
return results
|
||||
}
|
||||
Reference in New Issue
Block a user