← Indice documentazione Microprogettazione › fast-path introvertivo

Metnos

fast-path introvertivo — come l'assistente impara a rispondere subito
Microprogettazione

Pubblico: chi vuole capire perché Metnos a volte risponde in mezzo secondo
e a volte ci mette dieci.
Lettura: 10 minuti.

Indice

  1. L'idea in due righe
  2. Perché serve un fast-path
  3. I due livelli
  4. L0 — cache auto-prodotta (fastpath.py)
  5. L1 — autopath promossi dal riscontro (autopath.py)
  6. Invecchiamento, morte e eredità
  7. L'estrattore di argomenti
  8. Configurazione
  9. Promozione a executor sintetico

1. L'idea in due righe

Prima di interpellare il pianificatore, Metnos prova a riconoscere la richiesta. Se l'ha già vista e sa già come risolverla, ne riusa il path già pronto — la sequenza di executor che la porta a termine — e risponde in mezzo secondo invece che in dieci. Niente modello linguistico da consultare: basta la memoria.

richiesta query utente L0 fastpath impronta + coseno L1 autopath riscontro ✓ gruppo motore pianificatore LLM
Figura 1 — I livelli di memoria prima del motore: L0 fastpath (impronta + coseno), L1 autopath (riscontro dell'utente); se nessuno dei due scatta, la richiesta passa al motore, cioè al pianificatore LLM.

2. Perché serve un fast-path

Il pianificatore di Metnos è un modello linguistico locale, il tier wise, il più capace. Ragiona bene, ma per scegliere il primo passo di un turno ci mette una decina di secondi: per molte richieste è un'attesa fuori misura. «Che ora è?» non chiede un modello, chiede lo strumento get_now. E «scaricami questa pagina e descrivimela in due righe», se la chiediamo spesso, non chiede il pianificatore ma un path già noto: get_urls, poi describe_entries.

Resta da capire come riconoscere una richiesta nota — e quando una soltanto somigliante è abbastanza vicina da trattarla allo stesso modo. È il compito del fast-path introvertivo, su due livelli: colgono gradi diversi di somiglianza, ma arrivano allo stesso risultato, il path giusto eseguito senza ripensarci.

3. I due livelli

I due livelli si distinguono per quanto riconoscono del path. L0 ne riconosce tutto, argomenti compresi: la stessa richiesta di prima, con gli stessi valori concreti. L1 riconosce il solo path — lo scheletro della soluzione, spogliato degli argomenti — e per questo vale per un'intera famiglia di richieste affini.

LivelloCosa riconosceComeCosto a ogni riuso
L0Path + argomenti. La stessa richiesta già risolta — identica o di significato molto vicino — con i suoi valori concreti (quel nome, quell'URL, quella data).Confronto per impronta (0a) + coseno BGE-M3 (0b)< 5 ms (impronta) / < 150 ms (coseno)
L1Solo il path. Lo scheletro generalizzato, senza argomenti, valido per un gruppo di richieste affini già confermato dall'utente.Ricerca per intent e gruppo~30 ms

L'ordine è fisso: prima si tenta L0; se non trova corrispondenza si passa a L1. Se mancano entrambi, la richiesta arriva al pianificatore (il motore), come sempre.

Nota. Il pianificatore non sparisce: il fast-path lo affianca, non lo sostituisce. Se la richiesta è nuova, ambigua o non supera la soglia di nessuna delle due ricerche, riprende in mano lui, come se il fast-path non ci fosse.

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

Il primo livello vive in runtime/engine/fastpath.py e custodisce, in un database SQLite (fastpaths.sqlite), i piani già eseguiti. Le voci nascono da sole: ogni volta che un turno va a buon fine — un piano nuovo del motore, il riuso di un L1, una promozione dal coseno 0b — Metnos annota la query canonica, la sua impronta, l'embedding BGE-M3 (la forma numerica del testo, quella con cui se ne misura la vicinanza di significato), il piano per intero (lo scheletro, o framework) e l'intent, cioè il verbo e l'oggetto della richiesta. Nessuna approvazione: le catene sono fatte di executor già vagliati e provati.

Due modi di trovare la corrispondenza

La ricerca avviene in due fasi:

Si rifanno da soli. Un fastpath cancellato — per invecchiamento, per morte o per un riscontro negativo — rinasce alla prima ripetizione riuscita. La potatura costa poco, allora, e i valori predefiniti possono permettersi di essere aggressivi: nulla va perso per sempre.

Valvole di sicurezza

5. L1 — autopath promossi dal riscontro (autopath.py)

Il secondo livello vive in runtime/engine/autopath.py e ragiona in modo diverso: non ripete la stessa query, ma generalizza a un gruppo di intent affini, quello che l'utente ha approvato con un riscontro positivo.

A ogni «✓» dell'utente, Metnos annota lo scheletro del turno, la sua impronta e il gruppo di significato a cui appartiene. Bastano poche conferme — configurabili, di base una sola — sullo stesso scheletro e gruppo perché il piano diventi un autopath riusabile: la volta dopo, un intent dello stesso gruppo lo rimette in moto senza disturbare il pianificatore.

Anti-autopath e confronto campione/sfidante

Confine fra L0 e L1. L0 ripete la stessa query e ammette anche i piani legati a una singola richiesta, riconosciuti per impronta esatta. L1 generalizza a un gruppo di intent affini, con il consenso esplicito dell'utente. In cascata L0 viene per primo e ha la precedenza: se trova una corrispondenza esatta, salta tutto il resto — anche un autopath L1 buono per quell'intent.

6. Invecchiamento, morte e eredità

I fastpath L0 invecchiano e muoiono per regole fisse, senza che nessun modello ci metta mano. Ogni notte il processo task_state_reaper applica tre regole d'invecchiamento e quattro condizioni di morte.

Invecchiamento

RegolaCriterioDefaultEnv
Mai riusatoCreato da oltre N giorni ma mai servito una seconda volta14 giorniMETNOS_FASTPATH_GRACE_DAYS
StantioUltimo uso oltre N giorni fa30 giorniMETNOS_FASTPATH_STALE_DAYS
Cap LRUTotale entry superiore al tetto; le meno recenti vengono potate500METNOS_FASTPATH_MAX

Morte (solo con catalogo completo)

CodiceCausaEredità
C1Uno strumento del piano non esiste più nel catalogo (ritirato, rinominato, archiviato). La riesecuzione fallirebbe.No
C2 provenienzaIl fastpath è stato promosso a executor sintetico (vedi §9) e quell'executor è ora nel catalogo.
C2 nomeEsiste un executor con nome {verbo}_{oggetto} corrispondente all'intent, ma nessuno strumento del piano appartiene a quella famiglia. Il fastpath oscurerebbe l'executor.
C2 pre-filtroPer i piani a più passi: il pre-filtro di instradamento deterministico sulla query canonica indica che un singolo executor copre l'intent (anche con nome diverso).

Eredità dei punti

Quando un fastpath muore perché un executor lo ha superato (le condizioni C2), i suoi conteggi d'uso (n_uses) passano all'executor erede, lungo lo stesso meccanismo d'invecchiamento degli executor. La domanda già raccolta non si butta via.

La potatura non fa paura. Anche un fastpath tolto per errore rinasce alla prima ripetizione riuscita. Per questo si può potare con generosità: non si perde niente per sempre.

7. L'estrattore di argomenti

Riconoscere la richiesta è metà del lavoro. L'altra metà è ricavarne i valori concreti: quali path, quali URL, quale data, quale soglia. Se ne occupa un estrattore a regole (args_extractor.py), anch'esso senza modello:

8. Configurazione

Il fast-path si regola con variabili d'ambiente METNOS_*. Per i valori che devono restare nel tempo c'è un file TOML (~/.config/metnos/runtime.toml); il valore scritto nel modulo è l'ultima rete, quando tutto il resto tace.

Livello 0 (fastpath)

VariabileDefaultSignificato
METNOS_FASTPATH_STALE_DAYS30Giorni calendario dopo cui una entry non usata viene potata
METNOS_FASTPATH_GRACE_DAYS14Giorni di grazia per entry mai riusate
METNOS_FASTPATH_MAX500Tetto massimo righe (LRU)

Livello 1 (autopath)

VariabileDefaultSignificato
METNOS_AUTOPATH_MIN_OBS1Osservazioni positive minime per promuovere un autopath
METNOS_AUTOPATH_TTL_ANTI2592000 (30 gg)Durata di un'anti-autopath in secondi
METNOS_AUTOPATH_TTL_REPEAT3600 (1 h)Finestra breve per riscontri ripetuti

Promozione a executor

VariabileDefaultSignificato
METNOS_FP_PROMOTE_MIN_CLUSTER3Fastpath distinti minimo nel gruppo
METNOS_FP_PROMOTE_MIN_USES15Uso cumulato minimo
METNOS_FP_PROMOTE_MIN_AGE_DAYS30Età minima del gruppo
METNOS_FP_PROMOTE_MAX_PER_NIGHT3Massimo di nuove proposte per notte
METNOS_FASTPATH_AUTOPROMOTEoffAbilita l'auto-promozione di Modalità 2 (senza approvazione)

9. Promozione a executor sintetico

Quando più fastpath L0 ricorrenti condividono la stessa struttura di piano (l'impronta dello scheletro) e lo stesso intent, ogni notte il processo task_fastpath_promotion li soppesa come candidati a diventare un executor sintetico a tutti gli effetti. A pesare è il gruppo, mai la singola istanza: servono almeno tre fastpath distinti, quindici utilizzi in tutto e trenta giorni di età. E si promuovono solo gli schemi a più passi: quelli a passo singolo un executor ce l'hanno già, e lì il fastpath serve a saltare l'LLM, non a comporre il piano.

Perché da L0 e non da L1. L'analisi guarda i fastpath L0, non gli autopath L1, perché la prova della domanda reale è in L0: quante richieste concrete e distinte tornano, quante volte, da quanto tempo (i tre numeri qui sopra). L1 è già generale, ma nasce da un altro segnale — il «✓» dell'utente — e non porta con sé quel conteggio di istanze. La generalizzazione che si attribuirebbe a L1 c'è lo stesso, ma avviene qui: raccogliendo i fastpath L0 per stessa forma di piano e stesso intent.

Due modalità di promozione

Da dove viene un executor

Al momento della promozione, Metnos annota in una tabella (promotions) da quali fastpath è nato il nuovo executor: ne registra gli identificatori e le impronte. Serve a chiudere il cerchio. Quando l'executor entra nel catalogo, i fastpath che lo hanno generato non servono più e vengono ritirati (è la condizione di morte «C2 provenienza» del cap. 6). Grazie a quell'annotazione il ritiro è esatto: Metnos sa con certezza quali fastpath togliere, perché il legame fra ciascun fastpath e il suo erede è scritto, non indovinato dal nome.

© 2026 Roberto Brunialti · documentazione Metnos