Modèle / jeu de données
ax-llm/ax avatar
ax-llm/ax

Ax : signatures typées et profils de déploiement pour les LLM en TypeScript

The pretty much "official" DSPy framework for Typescript

2 924 étoiles194 forksTypeScriptApache-2.0

En bref

De quoi s’agit-il ?
Ax propose un modèle de programmation unique pour construire avec des LLM, avec des signatures typées, des agents et des optimiseurs. Le point à vérifier avant d'adopter est le coût de maintenance d'une base de code multi-langages et un écosystème d'optimiseurs plus étroit que celui de DSPy.
À qui s’adresse-t-il ?
Ax convient aux équipes TypeScript qui veulent des sorties structurées validées, des agents et des flows dans un seul modèle de programmation, sans changer de code en passant d'OpenAI à Anthropic ou Gemini. Il ne convient pas si vous avez besoin d'un écosystème d'optimiseurs large et éprouvé : l'optimiseur mis en avant est GEPA, et les autres familles de DSPy ne sont pas documentées ici.
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. Les derniers commits datent d’il y a 6 jours.
En quel langage est-il écrit ?
Principalement TypeScript, 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 que les signatures résolvent

Demander du JSON à un LLM et le parser à la main produit du code fragile : le modèle renvoie du texte, parfois du JSON valide, parfois non. Ax remplace cette étape par une signature déclarative. Le README donne cet exemple : une chaîne 'review:string -> sentiment:class "positive, negative, neutral"' décrit une entrée et une sortie contrainte à trois valeurs. La sortie est typée comme une union littérale, donc le compilateur TypeScript connaît les valeurs possibles. Le public visé est l'équipe qui écrit déjà du TypeScript côté serveur ou dans Node.js et qui veut éviter de maintenir un parseur et un validateur maison au-dessus de chaque appel de modèle. La signature peut aussi s'écrire avec un builder fluent f() ou avec n'importe quel validateur Standard Schema v1, Zod, Valibot ou ArkType, ce qui laisse le choix du schéma sans imposer une bibliothèque de validation particulière.

Profils de déploiement : le nom compte plus que le modèle

Dans l'exemple du README, ai({ name: "openai", apiKey: process.env.OPENAI_APIKEY }) construit le client. Le champ name n'est pas seulement un identifiant de fournisseur : le README le décrit comme un profil de déploiement qui sélectionne le comportement réseau. Un modèle DeepSeek hébergé par Together utilise le point d'accès et les règles de raisonnement de Together, pas le format natif de DeepSeek. C'est un choix de conception qui a des conséquences : changer de fournisseur revient à changer une chaîne, mais la même chaîne ne produit pas le même comportement selon l'hébergeur. La liste citée inclut openai, anthropic, google-gemini, meta, together, fireworks, deepseek et grok. Le diagramme du README montre le flux : une signature alimente AxGen, qui alimente les descripteurs de fournisseurs, AxAgent, AxFlow et les artefacts d'optimiseur. Le chemin chaud revendiqué est volontairement mince : rendre la signature, appeler le fournisseur, parser le résultat, retourner une valeur typée.

Agents, flows et optimiseurs : ce que couvre le noyau

Au-dessus de la génération typée, le README décrit trois blocs distincts. Les agents disposent d'une exécution runtime, de budgets de contexte, de checkpoints, de rejeu du journal d'actions, de découverte, de mémoire, de compétences et de délégation. Les flows sont des graphes de programme typés avec branches, boucles, rétroaction, comportement de cache, exécution parallèle et projection via .returns(...). Les optimiseurs incluent GEPA, le few-shot bootstrapping et des artefacts d'optimiseur portables avec des flux d'évaluation et d'application. Cette couverture est large pour une bibliothèque unique, et c'est précisément là que se situe la question de fond : chaque bloc ajoute une surface d'API à apprendre et à suivre entre deux versions. Le rythme de publication observé, trois versions en neuf jours autour de septembre 2026, suggère que cette surface bouge encore.

Démarrer : installation et exécution des exemples

Le paquet TypeScript est publié sur npm sous @ax-llm/ax et s'importe avec import { ai, ax, agent, flow } from "@ax-llm/ax". Le dépôt fournit un lanceur d'exemples qui évite de retenir les commandes de compilation de chaque langage. La commande npm run example -- list affiche les exemples disponibles, et chaque cible se lance avec un chemin de fichier, par exemple npm run example -- python src/examples/python/generation/axgen-openai.py ou npm run example -- rust src/examples/rust/generation/basic_generation.rs. Le benchmark de streaming s'exécute via des variables d'environnement, notamment AX_STREAM_BENCH_PROVIDER, AX_STREAM_BENCH_MODEL, AX_STREAM_BENCH_RUNS et AX_STREAM_BENCH_WARMUP_RUNS, avec npm run tsx src/examples/streaming-latency.ts. Ces noms de variables et ces chemins viennent du README. Le même document renvoie à docs/AI_PROFILES.md pour les profils et les migrations de classes, et à docs/COMPILER.md pour le compilateur indépendant du langage.

