← Documentation index Microarchitecture › introvertive fast-path

Metnos

introvertive fast-path — how the assistant learns to answer instantly
Microarchitecture

Audience: anyone who wants to understand why Metnos sometimes answers
in half a second, and sometimes takes ten.
Reading time: 10 minutes.

Table of contents

  1. The idea, in two lines
  2. Why a fast-path is necessary
  3. The two layers
  4. L0 — auto-produced cache (fastpath.py)
  5. L1 — autopaths promoted by rating (autopath.py)
  6. Aging, death and inheritance
  7. The arguments extractor
  8. Configuration
  9. Promotion to a synthesised executor

1. The idea, in two lines

Before calling on the planner, Metnos tries to recognise the request. If it has seen it before and already knows how to handle it, it reuses the ready-made path — the sequence of executors that carries the request through — and answers in half a second instead of ten. No language model to consult: memory is enough.

request user query L0 fastpath hash + cosine L1 autopath feedback ✓ cluster engine LLM planner
Figure 1 — The memory layers ahead of the engine: L0 fastpath (hash + cosine), L1 autopath (user feedback); if neither fires, the request goes through to the engine — the LLM planner.

2. Why a fast-path is necessary

The Metnos planner is a local language model — the wise tier, the most capable one. It reasons well, but it takes about ten seconds to choose the first step of a turn: for many requests that wait is out of all proportion. “What time is it?” doesn't call for a model, it calls for the get_now tool. And “download this page and sum it up in two lines”, when we ask it often, doesn't call for the planner but for a path we already know: get_urls, then describe_entries.

What remains is to recognise a known request — and to judge when one that is merely similar sits close enough to be handled the same way. That is the job of the introvertive fast-path, on two layers: they catch different degrees of similarity, but reach the same result, the right path run without a second thought.

3. The two layers

The two layers differ in how much of the path they recognise. L0 recognises all of it, arguments included: the same request as before, with the same concrete values. L1 recognises the path alone — the skeleton of the solution, stripped of its arguments — and so it holds for a whole family of related requests.

LayerWhat it recognisesHowCost per reuse
L0Path + arguments. The same request already solved — identical or very close in meaning — with its concrete values (that name, that URL, that date).Exact hash (0a) + BGE-M3 cosine (0b)< 5 ms (hash) / < 150 ms (cosine)
L1The path alone. The generalised skeleton, without arguments, valid for a group of related requests the user has confirmed.Lookup by intent and group~30 ms

The order is fixed: L0 first; if it finds nothing, L1. If both miss, the request reaches the planner (the engine), as always.

Note. The planner doesn't go away: the fast-path sits beside it, it doesn't replace it. If the request is new, ambiguous, or clears no threshold in either search, the planner takes over again, as if the fast-path weren't there.

4. L0 — auto-produced cache (fastpath.py)

The first layer lives in runtime/engine/fastpath.py and keeps the plans it has already run in a SQLite database (fastpaths.sqlite). The entries appear on their own: whenever a turn succeeds — a fresh plan from the engine, the reuse of an L1, a promotion from cosine 0b — Metnos notes down the canonical query, its hash, the BGE-M3 embedding (the numeric form of the text, the one used to gauge closeness in meaning), the whole plan (the skeleton, or framework) and the intent: the verb and the object of the request. No approval involved: the chains are built from executors already vetted and tested.

Two ways to find a match

The search runs in two phases:

They rebuild themselves. A fastpath that is deleted — by aging, by death, or by a negative user rating — comes back on the first successful repeat. Pruning is cheap, then, and the defaults can afford to be aggressive: nothing is lost for good.

Safety valves

5. L1 — autopaths promoted by rating (autopath.py)

The second layer lives in runtime/engine/autopath.py and thinks differently: it doesn't repeat the same query but generalises to a group of related intents — the one the user has approved with a positive rating.

At each user “✓”, Metnos notes the turn's skeleton, its hash and the group of meaning it belongs to. A few confirmations — configurable, one by default — on the same skeleton and group are enough for the plan to become a reusable autopath: next time, an intent from the same group sets it going again without troubling the planner.

Anti-autopaths, champion and challenger

The L0/L1 boundary. L0 repeats the same query and also admits plans tied to a single request, recognised by exact fingerprint. L1 generalises to a group of related intents, with the user's explicit consent. In the cascade L0 comes first and takes precedence: if it finds an exact match it skips everything else — even an L1 autopath fit for that intent.

