voice/routing: fix time-query misroute (seed collision, threshold, stage-0 grammars)
three bugs causing time queries to land on reminder or fact intent: - seed collision: query.txt and system.txt shared identical time/date seeds (который час, сколько времени), making system intent indistinguishable from query intent in centroid space - threshold (0.35) too low for ONNX embedder — cosine similarities cluster 0.5-0.7 for related intents, so Clarify never fired - reminder centroid contaminated by time-lexicon (every seed has a time expression), pulling any time-word utterance toward reminder intent fixes: - remove 3 duplicate time/date seeds from query.txt (keep in system.txt) - DefaultRouterThreshold 0.35 -> 0.55 - stage-0 grammar for напомни/remind me -> IntentReminder, bypasses classifier (fixes 'напомни через час' being misrouted to fact) - stage-0 grammars for time/date system queries (сколько времени, который час, какой сегодня день) -> IntentSystem, with Build filter to exclude elapsed/duration queries (сколько времени прошло) - time parser fallback in applyAction for stage-0 reminder matches (extractor doesn't run on stage-0 decisions)
This commit is contained in:
+23
-3
@@ -229,6 +229,7 @@ func wireVoice(cfg *config.Config, coreAPI ipc.CoreAPI, phr phraser.Phraser, mem
|
||||
memStore: memStore,
|
||||
dialogueSessions: dialogueSessions,
|
||||
queryMinScore: cfg.Voice.QueryMinScore,
|
||||
timeParser: router.StubDateTimeParser{},
|
||||
}
|
||||
|
||||
// ----- the server (TCP listener) -----
|
||||
@@ -268,6 +269,11 @@ type reactiveHandler struct {
|
||||
// wireVoice from VoiceConfig; default 0.55.
|
||||
queryMinScore float64
|
||||
|
||||
// timeParser — used as a fallback for stage-0 reminder grammar matches
|
||||
// (where the extractor didn't run). Shared with the router's extractor.
|
||||
// The production dateparser will replace StubDateTimeParser here too.
|
||||
timeParser router.DateTimeParser
|
||||
|
||||
// dialogueSessions carries slots across turns for follow-ups (single-user
|
||||
// box → one session slot, keyed voiceDialogueID). nil ⇒ no carry-over.
|
||||
dialogueSessions *dialogue.SessionStore
|
||||
@@ -443,7 +449,18 @@ func (h *reactiveHandler) applyAction(ctx context.Context, dec router.Decision)
|
||||
|
||||
case router.IntentReminder:
|
||||
if !dec.Slots.HasTime {
|
||||
return "не получилось разобрать время напоминания."
|
||||
// Stage-0 (reminder-wakeword grammar) skips the extractor, so the
|
||||
// time wasn't parsed. Run the parser as a fallback.
|
||||
if dec.Stage == 0 && h.timeParser != nil {
|
||||
t, ok, err := h.timeParser.Parse(ctx, dec.Utterance, h.now())
|
||||
if err == nil && ok {
|
||||
dec.Slots.Time = t
|
||||
dec.Slots.HasTime = true
|
||||
}
|
||||
}
|
||||
if !dec.Slots.HasTime {
|
||||
return "не получилось разобрать время напоминания."
|
||||
}
|
||||
}
|
||||
payload := `{"text":` + jsonString(dec.Utterance) + `}`
|
||||
if _, err := h.api.CreateReminder(ctx, dec.Slots.Time, payload, ""); err != nil {
|
||||
@@ -745,12 +762,15 @@ func (h *reactiveHandler) reply(ctx context.Context, text string, _ []string) (v
|
||||
// - 6 bootstrap examples covering the 5 intents + one compound-capture
|
||||
// placeholder. Spec calls for ~10 per intent at production; this is the
|
||||
// bootstrapping floor swapped by tuning the seed set later.
|
||||
// - Threshold is from voice.router_threshold config (default 0.35).
|
||||
// - Threshold is from voice.router_threshold config (default 0.55).
|
||||
func buildRouter(emb router.Embedder, acts router.ActMatcher, threshold float64) *router.Router {
|
||||
cls := router.NewClassifier(emb)
|
||||
seedClassifier(cls)
|
||||
grammars := router.DefaultGrammars(acts)
|
||||
grammars = append(grammars, router.SystemTimeDateGrammars()...)
|
||||
grammars = append(grammars, router.ReminderGrammar())
|
||||
return router.New(router.Config{
|
||||
Grammars: router.DefaultGrammars(acts),
|
||||
Grammars: grammars,
|
||||
Classifier: cls,
|
||||
Extractor: router.Extractor{
|
||||
Time: router.StubDateTimeParser{},
|
||||
|
||||
Reference in New Issue
Block a user