Modèle / jeu de données
BoundaryML/baml avatar
BoundaryML/baml

BAML : un langage dédié aux appels LLM, avec un système de types qui survit à l'exécution

The programming language for agents

9 180 étoiles492 forksRustApache-2.0

En bref

De quoi s’agit-il ?
BAML se présente comme le langage de programmation des agents. Le README promet un typage statique de bout en bout, des erreurs typées et une intégration depuis Python, TypeScript, Go, C# ou Java. Voici ce que la documentation permet réellement de vérifier, et ce qu'elle laisse dans le flou.
À qui s’adresse-t-il ?
BAML convient aux équipes qui écrivent déjà beaucoup d'appels LLM et veulent sortir du parsing ad hoc de JSON, à condition d'accepter un langage supplémentaire dans la pile. Il ne convient pas aux projets qui ont besoin d'une version stable : les releases publiées sont des nightly de la branche canary.
Puis-je l’utiliser commercialement ?
Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de 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é : faire tenir une réponse de LLM dans un type

Un appel à un modèle de langage renvoie du texte. Dès qu'on veut l'utiliser dans du code, il faut le convertir en structure : un dictionnaire, un objet, une ligne en base. Cette conversion se fait généralement à la main, avec du JSON.parse entouré de try/catch, ou avec une bibliothèque de validation ajoutée après coup. Le README de BAML décrit une approche différente : les types sont déclarés dans le langage lui-même et persistent à l'exécution. La formulation employée est explicite, il n'y a ni any ni conversion risquée vers un type arbitraire. Le public visé n'est donc pas le développeur qui fait un appel ponctuel à un modèle, mais celui qui en enchaîne plusieurs et qui veut que le compilateur lui signale les incohérences avant l'exécution. Le README ajoute que les erreurs sont typées et analysées statiquement, ce qui déplace une partie du débogage du runtime vers la compilation.

Types persistants et filesystem comme découpage des modules

Deux choix d'architecture ressortent du README. Le premier concerne le typage : BAML revendique un système de types comparable à celui de Rust, avec une compilation annoncée comme plus rapide que celle de Go, et surtout des types qui restent présents à l'exécution. C'est ce qui permet de valider une réponse de modèle contre la déclaration écrite dans le fichier source, plutôt que contre un schéma dupliqué ailleurs. Le second choix est plus inhabituel : l'arborescence de fichiers décrit les modules et les namespaces. Il n'y a donc pas de directive d'import à écrire pour organiser le code, la position du fichier fait office de déclaration. Ce mécanisme a un revers immédiat : déplacer un fichier change l'API exposée, et le README ne décrit pas d'alias permettant de conserver un ancien chemin. Le langage emprunte aussi à Go sur la concurrence, avec des green threads et une concurrence dite colorless, c'est-à-dire sans distinction entre fonction bloquante et fonction asynchrone. Le README mentionne enfin une bibliothèque standard dédiée aux agents et un cadre de tests et d'évaluation intégré, sans détailler leur contenu.

Mise en route : quatre commandes et un fichier à relire

Le README donne une séquence d'installation courte, reproduite telle quelle : brew install baml, puis baml agent install, puis baml init, puis baml ide install --code. La première commande suppose Homebrew, donc macOS ou Linux. La deuxième installe l'outillage orienté agent, la troisième crée la structure de projet, la quatrième branche l'éditeur. Le README ne précise pas ce que baml init écrit sur le disque, ni quels fichiers de configuration il génère, ni comment choisir un fournisseur de modèle à ce moment-là. C'est la première zone d'ombre : la commande est documentée, son résultat ne l'est pas. Le README indique par ailleurs qu'on peut appeler une fonction BAML depuis TypeScript, Python, Go, C# ou Java, et que l'adoption peut être incrémentale. Le paquet Python publié s'appelle baml-py sur PyPI, ce que le badge de version du README confirme. Pour les autres langages hôtes, le README ne nomme aucun paquet, aucune commande de génération de client, aucune option de configuration. Il faut donc consulter le quickstart lié pour combler cet écart.

Ce que la documentation ne permet pas de trancher

