Architecture des Profils et Configuration YAML

Présentation Générale

Mirza intègre une architecture modulaire et centralisée basée sur un fichier de configuration YAML unique (config.yaml). Cette refonte permet de :

  1. Définir des profils d’assistant modulaires et interchangeables (ex: assistant généraliste ou medical clinique).

  2. Centraliser la totalité des réglages (matériel, audio, STT, LLM, TTS, mémoire RAG, prompts).

  3. Garantir un chargement intelligent en mémoire (mise en cache singleton, zéro I/O disque répétitif lors des tours de parole).

  4. Permettre la sélection du profil et du fichier de configuration via des arguments en ligne de commande (--profile et --config).

  5. Permettre la bascule à chaud à l’exécution via l’API REST et le WebSocket sans interruption de service.

Structure du Fichier config.yaml

Le fichier racine config.yaml est structuré en plusieurs sections cohérentes :

# Profil actif par défaut ("assistant", "medical", etc.)
active_profile: "assistant"

# Matériel & VRAM
hardware:
  vram_limit_gb: 16
  cache_limit: 0

# Audio & VAD
audio:
  sample_rate: 16000
  silence_duration_threshold: 0.85
  speech_threshold: 0.45

# Transcription STT
stt:
  provider: "stt_local"
  language: "fr"

# Modèle de Langage (LLM)
llm:
  provider: "llm_local"
  model_repo: "local/llm-model"
  temperature: 0.5
  enable_speculative: true

# Synthèse Vocale (TTS)
tts:
  provider: "tts_local"
  voice: "fr_default"
  language: "fr-fr"

# Mémoire Épisodique & RAG
memory:
  enabled: true
  similarity_threshold: 0.65
  max_context_tokens: 900

# Catalogue des profils d'assistant
profiles:
  assistant:
    label: "Assistant Général"
    description: "Assistant personnel polyvalent avec mémoire épisodique, recherche web et synthèse orale concise."
    memory_db: "mirza/data/memory_assistant.db"
    allowed_tools:
      - "datetime_info"
      - "system_metrics"
      - "web_search"
      - "visit_webpage"
      - "recall_memory"
      - "save_memory"
    filler_phrases:
      - "Je vérifie les informations, un instant s'il vous plaît."
      - "Je consulte mes souvenirs et j'analyse votre demande."
    system_prompt: |
      Tu es Mirza, un assistant personnel et d'expertise d'élite fonctionnant en local sur Apple Silicon.
      ...

  medical:
    label: "Assistant Médical & Clinique"
    description: "Assistant clinique expert pour dossiers patients, bilans et requêtes médicales."
    memory_db: "mirza/data/memory.db"
    allowed_tools: null  # null = tous les outils (y compris clinical_records_stats et execute_clinical_sql)
    filler_phrases:
      - "Je vérifie les dossiers de la patientèle, un instant s'il vous plaît."
      - "Je consulte la base clinique et j'analyse les données."
    system_prompt: |
      Tu es Mirza, un assistant médical et clinique expert d'élite fonctionnant en local sur Apple Silicon.
      ...
    agent:
      system_prompt: |
        Tu es Mirza, un agent IA clinique et médical expert ultra-rapide fonctionnant en local sur Apple Silicon.
        ...
      instructions_prompt: |
        Tu es Mirza, un agent IA clinique et médical autonome haute performance.
        ...
      final_answer_prompt:
        pre_messages: |
          Tu es Mirza. Formule la réponse médicale finale au praticien sur la base des observations cliniques...
        post_messages: |
          Fournis la réponse clinique factuelle et précise à la demande :
          {{task}}

Hiérarchie et Centralisation des Prompts

