Files
Maven/internal/router/semantic/corpus.go
T
claude 5865699a5a router/semantic: corpus format and v1 dataset (slice 12)
136 examples with provenance from ru_routing_v1.json, tagged
fast_path_resolved vs residual. RouteExample carries source, source_id,
split_group for traceability. Split-by-family prevents paraphrase
leakage across train/eval.
2026-09-07 01:42:22 +04:00

77 lines
2.4 KiB
Go

package semantic
import (
_ "embed"
"encoding/json"
"fmt"
"sort"
)
//go:embed corpus_v1.json
var corpusV1JSON []byte
// RouteExample — one labeled utterance in the coarse-route experiment corpus.
// Every row carries provenance so no row can masquerade as independent when
// related paraphrases exist.
type RouteExample struct {
Text string `json:"text"`
Route SemanticRoute `json:"route"`
Source string `json:"source"` // where this row came from
SourceID string `json:"source_id"` // case ID in the source corpus
SplitGroup string `json:"split_group"` // family/seed ID for split discipline
Tags []string `json:"tags,omitempty"`
// FastPathResolved is true when a stage-0 grammar already handles this
// utterance. The learned router should not be measured on these unless
// explicitly desired; they are tagged, not removed.
FastPathResolved bool `json:"fast_path_resolved"`
}
// CorpusEnvelope — the versioned JSON envelope.
type CorpusEnvelope struct {
SchemaVersion int `json:"schema_version"`
Name string `json:"name"`
Notes []string `json:"notes"`
Examples []RouteExample `json:"examples"`
}
// SchemaVersionV1 is the version this package understands.
const SchemaVersionV1 = 1
// LoadCorpus returns the embedded corpus, rejecting unknown schema versions.
func LoadCorpus() ([]RouteExample, error) {
var env CorpusEnvelope
if err := json.Unmarshal(corpusV1JSON, &env); err != nil {
return nil, fmt.Errorf("semantic corpus: parse: %w", err)
}
if env.SchemaVersion != SchemaVersionV1 {
return nil, fmt.Errorf("semantic corpus: schema_version %d, want %d",
env.SchemaVersion, SchemaVersionV1)
}
return env.Examples, nil
}
// ByRoute groups examples by their semantic route, for per-route inspection.
func ByRoute(exs []RouteExample) map[SemanticRoute][]RouteExample {
m := make(map[SemanticRoute][]RouteExample)
for _, e := range exs {
m[e.Route] = append(m[e.Route], e)
}
for k := range m {
sort.Slice(m[k], func(i, j int) bool { return m[k][i].Text < m[k][j].Text })
}
return m
}
// SplitCounts returns the number of fast-path-resolved vs
// general-route-required examples.
func SplitCounts(exs []RouteExample) (fastPath, residual int) {
for _, e := range exs {
if e.FastPathResolved {
fastPath++
} else {
residual++
}
}
return
}