Le README est un texte de positionnement, pas un manuel. Plusieurs affirmations restent sans mécanisme associé. La compilation plus rapide que Go est annoncée sans chiffre, sans protocole et sans jeu de test. L'absence de sorties parasites dans les outils est présentée comme un principe de conception, sans exemple de ce qui est filtré. Le cadre de tests et d'évaluation intégré est mentionné en une ligne. Les guardrails apparaissent dans les topics du dépôt, jamais dans le corps du README. Aucun de ces points n'est démontrable à partir du matériel fourni, et je ne peux pas les vérifier sans installer le projet, ce que je n'ai pas fait. Un lecteur qui a besoin de savoir si BAML tient la charge en production, ou quel fournisseur de modèle est supporté nativement, ne trouvera pas la réponse ici. Le README renvoie vers le site et vers un serveur Discord, ce qui déplace la documentation hors du dépôt.

La vraie limite : un langage de plus dans la pile

Adopter BAML, c'est ajouter un langage, un compilateur et une étape de génération entre votre application et le modèle. Le bénéfice annoncé est le typage de bout en bout. Le coût est réel : vos définitions de types vivent dans des fichiers BAML, pas dans votre code Python ou TypeScript, et il faut maintenir la correspondance entre les deux côtés. Le README ne décrit pas de compatibilité ascendante des fichiers sources entre versions du langage. C'est un point à surveiller quand on voit le rythme des publications. Les releases listées sont toutes des nightly de la branche canary, avec des identifiants comme baml-language-0.18.1-nightly.20260908.a. Une nightly change sans préavis de stabilité. Pour un projet qui doit geler ses dépendances, c'est un obstacle concret, pas un détail de versionnage. BAML est aussi un mauvais choix si votre besoin se limite à un prompt unique et à une réponse en texte libre : le typage n'apporte rien dans ce cas, et vous payez l'outillage sans contrepartie.

Face aux bibliothèques de validation de schéma

L'alternative la plus directe n'est pas un autre langage, c'est une bibliothèque de validation associée à un client d'API de modèle. Dans cette approche, vous écrivez votre schéma dans le langage hôte, vous envoyez une consigne au modèle, vous recevez du texte, puis vous validez la structure obtenue et vous gérez l'échec dans votre propre code. La différence tient à l'endroit où vit le type. Avec BAML, le type est déclaré dans le fichier BAML et persiste jusqu'à l'exécution, selon le README. Avec une bibliothèque de validation, le type est déclaré dans votre code et la contrainte est appliquée après coup, côté application. La seconde approche garde une seule base de code et un seul écosystème de paquets, mais elle ne donne aucune garantie statique sur la forme de la réponse au moment de la compilation. La première fait porter cette garantie par un compilateur, au prix d'un fichier source supplémentaire et d'une génération de client vers votre langage hôte. Le README ne compare pas ces deux modèles et ne fournit aucun élément permettant de dire lequel produit le moins d'erreurs en pratique.

Coût de maintenance et licence

Le dépôt est publié sous Apache-2.0, ce qui autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions de licence et d'état des modifications. Je ne donne pas d'avis juridique : faites relire le texte de la licence si vous redistribuez le compilateur ou des fichiers générés. Sur la maintenance, le rythme des nightly indique un projet actif, mais il indique aussi que la surface stable est étroite. La branche par défaut s'appelle canary, ce qui n'est pas un choix anodin pour un outil que vous intégrez à une chaîne de build. Le coût de mise à jour ne se limite pas au paquet : il faut aussi suivre l'évolution du langage lui-même, puisque vos fichiers baml_src en dépendent. Le README ne documente ni politique de dépréciation, ni période de support, ni canal de version stable. Le dépôt n'est pas archivé, et le dernier push listé porte une date de septembre 2026, ce qui confirme une activité récente sans renseigner sur la stabilité de l'API.

Conclusion éditoriale

BAML convient aux équipes qui écrivent déjà beaucoup d'appels LLM et veulent sortir du parsing ad hoc de JSON, à condition d'accepter un langage supplémentaire dans la pile. Il ne convient pas aux projets qui ont besoin d'une version stable : les releases publiées sont des nightly de la branche canary. Avant d'adopter, vérifiez trois choses concrètes : la version exacte du paquet baml-py que vous installez, le contenu des fichiers baml_src que baml init génère, et la façon dont votre langage hôte consomme le client généré. Si ces trois points vous conviennent, le coût d'entrée reste limité à une commande brew install baml.

Sources officielles

  1. BoundaryML/baml on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Notes de la communauté

Notes de la communauté