Mirza suit un principe strict de source unique de vérité pour les prompts :

  1. Priorité absolue au fichier YAML (``config.yaml``) : Lorsqu’un profil définit system_prompt ou la section agent (avec system_prompt, instructions_prompt, final_answer_prompt), ce sont exactement ces valeurs qui sont chargées en mémoire et transmises au moteur de langage (LLM) et à l”AgentManager (smolagents). Aucun prompt codé en dur ne vient écraser les réglages du YAML.

  2. Gabarits par défaut centralisés (``mirza/core/prompts.py``) : Si une clé de prompt est omise dans le fichier YAML (ou en cas d’absence de fichier externe), Mirza effectue un repli automatique et propre sur les gabarits certifiés de mirza/core/prompts.py (re-exportés par mirza.engine.agent.prompts pour rétro-compatibilité).

  3. Séparation nette des contextes Direct vs Agentique :

    • Mode Conversationnel Direct / RAG : Utilise le system_prompt du profil (consignes de concision orale, gestion de la mémoire épisodique et balisage documentaire <result>).

    • Mode Agent (smolagents / CodeAgent) : Utilise la sous-section agent du profil :

      • system_prompt : Description des capacités de raisonnement Python et consignes d’utilisation des outils autorisés.

      • instructions_prompt : Contraintes de réactivité (2 étapes maximum, directitude, format oral + écrit).

      • final_answer_prompt : Gabarit guidant la formulation du verdict final (synthèse vocale courte en français + document complet structuré sous balise <result>).

  4. Bascule dynamique instantanée :

    Lors d’une bascule de profil (ex: de assistant à medical) :

    • Le prompt système du LLM est instantanément régénéré pour la conversation directe.

    • Les gabarits système, d’instructions et de réponse finale de l’agent sont mis à jour dans l”AgentManager.

    • Les restrictions d’outils (allowed_tools) sont appliquées immédiatement.

    • Les phrases d’attente vocale (filler_phrases) et la base mémoire SQLite-vec sont redirigées sans redémarrage.

Gestion Intelligente de la Charge (In-Memory Cache)

Pour éviter toute réouverture continue du fichier disque lors des requêtes vocales ou textuelles :

  • La classe AppConfig.load(configPath, profile, reload) parse le fichier YAML lors de son premier appel.

  • L’instance résultante est conservée en mémoire dans un singleton _CACHED_APP_CONFIG.

  • Tous les accès ultérieurs (via getConfig() ou au sein de la boucle de streaming) accèdent directement à l’objet Python en mémoire en quelques nanosecondes, sans aucun accès disque.

  • Le paramètre reload=True permet de forcer le rechargement si nécessaire.

Utilisation en Ligne de Commande (CLI)

Lancement avec profil spécifique :

# Lancement du profil généraliste
python main.py --server --ssl --profile assistant

# Lancement du profil médical
python main.py --server --ssl --profile medical

# Utilisation d'un fichier de configuration personnalisé
python main.py --server --ssl --config /chemin/vers/mon_config.yaml --profile medical

Via le script d’automatisation start_mirza.sh :

./scripts/start_mirza.sh --profile assistant
./scripts/start_mirza.sh --profile medical --skip-opt

API REST & WebSocket de Bascule à Chaud

REST API

  1. Lister les profils d’assistant : GET /api/action/profiles

    Réponse JSON :

    {
      "profiles": [
        {"id": "assistant", "label": "Assistant Général"},
        {"id": "medical", "label": "Assistant Médical & Clinique"}
      ],
      "activeProfileId": "assistant"
    }
    
  2. Basculer de profil d’assistant : POST /api/action/profiles/switch

    Corps de la requête :

    {"profileId": "medical"}
    

WebSocket

  • Action : {"action": "listAssistantProfiles"}

  • Action de bascule : {"action": "switchAssistantProfile", "profileId": "medical"}

  • Événements diffusés : assistantProfiles, agentStatus, memoryStatus.

Sélection Visuelle depuis l’Application Cliente

Sur le frontend client, l’utilisateur bascule instantanément entre les profils via le menu déroulant de l’en-tête :

Menu déroulant de sélection des profils d'assistant

Menu contextuel PROFIL D’ASSISTANT sur mobile : sélection immédiate entre le profil généraliste (Assistant Général) et le profil métier (Assistant Médical & Clinique), avec mise à jour instantanée du thème visuel, de la mémoire épisodique et de l’outillage.

Rendu Typographique et Mathématique (KaTeX)

Les symboles typographiques courants (→, ←, ≤, ≥, ±, ·) employés dans les listes ou le texte ordinaire en français (ex: Pancréas → stimulation..., Obésité (IMC ≥ 30...)) sont préservés en typographie Unicode native sans être transformés en formules KaTeX, évitant ainsi l’italique mathématique, la suppression d’espaces et la déformation des caractères accentués. Seules les expressions mathématiques explicites contenant des opérateurs cœur (∇, ∂, ∑, variables grecques avec indices) ou balisées par $...$ / $$...$$ sont envoyées au moteur de rendu KaTeX.