Il modello propone un piano, ma non decide liberamente la forma del comando. Metnos gli presenta un insieme ristretto di executor e, quando il servizio del modello supporta GBNF, vincola la decodifica alla struttura del Framework e ai nomi ammessi. Parsing, validazione e Vaglio controllano poi il risultato prima di ogni esecuzione.
Chiedi a Metnos con una richiesta come questa:
Trova i PDF modificati questa settimana nella cartella Progetti, calcola l'impronta SHA-256 di ciascuno e mostrami il risultato.
Il pianificatore non deve rispondere con una spiegazione vaga. Deve produrre una struttura simile a questa, limitata ai nomi presenti nel sottoinsieme calcolato per il turno:
{
"steps": [
{"tool": "find_files", "args": {"path": "Progetti", "extension": "pdf"}},
{"tool": "compute_signatures", "args": {"algorithm": "sha256"}}
]
}
L'esempio illustra la forma, non autorizza i percorsi e non sostituisce il riempimento degli argomenti. Le date relative, i riferimenti fra passi e gli ambiti del file system vengono risolti e verificati dagli strati successivi.
| Livello | Stato e funzione |
|---|---|
build_framework_grammar | È il percorso ordinario quando METNOS_PROPOSER_GRAMMAR=1, valore predefinito. Vincola la forma del Framework e il campo tool ai nomi del sottoinsieme effettivo; include final_answer come terminale valido. |
build_framework_grammar_typed | Con METNOS_PROPOSER_GRAMMAR_ARGS=1 lega inoltre ogni nome allo schema dei suoi argomenti. Esclude gli argomenti marcati runtime_resolved, che appartengono al runtime. Questa modalità non è il valore predefinito. |
runtime/tool_grammar.py contiene il traduttore da JSON Schema a
GBNF, la validazione della chiamata e i filtri semantici riusati dal motore.
L'API generate_tool_grammar genera una singola
tool_call; il pianificatore usa invece la grammatica del Framework,
che può contenere più passi.
I segnali in linguaggio naturale — per esempio annullamento, ricorrenza, prossimità, skill e nomi dei fornitori — provengono dal lessico di riconoscimento traducibile. Una nuova lingua richiede dati lessicali per quella lingua, non condizioni inserite nel codice per singole frasi.
Quando il vincolo sugli argomenti è attivo, ogni passo ha un ramo
proprio: il nome compute_signatures può essere seguito soltanto
dagli argomenti ricavati dal suo schema. Gli elenchi chiusi diventano
alternative GBNF; stringhe, numeri, booleani, array e oggetti annidati sono
tradotti nelle primitive corrispondenti. Se uno schema non è tipizzabile,
quel ramo usa argomenti JSON liberi e lascia la verifica all'executor.
| La grammatica garantisce | La grammatica non garantisce |
|---|---|
| Una struttura JSON ammessa dal profilo generato. | Che il piano soddisfi davvero la richiesta dell'utente. |
| Nel percorso ordinario, nomi di executor appartenenti al sottoinsieme del turno. | Che l'utente abbia autorizzato l'azione o il percorso indicato. |
| Con la modalità tipizzata, corrispondenza fra nome e schema degli argomenti per i rami traducibili. | Postcondizioni, effetti reali, disponibilità del servizio o correttezza dei dati. |
| Un'uscita più facile da analizzare e rifiutare in modo esplicito. | Riproducibilità assoluta del ragionamento linguistico o del contenuto libero. |
La profondità della traduzione degli schemi è limitata. Oltre il limite, o davanti a costrutti complessi, il generatore ricorre a JSON generico. La validazione successiva controlla forma superiore, nome, argomenti obbligatori e terminali sintetici; la convalida profonda resta responsabilità dell'executor e del contratto comune.
La costruzione della grammatica applica alcune regole necessarie al servizio locale attuale:
tools;Se il servizio non accetta il parametro grammar, il passaggio
alla modalità senza grammatica viene registrato. Il piano deve comunque
superare l'analisi sintattica e la validazione, ma non beneficia più del
vincolo applicato durante la decodifica.
Dato lo stesso sottoinsieme ordinato e gli stessi schemi, la stringa GBNF generata è deterministica. Questo rende confrontabile la superficie offerta al modello e impedisce che un nome assente compaia nel percorso vincolato. Non rende deterministica l'intera risposta del modello: testo libero, valori semantici e piani nuovi restano prodotti da un'inferenza probabilistica.
La grammatica viene costruita in memoria e non compie chiamate di rete. Il costo principale è nella decodifica, perché il servizio deve eliminare a ogni passo i token non ammessi. Metnos riduce tale costo costruendo la grammatica sul sottoinsieme del turno, non sull'intero catalogo, e assegna al proponente un bilancio di uscita calcolato dalla complessità della richiesta.
Le prove non sono descritte con un conteggio fisso, che diventerebbe presto obsoleto. Le suite principali sono:
tests/runtime/engine/test_tool_grammar.py tests/runtime/engine/test_grammar_args_typed.py tests/runtime/engine/test_routing_pool.py tests/runtime/engine/test_tool_call_parser.py
Coprono generazione deterministica, unione nome-argomenti, schemi annidati, elenchi chiusi, filtri per intento e fornitore, terminali sintetici, eliminazione dei duplicati e recupero delle uscite troncate. Le prove del motore verificano inoltre che il piano non possa nominare executor esclusi dal sottoinsieme.
GBNF è il meccanismo usato dal servizio locale compatibile con llama.cpp. Altri servizi possono offrire JSON Schema vincolato o chiamate di strumenti native. Il contratto di Metnos non dipende dal nome commerciale del fornitore: un adattatore è adatto soltanto se dichiara con precisione quale livello di vincolo applica e restituisce dati che il parser e i validatori comuni possono controllare.
La pagina Virtualizzazione dei modelli spiega come i ruoli logici vengono associati ai servizi configurati. Cambiare servizio non deve cambiare il vocabolario degli executor, l'autorità dell'utente o le regole del Vaglio.
runtime/engine/grammar_framework.py — grammatica del Framework e variante con argomenti tipizzati;runtime/tool_grammar.py — traduzione degli schemi, validazione e filtri deterministici;runtime/engine/proposer.py — scelta della modalità e invocazione del modello;runtime/llm_provider.py — trasporto della grammatica e parsing delle risposte del servizio.