Skip to content

tour_leger

tour_leger

Un modèle léger pour les tours courts ; le modèle choisi garde les tâches lourdes.

20 septembre 2026 : Carlito avait choisi qwen3.8:27b-mlx dans le sélecteur du chat. Ce modèle tient 18 à 26 Go sur un Mac de 32 Go qui n'en avait que 10,5 de libres au chargement (journal d'Ollama, 10:54:14). Résultat sur deux questions d'une ligne : « Qui est le président actuel d'Haïti ? » 56,6 s, « Que veut dire "Self Aware" en français ? » 89,4 s — pendant que « Ouvre moi YouTube et joue… », servi sans modèle par la voie éclair, prenait 1,2 s. Le classificateur de complexité marquait les deux « trivial » (0,06) mais ne changeait que le budget de jetons, jamais le modèle. Ses motifs sont anglais (explain, why, write) : en français presque tout est « trivial », il ne peut donc pas servir de critère de routage.

Règle : quand [intelligence].light_model est configuré, un tour LÉGER part sur ce modèle et le modèle choisi reste pour le reste. Léger = une demande d'une ou deux lignes, sans image, sans code, sans quantité (« 30 exercices »), sans production ni raisonnement demandé. Le modèle réellement utilisé est écrit dans chaque fragment (model) et dans le bilan (routing) : rien n'est fait semblant. Une trousse fournie par le client (API brute) et un modèle distant ne sont jamais reroutés.

Limite connue, mesurée : deux modèles ne cohabitent pas quand le lourd occupe la mémoire. Recharger le 27b après un tour léger coûte 7 s de démarrage plus une première passe qui repagine 18 Go (1 min 38 s le 20 septembre à 10:55) ; choisir le 27b dans le sélecteur le précharge, et un premier message léger l'évince aussitôt. Une suite (« Continue ») garde le modèle du tour qu'elle prolonge, mais une question neuve change de modèle. Sur cette machine, le remède de fond reste le 9b comme modèle du quotidien — ce routage évite seulement de payer le 27b pour une traduction.

Classes

Routage dataclass

Routage(
    modele: str, origine: str | None = None, motif: str = ""
)

Le modèle du tour, et d'où il vient quand il a changé.

Functions:

est_un_tour_leger

est_un_tour_leger(messages: Sequence[Message]) -> bool

Vrai si la demande courante se règle bien avec un petit modèle.

Le poids se propage : une suite (« Continue », « Plus court », trois mots ou moins) garde le poids du tour qu'elle prolonge, de proche en proche — « Rédige… » → « Continue » → « Encore » restent sur le modèle choisi.

Source code in src/diapason/server/tour_leger.py
def est_un_tour_leger(messages: Sequence[Message]) -> bool:
    """Vrai si la demande courante se règle bien avec un petit modèle.

    Le poids se propage : une suite (« Continue », « Plus court », trois mots
    ou moins) garde le poids du tour qu'elle prolonge, de proche en proche —
    « Rédige… » → « Continue » → « Encore » restent sur le modèle choisi.
    """
    leger = False
    premiere = True
    for demande in (m for m in messages if m.role == Role.USER):
        propre = _legere_en_soi(demande)
        if propre and not premiere and not leger and _est_une_suite(demande):
            propre = False
        leger, premiere = propre, False
    return leger and not premiere

choisir_le_modele

choisir_le_modele(
    modele: str,
    messages: Sequence[Message],
    config: Any,
    *,
    trousse_du_client: bool = False,
    engine: Any = None,
) -> Routage

Le léger configuré pour un tour léger ; sinon le modèle demandé.

Source code in src/diapason/server/tour_leger.py
def choisir_le_modele(
    modele: str,
    messages: Sequence[Message],
    config: Any,
    *,
    trousse_du_client: bool = False,
    engine: Any = None,
) -> Routage:
    """Le léger configuré pour un tour léger ; sinon le modèle demandé."""
    intelligence = getattr(config, "intelligence", None)
    leger = str(getattr(intelligence, "light_model", "") or "").strip()
    if not leger or trousse_du_client:
        return Routage(modele)
    demande = modele
    if modele in ("", "default"):
        demande = str(getattr(intelligence, "default_model", "") or modele)
    if demande == leger or _est_distant(demande):
        return Routage(modele)
    if not est_un_tour_leger(messages):
        return Routage(modele)
    if engine is not None and not modele_disponible(engine, leger):
        return Routage(modele)
    return Routage(leger, origine=demande, motif="tour léger")