Skip to main content
The Fuzzy Matcher (fuzzy_matcher) takes two inputs — an uncertain string (typically STT output) and a source of truth (a single string or an array of strings) — and returns the source-of-truth entry that best matches the uncertain input. It uses RapidFuzz composite scoring so imperfect transcriptions still map to the right label. This mirrors the two-input shape of the Conditional node, but instead of an exact comparison it returns a similarity score plus the matched string.
Palette category: Transform & Routing. Runs on cloud workflows and edge workers (same matching logic in both paths).

Typical chain

audio_track → wake_word_engine → audio_assistant → call_model (STT)
  → fuzzy_matcher ← twin (control_actuations / control_labels)
  → virtual_controller / conditional / downstream logic
Wire query (uncertain string) from Call Model result. Wire candidates (source of truth) from Twin node control_actuations — either an array, or a single string from any upstream node. Branch on match and pass match_string into actuation.

Inputs

FieldTypeRequiredDescription
querystringYes*Uncertain string to match (for example STT output). *Use a static value in the inspector when unwired.
candidatesstring | arrayYes*Source of truth: either a single string or an array of strings. A lone string is treated as a one-entry source of truth. *One label per line in the inspector when unwired.
score_thresholdnumberNoMinimum RapidFuzz score (0–100) to set match to true. Default 80. Set in the inspector or wire from upstream.
Inspector (node parameters):
  • Score Threshold — minimum similarity (0–100) to count as a match. Higher = stricter. Default 80.
  • Uncertain String (optional) — static fallback when query is not wired from upstream.
  • Source of Truth (optional) — one option per line, or a single string. Used when candidates is not wired from upstream.
Precedence: wired input mapping → node parameter → default (80 for threshold).

Outputs

FieldTypeDescription
matchbooleantrue when the best source-of-truth entry score ≥ score_threshold; false otherwise.
scorenumberBest RapidFuzz similarity (0–100) for the winning entry, even when match is false.
match_stringstringThe source-of-truth string that best matched the uncertain input (original casing). Empty when match is false.
Deprecated aliases (kept for older workflows):
FieldAlias of
matchedmatch
predictedmatch_string
matched_commandmatch_string
Advanced echo (debugging): query, candidates, score_threshold.

How matching works

  1. Normalize query and each candidate: lowercase, collapse whitespace, treat _ and - as spaces, strip punctuation (move_forwardmove forward).
  2. Score each candidate with the max of:
    • token_set_ratio — extra words, shuffled order
    • token_sort_ratio — similar order with typos
    • partial_ratio (both directions) — label inside a long phrase, or short utterance inside a label
    • WRatio — general typo tolerance
  3. Pick the highest-scoring source-of-truth entry as match_string.
  4. Set match to true only if that score ≥ score_threshold.
RapidFuzz scores are always on a 0–100 scale (100 = perfect after normalization).

Examples (threshold 80)

Query (STT)Dictionary labelTypical result
I want that you move forwardMove Forwardmatch: true, match_string: "Move Forward"
more forward / mole forwardMove Forwardmatch: true (typos)
move forwardemove_forwardmatch: true
forward / forwardeMove Forwardmatch: true (substring + typo)
what is the time tomorrowturn on the kitchen lightmatch: false, match_string: "", low score

Tuning score_threshold

ValueEffect
80 (default)Balanced for voice commands
Lower (e.g. 70)More tolerant of noisy STT; more false positives
Higher (e.g. 85)Stricter; short or typo-heavy utterances may need a higher raw score to pass
Use the score output to calibrate: if good phrases often score 75–79, lower the threshold slightly; if unrelated text still passes, raise it.

Execution targets

TargetNotes
CloudWorkflowUtils._execute_fuzzy_matcher_node — requires rapidfuzz in backend deps.
Edgefuzzy_matcher code emitter — worker needs cyberwave[fuzzy-match] / cyberwave-edge-core[fuzzy-match].

Dependencies

LayerRequirement
Compile serverrapidfuzz in cyberwave-backend/requirements/base.txt. provision_fuzzy_match_for_compile() fails compile if missing.
Edge workercyberwave[fuzzy-match] or cyberwave-edge-core[fuzzy-match]
edge-syncmodel_requirements: edge_package: fuzzy-match, edge_runtime: rapidfuzz
Error if compile server lacks the package:
This workflow uses Fuzzy Matcher but rapidfuzz is not installed on the compile server. Install rapidfuzz (or cyberwave[fuzzy-match]) on Django before compiling for edge.
See Edge workflow dependencies.