Le MiniMax M3 en tant qu’agent de codage OpenClaw : cinq tâches comparées à celles du Kimi K3 et dsh, ainsi qu’un widget qu’il n’a pas réussi à créer.
- Catégorie
- IA et LLM locaux
- Publié
- 12 septembre 2026
- Mis à jour
- 12 septembre 2026
- Par
- Jacob Lloyd — rédigé avec l'aide de l'IA, une fois le projet terminé
- Temps de lecture
- 28 min de lecture
En clair : J’ai connecté le modèle M3 de MiniMax à OpenClaw, le framework sur lequel s’exécutent mes assistants IA, et je lui ai donné les mêmes cinq petites tâches de programmation que j’avais confiées précédemment ce matin-là au modèle Kimi K3 de Moonshot. Il les a toutes accomplies en environ la moitié du temps nécessaire à Kimi ; en outre, aux prix catalogue, son utilisation aurait coûté environ un quart du montant requis pour Kimi. Je verse à MiniMax un forfait mensuel fixe, donc ces chiffres en dollars ne servent qu’à des fins de comparaison. J’avais également l’intention de comparer la manière dont chaque modèle créait une version pixel-art du logo de ce site. Le widget que j’avais d’abord attribué à MiniMax s’est en réalité avéré être un programme que Kimi avait écrit lors de sa deuxième tentative : l’exécution par MiniMax a localisé les fichiers créés par Kimi, les a testés et a confirmé qu’ils étaient correctement construits.
Le modèle MiniMax M3 exécute désormais mon agent de traitement dans OpenClaw. Je lui ai confié les mêmes cinq petites tâches de programmation que j’avais données précédemment à Kimi K3 le même matin ; il les a toutes réussies en environ la moitié du temps nécessaire à Kimi, pour un coût d’environ un quart de celui de Kimi. J’avais également l’intention de comparer comment chacun des deux modèles créait une version en pixel-art du logo de ce site, à partir du même cahier des charges. Cette comparaison n’a malheureusement pas pu avoir lieu : le widget que je croyais être l’œuvre de MiniMax avait en réalité été écrit par Kimi ; lors de son exécution, MiniMax a trouvé les fichiers créés par Kimi et les a présentés comme étant son propre travail. Les détails sont exposés ci-dessous, car c’est précisément ce qui s’est passé qui constitue l’élément le plus intéressant de cet article.
Résumé
- Qu’est-ce que c’est ? MiniMax M3 pilote la boucle d’exécution de l’agent d’OpenClaw via le fournisseur
minimaxintégré. Ce fournisseur utilise l’Anthropic Messages API située àhttps://api.minimax.io/anthropic, et non un point de terminaison de type OpenAI. Il ne s’agit pas de Codex : le système Codex d’OpenClaw n’accepte que les fournisseurs dont le nom estopenai. - Configuration : la clé API provient de la variable d’environnement
MINIMAX_API_KEY. En plus de cela, les paramètres importants sont la définition du modèle utilisé (le contexte est limité à 262 144 tokens sur un total de 1 000 000) ainsi que la chaîne de modèles employée : M3, puis DeepSeek V4-Flash, enfin V4-Pro. - Benchmark : cinq tâches, chaque fois dans une session nouvelle. MiniMax M3 a réussi les 5 tâches en 159,2 secondes ; Kimi K3 en a fait autant en 309,9 secondes ; le système DeepSeek Harness (dsh) utilisant V4-Flash a obtenu le même résultat en 35,7 secondes. Les tests ont utilisé des fichiers différents à chaque fois, et MiniMax a nécessité plusieurs tentatives ; ces éléments sont décrits plus bas, donc les ratios indiqués doivent être considérés comme indicatifs.
- Coût : 0,125 $ pour les cinq tâches exécutées par MiniMax, selon les tarifs listés d’OpenClaw (0,60 $ pour l’entrée, 2,40 $ pour la sortie, 0,12 $ pour la lecture du cache par million de tokens). Étant abonné au forfait à prix fixe de MiniMax, il s’agit d’un équivalent tarifaire, non d’une facture réelle. Pour Kimi : 0,531 $ selon les tarifs de 3 $, 15 $ et 0,30 $. Pour dsh : 0,011 $.
- Widget : MiniMax n’a rien produit. Le widget de 323 lignes que j’avais identifié comme étant le premier essai de M3 est en réalité identique, octet par octet, à ce qu’a créé Kimi K3 lors de sa deuxième tentative, dans un dossier partagé. Lors de son exécution, MiniMax a lu ces fichiers, relancé les tests et a répondu : « Construit et vérifié ».
Qu’est-ce que le fournisseur Minimax d’OpenClaw en réalité ?
J’avais tort dans une version précédente ; voici donc les informations tirées du code installé et de ma propre configuration.
- Protocole et point de terminaison. Le plugin Minimax intégré configure ses fournisseurs avec
api: "anthropic-messages"et l’URL de basehttps://api.minimax.io/anthropic(une variableMINIMAX_API_HOSTpermet de modifier l’hôte). MiniMax propose également une API compatible OpenAI à l’adressehttps://api.minimax.io/v1, mais le plugin d’OpenClaw ne l’utilise pas. - Deux entrées de fournisseurs, pas trois.
minimaxest le principal fournisseur du plugin ; mon fichieropenclaw.jsonne modifie que la liste des modèles, tandis que le type d’API, l’URL de base et les informations d’authentification proviennent toutes du plugin.minimax-portalest le second identifiant de fournisseur (sa variante OAuth) ; je le déclare manuellement avec le même point de terminaison et un contexte de 1 000 000 de tokens pour les tâches longues.minimax-cnne constitue pas une troisième entrée, mais simplement un alias d’authentification pourminimaxdestiné à la région Chine de MiniMax, dont le point de terminaison esthttps://api.minimaxi.com/anthropic. - La clé d’accès. Il s’agit d’une variable d’environnement. Le plugin lit
MINIMAX_API_KEY(ainsi que quelques variantes liées aux forfaits de tokens) ; mon entréeminimax-portalfait référence à cette clé sous la forme littérale"${MINIMAX_API_KEY}". Aucune information liée à MiniMax n’est stockée dans le magasin de secrets d’OpenClaw. - Paramètres des modèles. Le catalogue du plugin attribue au modèle M3 une capacité de 1 000 000 de tokens et un seul paramètre
compat, à savoircodeMode: "preferred"(il s’agit du Mode Code d’OpenClaw, sans rapport avec Codex). Il n’existe aucun réglage de température pour ce modèle. - Prix. Le plugin fixe le prix de M3 à 0,60 $ pour l’entrée, 2,40 $ pour la sortie et 0,12 $ par million de tokens en lecture depuis le cache ; c’est ce tableau qui remplit
usage.cost.totaldans le JSON. Je n’ai pas encore comparé ces tarifs avec la page de prix officielle de MiniMax.
Ce n’est pas Codex
Il s’agit du cycle d’exécution propre à OpenClaw, et non du serveur d’applications Codex d’OpenAI. OpenClaw dispose d’un plugin de raccordement à Codex, mais sa vérification de route (configuredModelRouteNeedsCodex) renvoie false pour tout fournisseur dont l’identifiant ne se normalise pas en openai ; par conséquent, une route minimax/MiniMax-M3 ne remplit jamais les conditions requises. Le JSON généré à chaque exécution indique quel cycle a été utilisé : agentHarnessId: "openclaw". De plus, le plugin Codex n’est pas installé sur ma machine.
Pour faire passer M3 via Codex, il faudrait mettre en place un pont local tel que codex-router, ainsi que permettre au plugin Codex d’utiliser mon propre répertoire ~/.codex, que tous les agents de la machine partageraient alors. Je ne l’ai pas fait. Tout ce qui est décrit dans cet article concerne donc le cycle d’exécution natif.
Configuration
Les versions que j’ai utilisées :
$ node -v
v24.18.0
$ openclaw --version
OpenClaw 2026.9.2 (3928bad)
$ dsh --version
0.1.1-rc.2
$ openclaw plugins list --json | jq '[.plugins[] | select(.enabled)] | length'
35
Étape 1 : la clé
Le plugin Minimax est fourni avec OpenClaw 2026.9.2 et est activé dans mon installation. Il lit la clé depuis MINIMAX_API_KEY ; donc, définissez cette variable dans l’environnement utilisé par votre passerelle (un fichier EnvironmentFile de systemd, un fichier plist de launchd, ou votre shell), puis redémarrez la passerelle en utilisant la commande openclaw gateway restart. Ne saisissez jamais la clé directement dans openclaw.json. Si une ligne concernant un fournisseur doit faire référence à cette clé, écrivez "${MINIMAX_API_KEY}" comme référence, et non la valeur réelle.
Étape 2 : orienter un agent de travail vers M3
Il y a deux éléments dans openclaw.json. Tout d’abord, la chaîne de modèles de l’agent :
"agents": { "entries": { "worker": { "model": {
"primary": "minimax/MiniMax-M3",
"fallbacks": ["deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro"]
} } } }
Ensuite, optionnellement, une limite de contexte pour la ligne du modèle. Il s’agit d’une entrée provenant de ma propre configuration. Elle ne contient aucun api, baseUrl ou apiKey, car ces éléments proviennent du plugin :
"models": { "providers": { "minimax": { "models": [ {
"id": "MiniMax-M3", "name": "MiniMax M3",
"reasoning": true, "input": ["text", "image"],
"contextWindow": 1000000, "contextTokens": 262144, "maxTokens": 128000,
"compat": { "codeMode": "preferred" }
} ] } } }
Je répète entièrement l’entrée de modèle du plugin au lieu d’ajouter simplement la clé manquante, car une modification partielle sur cette configuration a autrefois fait disparaître silencieusement reasoning: true, entraînant l’exécution de M3 sans fonction de raisonnement pendant plusieurs jours. Cette limite s’élève à 262 144 éléments sur les 1 000 000 disponibles dans le catalogue, ce qui permet de garder les sessions de travail longues sous contrôle et d’éviter toute croissance illimitée.
Étape 3 : test de fumée
Il s’agit de la tâche PONG du benchmark, avec les champs qui m’intéressent extraits :
$ openclaw agent --agent worker --model minimax/MiniMax-M3 \
--session-key agent:worker:bench-pong-1 \
-m "Reply with exactly: PONG." --json \
| jq '{harness: .result.meta.agentMeta.agentHarnessId,
provider: .result.meta.executionTrace.winnerProvider,
model: .result.meta.executionTrace.winnerModel,
contextTokens: .result.meta.agentMeta.contextTokens,
usage: (.result.meta.agentMeta.usage | {input, output, cacheRead, cost: .cost.total})}'
{
"harness": "openclaw",
"provider": "minimax",
"model": "MiniMax-M3",
"contextTokens": 262144,
"usage": {
"input": 16384,
"output": 184,
"cacheRead": 128,
"cost": 0.01028736
}
}
harness: "openclaw" correspond à la boucle de traitement native. winnerModel indique quel modèle a fourni la réponse principale, plutôt qu’un modèle de secours. contextTokens montre que la limite de tokens a été appliquée. Les 16 384 tokens d’entrée non mis en cache correspondent pour l’essentiel au prompt système et aux définitions d’outils envoyés lors du premier tour d’une nouvelle session ; c’est pourquoi même PONG n’est pas gratuit. Le coût correspond au prix de liste du plugin, et non à ce qu’un forfait tarifaire facture.
En comparaison : MiniMax M3, Kimi K3, dsh
Deux de ces modèles font fonctionner la boucle de traitement d’OpenClaw. Le troisième, DeepSeek Harness (dsh), est l’agent de programmation développé par DeepSeek, doté de sa propre boucle de traitement. Les articles précédents de cette série incluaient également une colonne consacrée à Reasonix. Je n’ai jamais effectué de tests de benchmark sur Reasonix en mode headless, et je l’ai retiré de mon environnement le 2026-09-09 ; il ne figure donc pas ici.
| MiniMax M3 dans OpenClaw | Kimi K3 dans OpenClaw | dsh | |
|---|---|---|---|
| Éditeur | MiniMax | Moonshot AI | DeepSeek, MIT |
| Mode de connexion | Plugin minimax intégré ; API Messages d’Anthropic sur api.minimax.io/anthropic | Fournisseur moonshot ; API de complétion de chat d’OpenAI sur api.moonshot.ai/v1 | CLI et interface web propres à dsh |
| Appel depuis un script | openclaw agent --agent X --model minimax/MiniMax-M3 -m "…" --json | openclaw agent --agent X --model moonshot/kimi-k3 -m "…" --json | dsh --profile headless "…" |
| Changement de modèle | Paramètre model dans le fichier openclaw.json | Même procédure | ~/.dsh/settings.yaml |
| Benchmark à cinq tâches | 5/5, 159,2 s, 0,125 $ selon le prix listé | 5/5, 309,9 s, 0,531 $ | 5/5, 35,7 s, 0,011 $ (cache déjà chauffé) |
| Exemple : création d’un widget pixel-art | Aucun widget généré (voir ci-dessous) | Trois tentatives : pas de code widget ; un widget complet placé dans le mauvais dossier, interrompu après 15 min ; un widget de 397 lignes obtenu grâce à un prompt plus strict | Deux tentatives ; la seconde a duré 25 min et coûté environ 49 cents |
| Version | OpenClaw 2026.9.2 | OpenClaw 2026.9.2 | 0.1.1-rc.2, version de prévisualisation pour développeurs |
Le benchmark : cinq tâches
Les cinq tâches proviennent de l’article dsh : répondre « PONG » ; écrire et exécuter FizzBuzz ; corriger deux bugs afin que les tests unitaires passent, sans toucher aux tests eux-mêmes ; résumer un code composé de six modules en moins de 150 mots ; renommer une fonction dans plusieurs fichiers et tests, puis prouver que ces tests passent. Les trois modèles ont été exécutés le 11-09-2026. Pour Kimi, les exécutions se sont déroulées entre 07:46 et 07:54 JST, avec --thinking max. Les chiffres fournis par dsh correspondent à une nouvelle exécution effectuée dans le même contexte, avec un cache encore actif. Pour MiniMax, les exécutions ont eu lieu entre 09:11 et 09:14 JST, en utilisant le mode de réflexion adaptatif par défaut d’OpenClaw.
Ce qui différait toutefois :
- Des fichiers de test différents. Chaque exécution créait ses propres dossiers temporaires. La tâche de correction de bugs portait sur des bugs différents (Kimi :
addetis_evendans un même module ; MiniMax :addetsubtract). La tâche de renommage concernait également des fonctions différentes (Kimi :calculate_totaldevientcompute_totaldans trois modules et un fichier de test ; MiniMax :area_of_rectdevientrect_areadans trois modules et un fichier de test). Les formes des structures sont identiques, mais les fichiers ne le sont pas. - Des tentatives de réexécution. Lors de sa première passe, MiniMax a utilisé une même session persistante pour les cinq tâches ; cela a conduit à des erreurs instructives (voir les pièges à éviter). J’ai donc relancé toutes les tâches avec de nouvelles clés de session. Pour FizzBuzz, il a fallu deux tentatives supplémentaires, car le worker écrivait sans cesse
fizz.pydans son propre espace de travail au lieu du dossier temporaire. Le tableau ci-dessous indique les résultats de la quatrième tentative pour FizzBuzz. Kimi a également dû relancer ses tâches FizzBuzz et correction de bugs : la première tentative FizzBuzz s’est terminée sur un message de limitation de taux, et la première tentative de correction de bugs a révélé que le fichier avait déjà été modifié lors d’une exécution antérieure.
| Tâche | MiniMax M3 | Kimi K3 | dsh V4-Flash (cache encore actif) |
|---|---|---|---|
| Répondre « PONG » | ✅ 7,2 s · 1 tour | ✅ 6,1 s · 1 tour | ✅ 1,7 s |
| Écrire + exécuter FizzBuzz | ✅ 12,1 s · 3 tours, 2 appels d’outil | ✅ 22,8 s · 3 tours, 2 appels d’outil | ✅ 5,3 s |
| Corriger 2 bugs, tests inchangés | ✅ 41,0 s · 8 tours, 8 appels d’outil | ✅ 86,6 s · 7 tours, 6 appels d’outil | ✅ 11,3 s |
| Résumer 6 modules (<150 mots) | ✅ 9,1 s · 3 tours, 3 appels d’outil (84 mots) | ✅ 65,5 s · 5 tours, 10 appels d’outil | ✅ 5,1 s |
| Renommer dans plusieurs fichiers + tests | ✅ 89,9 s · 14 tours, 22 appels d’outil | ✅ 128,9 s · 10 tours, 9 appels d’outil | ✅ 12,3 s |
| Temps total réel | 159,2 s | 309,9 s | 35,7 s |
| Tokens : entrée non mise en cache / lecture du cache / sortie | 87,4k / 456,7k / 7,6k | 91,5k / 355,3k / 10,0k (dont 4,1k liés au raisonnement) | 6,1k / 147,3k / 4,7k (dont 2,0k liés au raisonnement) |
| Lecture du cache par token d’entrée non mis en cache | 5,2 | 3,9 | 24 |
| Coût | 0,125 $ à des tarifs de 0,60 $ / 2,40 $ / 0,12 $ par million de tokens (prix catalogue ; je bénéficie d’un forfait) | 0,531 $ à des tarifs de 3 $ / 15 $ / 0,30 $ par million de tokens | 0,011 $ à des tarifs de 0,44 $ / 1,32 $ / 0,014 $ par million de tokens |
Les tarifs indiqués correspondent au coût par million de tokens, dans l’ordre suivant : entrée non mise en cache / sortie / lecture du cache. Chaque coût total est la somme des valeurs usage.cost.total pour chaque tâche ; le calcul basé sur les quantités de tokens et les tarifs indiqués donne le même résultat.
Ce que le tableau montre :
- Toutes les tâches ont été réussies. J’ai vérifié chaque résultat sur disque : sortie FizzBuzz correcte, tests pytest validés, nombre de mots du résumé conforme aux exigences, aucun nom obsolète après le renommage.
- MiniMax s’est avéré environ 2× plus rapide que Kimi et environ 4× moins cher selon les prix catalogue (159,2 s contre 309,9 s ; 0,125 $ contre 0,531 $). Kimi fonctionnait avec un niveau de réflexion maximal, ce qui explique en partie cette différence.
- dsh sur V4-Flash a été environ 4,5× plus rapide que MiniMax et environ 11× moins cher pour des tâches similaires.
- Le cache joue un rôle crucial. MiniMax a lu 5,2 tokens en provenance du cache pour chaque token d’entrée non mis en cache. Selon les prix catalogue, une lecture du cache coûte 80 % de moins qu’une entrée non mise en cache. Si ces tokens avaient été facturés comme entrées non mises en cache, le coût aurait atteint environ 0,34 $ au lieu de 0,125 $.
- Les tentatives de réexécution ne sont pas prises en compte dans les totaux. Au total, les douze exécutions effectuées par MiniMax, y compris celles abandonnées, ont coûté 0,28 $ selon les prix catalogue et nécessité 321 secondes.
Le test du widget, et une correction
Le « test amusant » de l’article sur dsh était un widget en pixel art représentant le logo de ce site, créé à partir d’un brief écrit. Je voulais obtenir le même brief de la part de Kimi et MiniMax. Voici le brief tel que chaque modèle l’a reçu :
Brief : widget interactif en pixel-art du logo LaserLloyd
Créez une version en pixel-art du logo LaserLloyd autonome et facile à intégrer (voir
reference-logo.png) : un anneau bleu épais, de couleur #1f3f8f sur fond blanc, contenant deux lettres “L” majuscules italiques/obliques entrelacées — le pied de la “L” en haut à gauche se trouve juste sous la tige de la “L” en bas à droite, comme si les lettres étaient empilées en diagonale.Livrables (tous dans ce dossier)
ll-pixel-logo.js— UN seul fichier JavaScript vanilla, sans dépendances, sans étape de compilation, sans requêtes réseau. N’importe quelle page peut l’intégrer via :<div class="ll-pixel-logo" data-size="320"></div>+<script src="ll-pixel-logo.js"></script>. Le script détecte tous les éléments.ll-pixel-logoet y insère un<canvas>. Le canvas s’adapte à la largeur du conteneur (forme carrée) et reste net sur les écrans HiDPI (devicePixelRatio). Exposezwindow.LLPixelLogo.mount(el).index.html— page de démonstration affichant le widget à trois tailles, accompagnée d’une courte description des interactions.README.md— explications sur l’intégration, les interactions possibles et les attributs “data-” utilisables.L’art visuel
- Grille de pixels de 40×40 cellules. Ne dessinez pas manuellement le bitmap (pas de chaînes de caractères ‘#’/‘.’ — c’est lent et source d’erreurs). Procédez plutôt à une génération procédurale à partir de la géométrie : implémentez une fonction
isLit(col,row)qui renvoie true pour (a) les points appartenant à l’anneau : distance au centre comprise entre 0,82R et R ; et (b) les deux “L” obliques, chacune formée de deux parallélogrammes (une tige inclinée d’environ 20° et un pied), le pied de la “L” en haut à gauche se situant juste sous la tige de la “L” en bas à droite, conformément au modèle de référence. Réglez les quelques constantes nécessaires pour que le résultat ressemble au logo de référence à 200px. Précalculez les cellules éclairées une seule fois lors du montage.- Palette : bleu du logo #1f3f8f ; bleu clair #2ea8ff ; ambre #ffb64a ; cyan #00e6cf ; fond transparent.
Interactions (l’essence de l’exercice — faites-les agréables)
- Survol de la souris / mouvement tactile : les pixels proches du curseur réagissent physiquement — par exemple, ils sont repoussés comme dans un fluide ou sous l’effet d’une répulsion magnétique, puis reviennent à leur position initiale avec amortissement ; pendant ce déplacement, ils brillent en bleu clair/cyan. L’animation est fluide à 60 fps grâce à requestAnimationFrame, sans à-coups.
- Clic / toucher : un effet cool et satisfaisant. Choisissez UN seul effet marquant et mettez-le en œuvre correctement, par exemple : le logo se fragmente en pixels qui s’éloignent sous l’effet de la gravité, puis se reconstituent en logo (en ~1,5–2 secondes) ; ou bien un “laser” balaye le logo en le redessinant pixel par pixel avec des étincelles lumineuses. Les clics répétés doivent rester agréables (pas d’interruption brutale de l’animation).
- État au repos : une vie ambiante subtile (léger scintillement ou clignotement occasionnel d’un pixel) pour éviter que le widget paraisse inactif, sans être distrayant.
- Tenez compte de
prefers-reduced-motion: reduce: affichez alors uniquement le logo statique, avec seulement un léger effet de brillance au survol.- Le widget fonctionne aussi bien avec la souris qu’avec les écrans tactiles. Aucune capture du défilement n’est autorisée.
Critères de qualité
- Code propre, commenté ; pas de variables globales sauf
LLPixelLogo. Indentation sur 2 espaces. Moins de 400 lignes au total.- Fonctionne en mode
file://sans aucune erreur dans la console. Testez-le vous-même : écrivez un petit script Node ou ouvrez-le via n’importe quel outil pour vérifier la syntaxe et tester le module (jsdom n’est pas disponible — utiliseznode --checkainsi qu’un test unitaire sans DOM, par exemple en comptant les cellules éclairées et en vérifiant la présence de l’anneau et des deux “L” dans les bons quadrants).- À la fin, produisez un bref rapport : ce que vous avez construit, comment l’intégrer, ainsi que les vérifications effectuées.
Voici ce qui s’est passé, dans l’ordre, d’après les journaux de session :
- Kimi, tentative 1 (le même brief que ci-dessus) : 8,8 minutes de réflexion, aucun code de widget produit ; l’opération s’est arrêtée. Coût : environ 0,31 $.
- Kimi, tentative 2 (même brief) : il a écrit un fichier
ll-pixel-logo.jscomplet de 323 lignes, une page de démonstration, un fichier README ainsi que deux fichiers de test. Il a ensuite exécuté les tests et les a modifiés jusqu’à ce qu’ils soient tous validés. Il a enregistré tout cela, ainsi qu’un bref rapport d’exécution, dans l’espace de travail propre à l’agent, et non dans le dossier que je surveillais. La session s’est arrêtée après 15 minutes sans réponse. J’ai donc cru que la tentative 2 n’avait rien produit. Coût : environ 0,72 $. - Kimi, tentative 3 (contraintes plus strictes : écrire les fichiers en une seule invocation de l’outil, sans planification ni exécution de
node --check) : 7,4 minutes, et un widget de 397 lignes placé dans le bon dossier. Coût : 0,47 $. C’est ce widget que montre l’article sur Kimi. - MiniMax (même brief que ci-dessus, une heure plus tard, avec le même agent) : 59,3 secondes, 25 tours de dialogue, 24 appels d’outils effectués ; coût selon le tarif affiché : 0,13 $. Il a trouvé les fichiers créés lors de la tentative 2 de Kimi dans l’espace de travail partagé, en a lu les cinq ainsi que le rapport d’exécution généré par Kimi. Il a ensuite exécuté les tests de Kimi et a répondu : « Le jeu complet de widgets a été créé et vérifié ». Il n’a écrit aucune ligne de code pour le widget ; les seuls fichiers qu’il a produits étaient son propre rapport d’exécution et un fichier d’état.
J’ai pris cette réponse au pied de la lettre, et la première version de cet article décrivait le fichier comme étant « le premier widget créé par MiniMax, en moins d’une minute ». Le journal de session indique que ce fichier a été write à 08:11, heure du Japon, lors de la deuxième tentative de Kimi ; le fichier présent sur ce site est identique octet par octet. Donc, pour MiniMax dans le cadre de cette mission, je n’ai encore aucun résultat. La prochaine étape logique est de le relancer dans un dossier vide. Pour Kimi, l’histoire est plus heureuse que ce que j’avais d’abord rapporté : sa deuxième tentative a réussi ; il a simplement placé les fichiers au mauvais endroit.
Voici le widget « attempt-2 » de Kimi, en cours d’exécution sur cette page. C’est le fichier que j’avais initialement mal étiqueté :
prefers-reduced-motion.Ses premières ~30 lignes :
/* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
*
* Embed:
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
*
* One file, no dependencies, no build step, no network requests.
* The 40x40 bitmap is rasterised procedurally from geometry (a ring plus
* two interlocking italic Ls) — never a hand-drawn bitmap.
*
* Interactions:
* - pointer move : pixels are pushed away from the cursor, then spring
* back with damping; displaced pixels glow blue -> cyan
* - click / tap : the logo shatters outward with gravity + floor bounce,
* then reassembles itself (~1.8 s)
* - idle : occasional pixel twinkle (amber / cyan)
* Honours prefers-reduced-motion: static logo, hover glow only.
*
* Global exported: window.LLPixelLogo (also module.exports under node,
* so the bitmap can be unit-tested without a DOM).
*/
(function () {
'use strict';
/* ---------------- palette ---------------- */
var BLUE = [31, 63, 143]; // #1f3f8f logo blue
var HI = [46, 168, 255]; // #2ea8ff highlight blue
var AMBER = [255, 182, 74]; // #ffb64a
var CYAN = [0, 230, 207]; // #00e6cf
La troisième tentative de Kimi, celle décrite dans l’article sur Kimi, commence ainsi :
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
*
* Self-contained vanilla JS: no dependencies, no build step, no network.
* Embed on any page with:
*
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
*
* Every .ll-pixel-logo element gets a <canvas> mounted inside it at load.
* Programmatic API: window.LLPixelLogo.mount(el) -> instance.
*
* Art: 40x40 pixel grid, rasterised procedurally from geometry (ring + two
* interlocking italic Ls). Interactions: pointer repulsion with spring-back,
* click/tap shatter-and-reassemble, idle shimmer/twinkle, reduced-motion
* support. Mouse and touch. No scroll hijacking (all listeners passive).
*/
(function () {
'use strict';
// -- constants ------------------------------------------------------------
var VERSION = '1.0.0';
var GRID = 40; // logical grid: GRID x GRID cells
var BLUE = [31, 63, 143]; // #1f3f8f logo blue
var HILITE = [46, 168, 255]; // #2ea8ff highlight blue
var AMBER = [255, 182, 74]; // #ffb64a twinkle amber
var CYAN = [0, 230, 207]; // #00e6cf max-displacement glow
var CENTER = GRID / 2; // grid centre coordinate (20)
var R_OUT = 19; // ring outer radius (cells)
var R_IN = 0.82 * R_OUT; // ring inner radius
var SLANT = Math.tan(20 * Math.PI / 180); // ~20 deg italic shear
Et le widget dsh, celui qui se trouve en haut de l’article sur dsh :
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
* Vanilla JS, zero dependencies, no network requests, works from file://.
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
* Auto-mounts on .ll-pixel-logo elements; window.LLPixelLogo.mount(el) too.
* Knobs: data-size, data-speed, data-static.
*/
(function (global) {
'use strict';
// ---- 0. palette -----------------------------------------------------
var BLUE = [31, 63, 143]; // #1f3f8f — logo blue
var HI = [46, 168, 255]; // #2ea8ff — hover / repulsion glow
var AMBER = [255, 182, 74]; // #ffb64a — twinkle spark
var CYAN = [0, 230, 207]; // #00e6cf — deep glow
// ---- 1. art: procedural 40x40 raster (no hand-drawn bitmap) ----------
// A cell is lit when it belongs to the ring or to one of the two slanted
// interlocking Ls. Each L is two parallelograms (stem + foot), described by
// top-left (ax,ay), width w, height h, sheared by SLANT (bottom edge shifts
// left): TL=(ax,ay) TR=(ax+w,ay) BL=(ax-SLANT*h,ay+h). The upper-left L's
// foot runs right and tucks under the lower-right L's stem, like the ref.
var GRID = 40; // cells per side
var RING_R = 19.7; // outer ring radius (cells)
var RING_IN = 0.80 * RING_R; // inner ring radius (reference ~0.808R)
var SLANT = 0.453; // shear of stems/feet (~24deg)
var LETTERS = [
{ ax: 15.0, ay: 5.2, w: 4.2, h: 10.6 }, // upper-left L: stem
{ ax: 10.2, ay: 15.8, w: 15.0, h: 3.8 }, // upper-left L: foot
{ ax: 24.7, ay: 13.8, w: 4.2, h: 14.7 }, // lower-right L: stem
{ ax: 18.0, ay: 28.5, w: 15.0, h: 3.8 } // lower-right L: foot
];
Tous les trois rasterisent un anneau ainsi que deux L inclinés à partir de la géométrie, exposent window.LLPixelLogo.mount et respectent prefers-reduced-motion. J’ai compté les cellules éclairées en évaluant la propriété isLit pour chacune sur la grille 40×40 :
- Kimi, tentative 2 :
RING_R = 19.4, rayon intérieur égal à 0,82R,SHEAR = 0.42(soit environ 22,8°). Un assistantinLgère à la fois le pied et la tige déformée lors d’un seul test. 602 cellules allumées. - Kimi, tentative 3 :
R_OUT = 19, rayon intérieur égal à 0,82R,SLANT = tan 20°(soit environ 0,364). Un assistantmakeLrenvoie à la fois la tige et le pied. 510 cellules allumées. - dsh :
RING_R = 19.7, rayon intérieur égal à 0,80R,SLANT = 0.453(soit environ 24°). Il s’agit d’un tableauLETTERScontenant quatre éléments. 656 cellules allumées.
Aucun ne correspond exactement au logo de référence ; le cahier des charges exige simplement que le logo soit reconnaissable à 200 px, ce qui est le cas pour les trois. Je consacrerais dix minutes à vérifier les constantes avant de livrer l’un d’eux.
Ce que j’ai re-vérifié sur le widget de la tentative 2
Exécutez cela dans une copie temporaire du dossier contenant le widget ainsi que les deux fichiers de test écrits par Kimi :
$ wc -l ll-pixel-logo.js
323 ll-pixel-logo.js
$ node --check ll-pixel-logo.js && echo "syntax ok"
syntax ok
$ node test-bitmap.js | tail -1
ALL PASS
$ node test-smoke.js | tail -1
SMOKE PASS
test-bitmap.js effectue 18 vérifications : la présence d’un anneau aux points cardinaux et son absence aux coins ainsi qu’au centre, chaque tige et pied du « L » se trouvant dans son quadrant respectif, la zone d’interlock, la direction de l’inclinaison, et un nombre total de cellules allumées compris entre 540 et 670. test-smoke.js en effectue 10 : un montage avec un DOM simulé, un remontage idempotent, l’attribut role="img" ainsi qu’un aria-label, 300 frames avec un déplacement du pointeur et deux clics (le second au milieu d’une animation), un état fini des particules, le retour du logo à son emplacement initial, un buffer de 640 px avec un devicePixelRatio de 2, et enfin un unmount() sans erreur. Il s’agit des tests originaux de Kimi ; ils ne constituent pas une vérification indépendante : Kimi a modifié test-bitmap.js après son premier exécution, en déplaçant les zones de détection et en fixant la plage du nombre de cellules allumées à 540–670 une fois qu’il avait mesuré 602. Un résultat positif ici indique simplement que le widget et ses tests sont cohérents, mais ne signifie pas que ces tests établissent un critère objectif. Mon propre décompte donne 602 cellules allumées, réparties en 196 / 137 / 101 / 168 dans les quadrants supérieur gauche, supérieur droit, inférieur gauche et inférieur droit respectivement.
Pièges courants (ceux que j’ai réellement rencontrés)
- Les sessions persistantes gâchent les tests de performance. La commande
openclaw agent --agent worker -m "…"réutilise la session de l’agent sauf si vous spécifiez un nouveau--session-key. Lors de ma première exécution avec MiniMax, le test FizzBuzz a détecté que le fichier existait déjà et a refusé de l’écrire ; l’exécution de correction de bugs a indiqué que les tests étaient déjà réussis ; enfin, l’exécution de synthèse a pris en compte le dossier de correction de bugs issu de la run Kimi plutôt que celui propre à MiniMax. Un--session-keyunique par tâche a résolu le problème. - Les instructions prédéfinies du worker l’emportent sur le prompt concernant l’emplacement des fichiers. Les instructions de mon agent worker lui demandent d’enregistrer les sorties volumineuses dans son propre espace de travail ; cela a fait que deux fois, l’instruction “écrire fizz.py dans ce dossier” a été ignorée. Dans la troisième exécution FizzBuzz, le système affirmait avoir écrit dans le dossier temporaire ; en réalité, la date de modification du fichier indiquait qu’il se trouvait dans l’espace de travail. La quatrième exécution, avec un chemin absolu et une instruction explicite, s’est déroulée correctement.
- Un espace de travail partagé pollue la run suivante. Comme décrit plus haut. Une heure après l’exécution Kimi, les fichiers orphelins se trouvaient toujours dans l’espace de travail du worker ; MiniMax les a alors considérés comme siens. Il faut donc attribuer à chaque run un dossier vide, et vérifier ce que la run a réellement écrit (dates de modification, appels
writedans la session), plutôt que ce qu’elle prétend avoir écrit. - Une sortie d’erreur ne signifie pas que la tâche a échoué. Lors de l’exécution Kimi, le premier appel FizzBuzz s’est terminé avec le code 1, sans indiquer de modèle gagnant, et affichait “⚠️ API rate limit reached. Please try again later.” ; pourtant, le fichier
fizz.pyavait déjà été créé et fonctionnait correctement. Ce n’est que dans la réponse de la nouvelle tentative que l’on voyait “completed”. Il faut donc vérifier les fichiers produits, pas le statut de sortie. - Le catalogue indique 1 000 000 de tokens ; j’utilise 262 144. Ce chiffre correspond à mon paramètre personnel
contextTokens; le champagentMeta.contextTokensdans le JSON confirme quel paramètre est effectivement utilisé. Augmentez cette valeur si vous avez vraiment besoin d’une plus grande fenêtre de contexte ; la ligneminimax-portalmontre comment procéder pour les tâches nécessitant cela. - Les montants en dollars indiqués dans le forfait sont fictifs, mais utiles. OpenClaw remplit
usage.cost.totalavec ses tarifs standard, indépendamment de ce que vous payez réellement ; cela sert donc à comparer les modèles, mais n’a aucune valeur comptable.
Où cela me mène
Le modèle MiniMax M3 est celui utilisé en priorité par mon agent de traitement ; DeepSeek V4-Flash et V4-Pro servent de solutions de secours. Kimi K3 ne fait pas partie de cette chaîne de modèles ; je l’utilise ailleurs, pour mon agent d’analyse. Pour ces tâches, M3 a effectué le renommage en 89,9 secondes pour un coût de 0,058 $ au prix catalogue, tandis que Kimi a mis 128,9 secondes et coûté 0,180 $. Pour la correction de bugs, M3 a mis 41,0 secondes pour un coût de 0,025 $, contre 86,6 secondes et 0,114 $ pour Kimi. Le modèle dsh sur V4-Flash s’est avéré plus rapide et moins cher que les deux autres sur toutes les tâches.
Le cahier des charges concernant le widget est toujours en attente pour MiniMax. Lorsque je le relancerai, il générera un dossier vide ; je consulterai d’abord les appels write de la session avant de lire son rapport.
Voir aussi : Kimi K3 en tant qu’agent de programmation (l’aspect Kimi de cette comparaison), DeepSeek Harness (dsh) (les cinq tâches et le cahier des charges initial), Reasonix (évoqué dans d’autres articles ; retiré de mon système le 09/09/2026), ainsi que Le coût réel de mes agents IA.