265 lines
9.3 KiB
Markdown
265 lines
9.3 KiB
Markdown
# Quantum Tutor — Design Spec
|
||
|
||
**Date:** 2026-04-29
|
||
**Status:** Approved
|
||
**Scope:** Extension pédagogique de quantum-bridge-mcp — 4 nouveaux outils MCP + curriculum JSON + suivi de progression
|
||
|
||
---
|
||
|
||
## 1. Contexte et objectif
|
||
|
||
quantum-bridge-mcp est un serveur MCP Rust qui expose 3 outils de simulation de circuits OpenQASM 3.0. Ce module ajoute une **couche pédagogique** au-dessus des outils existants : un tuteur quantique qui guide l'utilisateur à travers un curriculum structuré, vérifie ses exercices, et suit sa progression.
|
||
|
||
**Utilisateur cible :** débutant en informatique quantique avec des notions vagues de superposition/intrication. Objectif : aller des bases jusqu'aux algorithmes (Grover).
|
||
|
||
**Style d'apprentissage :** explication courte → exercice guidé → exploration libre. Maths introduites progressivement quand elles deviennent nécessaires.
|
||
|
||
---
|
||
|
||
## 2. Nouveaux outils MCP
|
||
|
||
### 2.1 `get_lesson`
|
||
|
||
```
|
||
get_lesson(module_id: u32, lesson_id?: u32) → JSON
|
||
```
|
||
|
||
Retourne le contenu d'une leçon : explication du concept, circuit(s) d'illustration à exécuter, et exercice(s) à résoudre.
|
||
|
||
**Paramètres :**
|
||
- `module_id` : 1–7 (voir curriculum §4)
|
||
- `lesson_id` : optionnel ; si absent, retourne la première leçon non complétée du module
|
||
|
||
**Réponse :**
|
||
```json
|
||
{
|
||
"module_id": 2,
|
||
"lesson_id": 1,
|
||
"title": "La porte H et la superposition",
|
||
"concept": "...",
|
||
"example_circuit": "OPENQASM 3.0;\n...",
|
||
"what_to_observe": "Lance run_circuit avec 1000 shots. Tu devrais voir ~500 '0' et ~500 '1'.",
|
||
"exercise": {
|
||
"id": "2-1-a",
|
||
"prompt": "Écris un circuit qui met un qubit en superposition parfaite et le mesure.",
|
||
"hint": "Une seule porte suffit avant la mesure."
|
||
}
|
||
}
|
||
```
|
||
|
||
**Comportement :** si `lesson_id` est absent et que `get_progress()` indique que le module est déjà complété, retourne un résumé du module avec suggestion d'avancer.
|
||
|
||
---
|
||
|
||
### 2.2 `check_exercise`
|
||
|
||
```
|
||
check_exercise(exercise_id: str, circuit: str) → JSON
|
||
```
|
||
|
||
Vérifie si le circuit soumis résout l'exercice identifié par `exercise_id`. Exécute le circuit en interne (1024 shots), compare les résultats aux critères définis dans `curriculum.json`, met à jour la progression.
|
||
|
||
**Paramètres :**
|
||
- `exercise_id` : identifiant de l'exercice (ex: `"2-1-a"`)
|
||
- `circuit` : source OpenQASM 3.0
|
||
|
||
**Réponse (succès) :**
|
||
```json
|
||
{
|
||
"passed": true,
|
||
"exercise_id": "2-1-a",
|
||
"feedback": "Parfait ! Ta porte H crée bien une superposition équilibrée. Tu observes ~50% de '0' et ~50% de '1'.",
|
||
"counts": {"0": 512, "1": 512},
|
||
"progress_updated": true
|
||
}
|
||
```
|
||
|
||
**Réponse (échec) :**
|
||
```json
|
||
{
|
||
"passed": false,
|
||
"exercise_id": "2-1-a",
|
||
"feedback": "Ton circuit produit toujours '0'. Le qubit n'est pas en superposition. Essaie d'ajouter une porte avant la mesure.",
|
||
"counts": {"0": 1024},
|
||
"hint": "La porte H transforme |0⟩ en (|0⟩ + |1⟩)/√2."
|
||
}
|
||
```
|
||
|
||
**Critères de vérification (définis par exercice dans curriculum.json) :**
|
||
- `required_outcomes` : liste de bitstrings qui doivent apparaître (avec proportion min/max optionnelle)
|
||
- `forbidden_outcomes` : bitstrings qui ne doivent pas apparaître
|
||
- `statevector_check` : optionnel — amplitudes attendues avec tolérance ε=1e-6
|
||
|
||
**Erreurs :** si le circuit est invalide, retourne l'erreur de validation avec position (réutilise `CircuitValidator`).
|
||
|
||
---
|
||
|
||
### 2.3 `explain_result`
|
||
|
||
```
|
||
explain_result(circuit: str, counts: object, statevector?: array) → JSON
|
||
```
|
||
|
||
Génère une explication pédagogique de ce qui s'est passé dans le circuit : quelles portes ont fait quoi, pourquoi on observe cette distribution, ce que ça signifie quantiquement.
|
||
|
||
**Paramètres :**
|
||
- `circuit` : source OpenQASM 3.0 (le circuit qui vient d'être exécuté)
|
||
- `counts` : résultat de `run_circuit` (bitstring → count)
|
||
- `statevector` : optionnel — amplitudes complexes de `run_circuit` avec `return_statevector: true`
|
||
|
||
**Réponse :**
|
||
```json
|
||
{
|
||
"gate_breakdown": [
|
||
{"gate": "h q[0]", "qubit": 0, "description": "Hadamard — crée une superposition égale", "effect_on_zero": "Transforme |0⟩ en (|0⟩+|1⟩)/√2"},
|
||
{"gate": "cx q[0], q[1]", "control": 0, "target": 1, "description": "CNOT — flip la cible si le contrôle est |1⟩"}
|
||
],
|
||
"num_qubits": 2,
|
||
"key_concept": "intrication",
|
||
"dominant_outcomes": ["00", "11"],
|
||
"missing_outcomes": ["01", "10"],
|
||
"statevector_summary": {"non_zero_amplitudes": [0, 3], "zero_amplitudes": [1, 2]}
|
||
}
|
||
```
|
||
|
||
**Implémentation :** le serveur Rust analyse le circuit via `CircuitValidator` et retourne des **données structurées** (liste de gates avec descriptions depuis `curriculum.json`, statistiques des counts, concept clé). C'est Claude (le client MCP) qui synthétise l'explication en langage naturel à partir de ces données — cette séparation exploite les capacités respectives du simulateur (analyse structurelle) et du LLM (narration pédagogique).
|
||
|
||
---
|
||
|
||
### 2.4 `get_progress`
|
||
|
||
```
|
||
get_progress() → JSON
|
||
```
|
||
|
||
Retourne l'état de progression de l'utilisateur dans le curriculum.
|
||
|
||
**Réponse :**
|
||
```json
|
||
{
|
||
"current_module": 2,
|
||
"current_lesson": 1,
|
||
"modules": [
|
||
{"id": 1, "title": "Le qubit", "status": "completed", "exercises_solved": 3},
|
||
{"id": 2, "title": "Superposition", "status": "in_progress", "exercises_solved": 0},
|
||
{"id": 3, "title": "Interférence", "status": "locked", "exercises_solved": 0}
|
||
],
|
||
"total_exercises_solved": 3,
|
||
"total_exercises": 18,
|
||
"percent_complete": 17
|
||
}
|
||
```
|
||
|
||
**Persistence :** fichier JSON à `~/.config/quantum-bridge-mcp/progress.json`. Créé automatiquement au premier appel avec progression à zéro.
|
||
|
||
---
|
||
|
||
## 3. Architecture interne
|
||
|
||
### Nouveaux fichiers
|
||
|
||
```
|
||
curriculum/
|
||
curriculum.json — leçons, exercices, critères de vérification, descriptions de gates
|
||
src/
|
||
tutor.rs — CurriculumLoader + ExerciseChecker (logique de vérification)
|
||
progress.rs — ProgressStore (lecture/écriture progress.json)
|
||
tools/
|
||
tutor_tools.rs — handlers MCP des 4 nouveaux outils
|
||
```
|
||
|
||
### Réutilisation des composants existants
|
||
|
||
| Composant existant | Réutilisé par |
|
||
|---|---|
|
||
| `CircuitValidator` (`src/validator.rs`) | `check_exercise` (validation avant exécution), `explain_result` (analyse des gates) |
|
||
| `LocalSimulator` via `CanExecute` | `check_exercise` (exécution interne des circuits) |
|
||
| `CircuitSource`, `ShotCount`, `SimulationResult` (`src/types.rs`) | `check_exercise`, `explain_result` |
|
||
| Trait `Backend` | `check_exercise` — dépend de `&dyn Backend`, compatible IBM V1.5 |
|
||
|
||
### Contraintes d'architecture
|
||
|
||
- Les outils tutor dépendent de `&dyn Backend`, jamais de `LocalSimulator` directement (même règle que les outils existants).
|
||
- `check_exercise` utilise `ShotCount(1024)` fixe pour la vérification (reproductibilité statistique).
|
||
- `ExerciseChecker` compare avec tolérance : un résultat passe si chaque outcome requis représente au moins `min_ratio - 2σ` des shots (σ calculé pour N=1024 shots, distribution binomiale).
|
||
|
||
---
|
||
|
||
## 4. Curriculum — structure des 7 modules
|
||
|
||
| Module | Titre | Concepts clés | Nb exercices |
|
||
|--------|-------|--------------|--------------|
|
||
| 1 | Le qubit | États \|0⟩/\|1⟩, gate X, mesure | 2 |
|
||
| 2 | Superposition | Gate H, état \|+⟩, distribution 50/50 | 3 |
|
||
| 3 | Interférence et phase | H·H=I, phase relative, gates Z/S/T/RZ | 3 |
|
||
| 4 | 2 qubits et intrication | Bell state, CNOT, mesure corrélée | 3 |
|
||
| 5 | Circuits multi-qubits | GHZ, Toffoli, statevecteur complet | 3 |
|
||
| 6 | Premiers algorithmes | Deutsch-Jozsa, Bernstein-Vazirani, téléportation | 2 |
|
||
| 7 | Algorithme de Grover | Oracle de phase, opérateur de diffusion | 2 |
|
||
|
||
**Total : 18 exercices** sur 7 modules.
|
||
|
||
Les modules 2–7 sont verrouillés jusqu'à complétion du module précédent. Exception : le module suivant se déverrouille dès qu'au moins 2/3 des exercices du module courant sont résolus.
|
||
|
||
---
|
||
|
||
## 5. Format curriculum.json (schéma)
|
||
|
||
```json
|
||
{
|
||
"version": "1.0",
|
||
"gate_descriptions": {
|
||
"h": {
|
||
"short": "Hadamard — crée une superposition égale",
|
||
"effect_on_zero": "Transforme |0⟩ en (|0⟩+|1⟩)/√2",
|
||
"effect_on_one": "Transforme |1⟩ en (|0⟩-|1⟩)/√2"
|
||
}
|
||
},
|
||
"modules": [
|
||
{
|
||
"id": 1,
|
||
"title": "Le qubit",
|
||
"lessons": [
|
||
{
|
||
"id": 1,
|
||
"title": "États |0⟩ et |1⟩",
|
||
"concept": "...",
|
||
"example_circuit": "OPENQASM 3.0;\n...",
|
||
"what_to_observe": "...",
|
||
"exercises": [
|
||
{
|
||
"id": "1-1-a",
|
||
"prompt": "...",
|
||
"hint": "...",
|
||
"criteria": {
|
||
"required_outcomes": [{"bitstring": "1", "min_ratio": 0.95}],
|
||
"forbidden_outcomes": ["0"]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Tests
|
||
|
||
- **Unitaires** : `ExerciseChecker` avec critères simples (gate X → bitstring "1" avec ratio 1.0)
|
||
- **Intégration** : `check_exercise` roundtrip via MCP JSON-RPC pour 3 exercices représentatifs (un par module difficile)
|
||
- **Golden files** : `tests/tutor/` — circuits d'exercices + résultats attendus (pass/fail)
|
||
- **Progress** : `ProgressStore` — création, mise à jour, lecture, reset
|
||
|
||
---
|
||
|
||
## 7. Hors scope (V1)
|
||
|
||
- Visualisation sphère de Bloch (V2)
|
||
- Dessin de circuits en ASCII/SVG (V2)
|
||
- Explications générées par LLM (V2)
|
||
- Support multi-utilisateurs (V2)
|
||
- Gamification / badges (V2)
|