Le streaming comme boucle de correction, pas comme confort

Le README présente le streaming comme le mode par défaut, avec un argument précis : parser les champs au fil de leur arrivée, exécuter des assertions en flux, échouer tôt, annuler le flux en cours et lancer une correction sans dépenser des jetons sur une sortie déjà invalide. C'est un mécanisme, pas un slogan. forward() reste disponible pour obtenir un objet final unique, et streamingForward() expose le flux directement. La limite tient au compromis : annuler un flux ne rembourse pas les jetons déjà générés, et une assertion en flux mal calibrée peut interrompre des réponses correctes. Le README affirme que, sur les exécutions récentes mentionnées, la file d'attente du fournisseur et la génération du modèle dominent la latence totale, AxGen restant proche du chemin ai.chat() brut. Aucun chiffre n'est fourni dans le matériel, et le dépôt invite à mesurer soi-même avec le benchmark plutôt qu'à se fier à une valeur publiée.

Le pari multi-langages et son coût

Le README annonce le même modèle de programmation en TypeScript, Python, Java, C++, Go et Rust. Le TypeScript est l'implémentation source et le paquet publié. Les autres bibliothèques sont décrites comme générées et vérifiées, avec leur source commitée sous packages/<language>. Le point d'entrée Python est axllm, Java passe par dev.axllm:ax sur Maven Central, Rust par axllm sur crates.io, Go s'installe avec go get, et C++ se construit depuis les sources via CMake FetchContent. Le README précise que lorsque AxIR change, il faut lancer npm run axir:generate-packages pour régénérer les paquets commités. C'est le coût réel du pari : une modification du noyau sémantique se propage à des paquets générés dans cinq autres langages. Une équipe qui n'utilise que TypeScript n'a pas à s'en soucier, mais elle dépend d'un dépôt dont une partie du travail de maintenance concerne ces paquets.

Face à DSPy : la différence n'est pas la traduction

Le README se présente lui-même comme le framework DSPy pour TypeScript, et la comparaison la plus utile porte sur les optimiseurs. DSPy a construit sa réputation sur un ensemble de stratégies d'optimisation et une communauté Python autour d'elles. Ax met en avant GEPA, le few-shot bootstrapping et des artefacts d'optimiseur portables. Le README ne documente pas d'autres familles d'optimiseurs, et il ne fournit aucune comparaison de résultats entre Ax et DSPy. La différence d'approche se situe donc ailleurs : Ax est TypeScript-first, avec des signatures qui acceptent un validateur Standard Schema v1 et des profils de déploiement qui encapsulent le comportement réseau du fournisseur. Une équipe dont le reste de la pile est en Python n'a guère de raison de changer. Une équipe qui écrit du TypeScript et veut garder ses schémas Zod existants trouve ici une intégration directe que DSPy n'offre pas dans ce langage.

Licence et maintenance

Le dépôt est publié sous Apache-2.0, une licence permissive qui autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions et de l'avis de licence. Ce texte n'est pas un conseil juridique : si vous redistribuez une version modifiée, faites relire les conditions par une personne compétente. Côté maintenance, le rythme de publication est élevé, ce qui implique de suivre les notes de version et de vérifier les migrations de classes documentées dans docs/AI_PROFILES.md avant de mettre à jour. Le projet n'est pas archivé et le README renvoie à un serveur Discord et à un compte X pour le suivi des versions, ce qui indique un développement actif mais concentré autour d'un mainteneur identifiable.

Conclusion éditoriale

Ax convient aux équipes TypeScript qui veulent des sorties structurées validées, des agents et des flows dans un seul modèle de programmation, sans changer de code en passant d'OpenAI à Anthropic ou Gemini. Il ne convient pas si vous avez besoin d'un écosystème d'optimiseurs large et éprouvé : l'optimiseur mis en avant est GEPA, et les autres familles de DSPy ne sont pas documentées ici. Avant de vous engager, vérifiez deux choses concrètes : que votre fournisseur est couvert par un profil de déploiement dans docs/AI_PROFILES.md, et que l'exemple de benchmark de streaming donne une surcharge acceptable sur vos propres modèles.

Sources officielles

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

Notes de la communauté