6. Aging, death and inheritance

L0 fastpaths age and die by fixed rules, with no model in the loop. Each night the task_state_reaper process applies three aging rules and four death conditions.

Aging

RuleCriterionDefaultEnv
Never reusedCreated more than N days ago but never served a second time14 daysMETNOS_FASTPATH_GRACE_DAYS
StaleLast use more than N days ago30 daysMETNOS_FASTPATH_STALE_DAYS
LRU capTotal entries above the cap; least recently used are pruned500METNOS_FASTPATH_MAX

Death (only with complete catalogue)

CodeCauseInheritance
C1A tool in the plan no longer exists in the catalogue (retired, renamed, archived). Replay would fail.No
C2 provenanceThe fastpath was promoted to a synthetic executor (see §9) and that executor is now in the catalogue.Yes
C2 nameAn executor named {verb}_{object} matching the intent exists, but no tool in the plan belongs to that family. The fastpath would shadow the executor.Yes
C2 pre-filterFor multi-step plans: the deterministic routing pre-filter on the canonical query shows that a single executor now covers the intent (even under a different name).Yes

Point inheritance

When a fastpath dies because an executor has superseded it (the C2 conditions), its usage counts (n_uses) pass to the heir executor, along the same aging machinery the executors use. The demand already gathered isn't thrown away.

Pruning is nothing to fear. Even a fastpath removed by mistake comes back on the first successful repeat. That is why it can be pruned freely: nothing is lost for good.

7. The arguments extractor

Recognising the request is half the work. The other half is drawing out its concrete values: which paths, which URLs, which date, which threshold. A rule-based extractor (args_extractor.py) handles this, again with no model:

8. Configuration

The fast-path is tuned with METNOS_* environment variables. For values meant to last there is a TOML file (~/.config/metnos/runtime.toml); the value written in the module is the last net, when everything else is silent.

Layer 0 (fastpath)

VariableDefaultMeaning
METNOS_FASTPATH_STALE_DAYS30Calendar days after which an unused entry is pruned
METNOS_FASTPATH_GRACE_DAYS14Grace days for never-reused entries
METNOS_FASTPATH_MAX500Maximum rows (LRU cap)

Layer 1 (autopath)

VariableDefaultMeaning
METNOS_AUTOPATH_MIN_OBS1Minimum positive observations to promote an autopath
METNOS_AUTOPATH_TTL_ANTI2592000 (30 d)Anti-autopath duration in seconds
METNOS_AUTOPATH_TTL_REPEAT3600 (1 h)Short window for repeated ratings

Promotion to executor

VariableDefaultMeaning
METNOS_FP_PROMOTE_MIN_CLUSTER3Minimum distinct fastpaths in the group
METNOS_FP_PROMOTE_MIN_USES15Minimum cumulative usage
METNOS_FP_PROMOTE_MIN_AGE_DAYS30Minimum group age
METNOS_FP_PROMOTE_MAX_PER_NIGHT3Maximum new proposals per night
METNOS_FASTPATH_AUTOPROMOTEoffEnables Mode 2 auto-promotion (no human approval)

9. Promotion to a synthesised executor

When several recurring L0 fastpaths share the same plan structure (the skeleton hash) and the same intent, each night the task_fastpath_promotion process weighs them as candidates to become a synthetic executor in their own right. What it weighs is the group, never the single instance: at least three distinct fastpaths, fifteen uses in all, and thirty days of age. And only multi-step shapes are promoted: single-step ones already have an executor, and there the fastpath only saves the LLM call, not the plan.

Why from L0 and not from L1. The analysis looks at the L0 fastpaths, not the L1 autopaths, because the evidence of real demand lives in L0: how many concrete, distinct requests recur, how often, for how long (the three numbers above). L1 is already general, but it springs from a different signal — the user's “✓” — and carries no such count of instances. The generalisation one would credit to L1 happens all the same, but here: by gathering the L0 fastpaths that share a plan shape and an intent.

Two modes of promotion

Where an executor comes from

At promotion time Metnos notes, in a table (promotions), which fastpaths the new executor was born from: it records their identifiers and fingerprints. This is what closes the loop. Once the executor is in the catalogue, the fastpaths that produced it are no longer needed and get retired (the “C2 provenance” death condition from §6). Thanks to that note the retirement is exact: Metnos knows for certain which fastpaths to remove, because the link between each fastpath and its heir is written down, not guessed from the name.

© 2026 Roberto Brunialti · Metnos documentation