5865699a5a
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.
77 lines
2.4 KiB
Go
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
|
|
}
|