NobodyWho : un moteur d'inférence Rust pour exécuter des LLM sur l'appareil, du Kotlin au Godot
NobodyWho is an inference engine that lets you run LLMs locally and efficiently on any device.
En bref
- De quoi s’agit-il ?
- NobodyWho encapsule llama.cpp derrière des liaisons Kotlin, Swift, Python, Flutter, React Native/Expo et Godot. Le projet vise l'inférence locale hors ligne avec tool calling typé, mais la licence EUPL-1.2 et la dépendance à llama.cpp structurent les décisions d'adoption.
- À qui s’adresse-t-il ?
- NobodyWho convient aux équipes qui livrent une application Kotlin, Swift, Python, Flutter, React Native ou Godot et veulent une inférence locale sans clé API, avec un tool calling généré depuis les signatures de fonctions. Il ne convient pas à ceux qui ont besoin d'un backend serveur partagé, d'un débit élevé ou d'une licence permissive de type MIT.
- Puis-je l’utiliser commercialement ?
- Oui, sous conditions. EUPL-1.2 est une licence à copyleft faible : vous pouvez l’intégrer à un logiciel commercial ou propriétaire, mais si vous distribuez des modifications de ses propres fichiers, vous devez les publier sous la même licence.
- Est-il encore maintenu ?
- Oui. Le dépôt a reçu de nouveaux commits au cours des dernières 24 heures.
- En quel langage est-il écrit ?
- Principalement Rust, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème visé : l'inférence locale sans écrire de liaison native
Faire tourner un LLM dans une application mobile ou un jeu implique normalement d'écrire soi-même la couche qui relie llama.cpp au langage de l'application. NobodyWho prend en charge cette couche et publie des paquets prêts à l'emploi pour Kotlin, Swift, Python, Flutter, React Native/Expo et Godot. Le README résume la promesse ainsi : "an inference engine that lets you run LLMs locally and efficiently". Le public visé est donc l'équipe produit qui veut embarquer un modèle GGUF dans son binaire, pas l'équipe qui exploite un cluster d'inférence. Le choix de Rust comme langage principal indique que le projet mise sur un cœur unique compilé, exposé ensuite à chaque écosystème via des liaisons. Cela explique la présence simultanée de Maven Central, SPM, npm, pub.dev, PyPI et de l'AssetLib Godot dans le README : un seul moteur, plusieurs canaux de distribution.
Sous le capot : llama.cpp, context shifting et grammaires de tool calling
Le README indique que le moteur est "powered by the wonderful llama.cpp". Toute la compatibilité avec les modèles découle de ce choix : le format supporté est le GGUF, et le README affirme la compatibilité avec "thousands of pre-trained LLMs". L'accélération passe par Vulkan ou Metal selon le système. Deux mécanismes méritent l'attention. D'abord le context shifting préemptif, décrit comme "conversation-aware" : il déplace le contexte pour conserver la mémoire de conversation sans limite de longueur de message. En pratique, cela signifie que le projet ne se contente pas de tronquer les vieux messages, il réorganise le contexte. Ensuite le tool calling : les grammaires structurées sont générées automatiquement à partir des signatures de fonctions, ce qui évite d'écrire un schéma JSON à la main. C'est un vrai gain de maintenance quand les outils changent souvent, mais cela lie le comportement au modèle choisi, puisque la qualité du respect de la grammaire dépend du modèle. Le README mentionne aussi l'entrée multimodale (image et audio), la synthèse vocale via Kokoro, Pocket TTS et Supertonic, et la transcription via Whisper.
Installation : des commandes différentes selon la plateforme
Chaque écosystème a son canal. En Kotlin, le README donne deux dépendances Gradle distinctes : implementation("ai.nobodywho:nobodywho-android:2.0.0") pour Android et implementation("ai.nobodywho:nobodywho:2.0.0") pour la JVM de bureau. En Swift, l'ajout se fait via Swift Package Manager avec l'URL https://github.com/nobodywho-ooo/nobodywho-swift.git. En Python, pip install nobodywho. En Flutter, flutter pub add nobodywho, avec un appel obligatoire à nobodywho.NobodyWho.init() avant toute création de chat. En React Native, npm install react-native-nobodywho, et pour Expo npx expo install react-native-nobodywho. Pour Godot, le README privilégie l'AssetLib interne de Godot 4.5+ avec une recherche sur "NobodyWho", ou l'import manuel d'un zip depuis les releases GitHub, en veillant à cocher l'option ignore asset root dans la boîte de dialogue d'import. Le chargement du modèle accepte un chemin Hugging Face, par exemple hf://NobodyWho/Qwen_Qwen3-0.6B-GGUF/Qwen_Qwen3-0.6B-Q4_K_M.gguf en Kotlin, Swift et React Native, alors que Flutter et Python utilisent le préfixe huggingface:. Cette différence de schéma entre liaisons est un détail à ne pas recopier d'un exemple à l'autre.
Ce que le README ne dit pas sur le coût de possession
Le projet est sous EUPL-1.2, une licence copyleft de l'Union européenne. Le README ne contient aucune section sur les obligations de redistribution, et je ne peux pas affirmer ici ce que la licence impose à votre produit : c'est un point à faire vérifier par votre juriste avant toute distribution, notamment si vous liez la bibliothèque dans une application propriétaire. Sur la maintenance, les releases récentes montrent des versions majeures distinctes par liaison : nobodywho-swift-v3.0.0, nobodywho-react-native-v3.0.0 et nobodywho-python-v2.0.0, toutes publiées en août 2026. Le fait que Python soit en 2.x quand Swift et React Native sont en 3.x indique que les liaisons ne progressent pas au même rythme. Concrètement, une équipe multi-plateformes doit prévoir de suivre plusieurs calendriers de version. Le README ne documente pas de politique de support à long terme ni de compatibilité ascendante entre versions majeures, et le matériel fourni ne permet pas de trancher.
Les cas où NobodyWho n'est pas le bon outil
Le projet cible l'inférence sur l'appareil. Si votre besoin est un service central qui sert plusieurs clients, avec mise en cache des prompts et montée en charge horizontale, l'architecture de NobodyWho ne répond pas à la question : chaque instance charge son propre modèle et consomme la mémoire de l'appareil. Deuxième limite : la taille du modèle. Le README ne donne aucun chiffre de mémoire ni de latence, mais le fait que l'exemple d'installation utilise Qwen3-0.6B en quantification Q4_K_M suggère que les modèles de cette taille sont le terrain naturel du projet. Un modèle de plusieurs dizaines de milliards de paramètres n'entre pas dans ce cadre. Troisième limite : le contexte matériel. L'accélération repose sur Vulkan ou Metal ; une plateforme sans l'un des deux retombe sur un chemin non précisé par le README. Enfin, la dépendance à llama.cpp signifie que les formats non GGUF sont hors périmètre, et que les fonctionnalités du moteur suivent l'amont.
Face à quoi : llama.cpp brut, ou une API hébergée
La comparaison utile se fait sur deux axes. D'un côté, utiliser llama.cpp directement : c'est le même moteur, mais vous écrivez vous-même les liaisons pour Kotlin, Swift, Flutter, React Native ou Godot, ainsi que la gestion du context shifting et la génération de grammaires pour le tool calling. NobodyWho vend précisément cette couche, et le README insiste sur le fait que les grammaires sont générées depuis les signatures de fonctions, ce qui est un travail que llama.cpp seul ne fournit pas. De l'autre côté, une API hébergée : elle déplace le coût vers un appel réseau et une facturation à l'usage, en échange de modèles plus gros et d'aucune contrainte mémoire sur l'appareil. Le README revendique l'absence de clé API et de frais cachés, ce qui est l'argument central en faveur du local. Le compromis est clair : NobodyWho échange la puissance des gros modèles contre la confidentialité et le fonctionnement hors ligne.
Qui adopte, qui passe, et quoi vérifier d'abord
Adoptez NobodyWho si vous livrez une application Kotlin, Swift, Python, Flutter, React Native/Expo ou Godot, que vous voulez un modèle GGUF embarqué, et que le tool calling typé ou la synthèse vocale locale font partie de votre fonctionnalité. Passez votre chemin si vous avez besoin d'un service partagé, d'un débit élevé, de modèles de grande taille, ou d'une licence permissive de type MIT. Trois vérifications avant d'écrire du code de production. Premièrement, la compatibilité de EUPL-1.2 avec votre mode de distribution. Deuxièmement, le comportement réel du context shifting sur vos conversations les plus longues, car le README en fait un argument central sans fournir de mesure. Troisièmement, la version de la liaison que vous ciblez : Python est en 2.0.0 quand Swift et React Native sont en 3.0.0, et cette divergence de numérotation est le premier signal à interpréter avant de figer une dépendance.
Conclusion éditoriale
NobodyWho convient aux équipes qui livrent une application Kotlin, Swift, Python, Flutter, React Native ou Godot et veulent une inférence locale sans clé API, avec un tool calling généré depuis les signatures de fonctions. Il ne convient pas à ceux qui ont besoin d'un backend serveur partagé, d'un débit élevé ou d'une licence permissive de type MIT. Avant de l'intégrer, vérifiez la compatibilité de la version EUPL-1.2 avec votre mode de distribution, et testez le comportement du context shifting sur vos conversations les plus longues.
Notes de la communauté