Padatious Pipeline¶
Maturity — Stable ⬤⬤⬤⬤◯
Established and production-ready, actively maintained. Rated by repository health, not version.
In a nutshell
Padatious is one of the tools that helps the assistant work out what you want. Instead of matching fixed keywords, a skill gives it a handful of example sentences (like "what is the weather" and "what's the weather like"), and Padatious learns the pattern so it can recognize new phrasings of the same request. It is the "learns from examples" companion to the keyword-based Adapt tool. See the Glossary for unfamiliar terms.
Shipped in the default pipeline.
The rest of this page is for people deploying or customizing OVOS. If you only wanted to know what this stage does, you are done.
📐 Formal specification
Padatious is a pipeline plugin under OVOS-PIPELINE-1 — Utterance Lifecycle & Pipeline. It is a template-intent engine in the sense of OVOS-INTENT-3 — Intent Definition §5: the .intent example sentences are training data, written in the OVOS-INTENT-1 — Sentence Template Grammar with {slot} placeholders the engine fills at match time. See the spec index.
The Padatious Pipeline Plugin brings example-based intent recognition to the OpenVoiceOS (OVOS) pipeline. You define each intent by listing a few example sentences in a plain-text .intent file. Padatious trains a small neural network (numpy backend) on those examples and scores incoming utterances against them.
In OVOS-PIPELINE-1 terms Padatious is a pipeline plugin exposing match(utterances, lang, session) → Match | None. The orchestrator iterates session.pipeline and takes the first match. The conf_high/medium/low thresholds are Padatious's own per-stage accept gate, not a cross-plugin ranking. INTENT-1 §4 and INTENT-3 §1.1 leave generalization and scoring entirely engine-specific. This is exactly why a capable engine recognizes phrasings beyond its training samples.
When it runs: Padatious sits early in the pipeline. Its high-confidence stage runs before Adapt, so a strong example match wins over a keyword rule. The medium and low stages run later, as the pipeline relaxes its confidence requirements.
Minimal example: drop a weather.intent file in your skill's locale/en-us/ folder:
and wire it up:
from ovos_workshop.decorators import intent_handler
@intent_handler("weather.intent")
def handle_weather(self, message):
...
How it works¶
flowchart TD
F[.intent example files] --> TR[Train neural model]
TR --> MO[Trained model, cached]
U[Utterance] --> SC[Score against model]
MO --> SC
SC --> C{Best score clears\nstage threshold?}
C -->|yes| I[Intent + confidence + slots]
C -->|no| N[No match, try next stage]
Diagram: example sentences train a small neural model ahead of time, then an incoming utterance is scored against that model, and the best-scoring intent is returned only if it clears the current stage's confidence threshold.
Pipeline Stages¶
The plugin ships a single OPM entry point, ovos-padatious-pipeline-plugin, mapped to the PadatiousPipeline class. That class is a ConfidenceMatcherPipeline, so OVOS exposes three matcher stages from it. You select these in your pipeline config by the IDs below (the short padatious_* aliases still work but are deprecated):
| Pipeline ID | Legacy alias | Matcher | Recommended Use |
|---|---|---|---|
ovos-padatious-pipeline-plugin-high |
padatious_high |
match_high |
Primary stage for Padatious use |
ovos-padatious-pipeline-plugin-medium |
padatious_medium |
match_medium |
Backup, if confidence tuning allows |
ovos-padatious-pipeline-plugin-low |
padatious_low |
match_low |
Not recommended (often inaccurate) |
Each stage runs at a different point in the pipeline and applies a different confidence threshold to the same scored result.
Configuration¶
Configure Padatious thresholds in your mycroft.conf under intents → ovos-padatious-pipeline-plugin (the canonical, plugin-id-keyed section. The older padatious key is read as a fallback if the canonical one is absent). The defaults are:
{
"intents": {
"ovos-padatious-pipeline-plugin": {
"conf_high": 0.95,
"conf_med": 0.8,
"conf_low": 0.5
}
}
}
These thresholds gate which matcher stage accepts a given result.
Other useful config keys read by the plugin:
| Key | Default | Effect |
|---|---|---|
cast_to_ascii |
false |
Strip accents before matching |
stem |
false |
Apply Snowball stemming to examples and utterances |
disable_padaos |
false |
Disable the bundled regex fast-path and use only the neural matcher. Affects tier placement: an exact trained utterance scores conf=1.0 with padaos enabled, but only ~0.67-0.69 from the neural matcher alone, below the medium-confidence threshold. Disabling padaos pushes exact matches out of the high-confidence tier and into a lower one. |
intent_cache |
XDG data dir | Where trained intent models are cached |
domain_engine |
false |
Train a separate model per skill domain instead of one flat model |
instant_train |
false |
Retrain synchronously on every registration instead of batching |
Multilingual Support¶
Padatious is excellent for multilingual environments because intents are defined in plain text .intent files, not in code. This allows translators and non-developers to contribute new languages easily without touching Python.
To add another language, simply create a new .intent file in the relevant language folder, such as:
Defining Intents¶
Intent examples are written line-by-line in .intent files:
Skills can also capture free-form values with .entity files, one example value per
line — training hints that score a slot fill, not a closed vocabulary (see
Padatious Intents for what happens to values outside the file) — referenced from an .intent file with {filename} braces (the entity file's
basename becomes the placeholder name). For example, a location.entity file:
referenced from weather.intent:
The matched value is delivered to the intent handler as message.data["location"].
In your skill:
from ovos_workshop.decorators import intent_handler
@intent_handler("weather.intent")
def handle_weather(self, message):
# Your code here
pass
Limitations¶
Padatious is reliable in terms of not misclassifying. It rarely picks the wrong intent. However, it has key limitations:
-
Weak paraphrase handling: If the user speaks a sentence that doesn't closely match an example, Padatious will often fail to match anything at all.
-
Rigid phrasing required: You may end up in a "train the user to speak correctly" scenario, instead of training the system to understand variations.
-
Maintenance burden for sentence diversity: Adding more phrasing requires adding more sentence examples per intent, increasing effort and clutter.
Padacioso (literal, no-model matching) and Nebulento (fuzzy matching) are drop-in replacements that address these limits.
When to Use¶
Padatious is a good choice in OVOS when:
-
You want easy localization/multilingual support.
-
You're creating simple, personal, or demo skills.
-
You can control or guide user phrasing, such as in kiosk or assistant environments.
Avoid Padatious for complex conversational use cases, skills with overlapping intents, or scenarios requiring broad paraphrasing support.
Advanced¶
Entry point and class. The plugin registers one opm.pipeline entry point:
[project.entry-points."opm.pipeline"]
"ovos-padatious-pipeline-plugin" = "ovos_padatious.opm:PadatiousPipeline"
PadatiousPipeline subclasses ConfidenceMatcherPipeline, exposing match_high, match_medium, and match_low. The plugin manager derives the _high/_medium/_low pipeline IDs from that single plugin at runtime. They are not separate entry points.
Files. Skills register .intent files (example sentences) and .entity files (entity value lists). Registration happens over the bus via padatious:register_intent and padatious:register_entity. Training is triggered by mycroft.skills.train and announced with mycroft.skills.trained. See the Bus Events Reference for the wider intent-matching event set these fit into.
Gotcha: training is asynchronous. Padatious must train its model before it can match. On a cold start (or after installing a skill), matches will fail until training completes. Set instant_train to force synchronous training when you need deterministic behavior in tests. A harness that probes matching should wait on mycroft.skills.trained first.
Every registration schedules a background training pass off the utterance-handling thread. Nothing is left dirty waiting for an unrelated live query to trigger it. Queries made while a retrain is in flight, and the intent.service.padatious.manifest.get bus response, still serve the previous trained generation instead of blocking or erroring. Re-registering an intent or entity with unchanged content is a no-op. Both workers debounce a burst of registrations into a single retrain instead of retraining once per registration. Each new registration resets a 2-second quiet timer. The retrain fires once nothing new arrives within that window, capped at a 60-second maximum wait so a slow, steady trickle of registrations still eventually trains.
mycroft.skills.trained only fires once every container a training pass touched is fully compiled, both the neural model and the padaos regex layer. A registration that lands mid-pass defers the signal to the next pass instead of firing early, so a caller waiting on this event can rely on exact matches being live when it fires.
Per-domain training. Setting domain_engine: true in the plugin's config trains a separate model per skill domain (using the same ovos-padatious-pipeline-plugin entry point) instead of one flat model across all skills, reducing cross-skill collisions at the cost of extra memory.
Upcoming
A dedicated DomainPadatiousPipeline OPM entry point (a first-class plugin ID for the per-domain training mode, instead of the domain_engine config flag on the flat plugin) is Upcoming.
Read next: Model2Vec Pipeline Related: Nebulento · Padatious Intents · Adapt Pipeline · Debugging Intent Matching