Aller au contenu
Riadh Mnasri
← Retour au blog
4 min de lecture

LangChain4j vs Spring AI : deux façons d'amener un LLM dans une JVM

Après avoir intégré Spring AI dans un backend Kotlin, la question naturelle a été de comparer avec LangChain4j, l'autre librairie JVM qui revient systématiquement dans les discussions sur l'IA côté Java et Kotlin. Les deux font sensiblement la même chose, appeler un LLM, gérer des outils, structurer une sortie, mais elles partent de deux points de départ opposés, et ce point de départ se ressent à chaque ligne de code.

Deux philosophies, pas deux implémentations d'une même idée#

Spring AI part du framework : un ChatClient s'injecte comme n'importe quel bean Spring, la configuration passe par les mécanismes Spring habituels (application.yml, auto-configuration), et l'intégration vise à disparaître dans les conventions déjà en place sur un projet Spring Boot. LangChain4j part du modèle : la librairie ne présuppose aucun framework, elle expose ses propres abstractions (chains, agents, mémoire conversationnelle) que l'on peut faire cohabiter avec Spring, Quarkus, Micronaut ou aucun framework du tout.

Spring AILangChain4j
Point de départLe framework SpringLe modèle et ses abstractions
Dépendance à un frameworkFort, pensé pour Spring BootAucune, s'utilise indépendamment
Configurationapplication.yml, auto-configuration SpringConstruction explicite en code
Sortie structuréeentity(), désérialisation directeInterfaces AI Services, générées dynamiquement
Courbe d'adoption sur un projet Spring existantFaible, s'intègre aux conventions en placeMoyenne, introduit son propre vocabulaire

Ce que ça donne côté code#

Le même besoin, scorer une offre de mission par rapport à une stack, s'écrit en LangChain4j via une interface annotée plutôt qu'un appel impératif :

java
interface MissionScorer {
    @SystemMessage("Tu scores une offre de 0 à 100 par rapport à la stack fournie.")
    @UserMessage("Stack : {{stack}}\n\nOffre : {{mission}}")
    ScoreResult score(@V("stack") String stack, @V("mission") String mission);
}
 
MissionScorer scorer = AiServices.create(MissionScorer.class, model);
ScoreResult result = scorer.score(stackSummary, missionDescription);

L'interface MissionScorer n'a ici aucune implémentation écrite à la main : LangChain4j en génère une dynamiquement à partir des annotations. C'est élégant, et ça pousse le prompt au même niveau de première classe qu'une signature de méthode. C'est aussi ce qui, pour un développeur venant d'un monde Spring pur, demande un temps d'adaptation réel : le comportement n'est plus dans le corps de la méthode, il est dans ses annotations.

Là où Spring AI gagne : un projet Spring Boot existant#

Astuce

Sur un backend Spring Boot déjà en place, avec son auto-configuration, son observabilité et ses conventions établies, Spring AI a un avantage qui n'est pas technique mais organisationnel : il ne demande pas d'apprendre un nouveau vocabulaire, juste un nouveau type de bean.

C'était le cas pour l'exemple pris sur MissionMatch : Spring AI s'est glissé dans une architecture hexagonale existante sans rien redéfinir, parce que tout le reste du projet parlait déjà Spring.

Là où LangChain4j gagne : la portabilité et les agents#

LangChain4j prend l'avantage dès que le projet n'est pas un projet Spring, ou dès que le besoin dépasse un simple appel modèle : orchestration d'outils multiples, mémoire conversationnelle, agents qui enchaînent plusieurs appels. Ses abstractions sont pensées pour ces cas dès le départ, là où Spring AI reste plus proche d'un client HTTP typé que d'un framework d'orchestration d'agents.

Attention

Choisir LangChain4j pour ses capacités d'agent sur un projet qui n'a besoin, en réalité, que d'un appel modèle simple, importe une complexité et un vocabulaire qui ne se justifient pas. La question à se poser n'est pas « laquelle est la plus puissante », c'est « qu'est-ce que ce projet précis a vraiment besoin de faire ».

Le critère qui tranche, en pratique#

Le choix ne se fait pas sur des benchmarks de performance, les deux appellent le même modèle derrière une fine couche d'abstraction. Il se fait sur une seule question : le projet est-il déjà structuré autour de Spring, ou a-t-il besoin d'une librairie qui ne présuppose rien sur le reste de la stack ? Sur un backend Spring Boot existant, Spring AI coûte moins cher en adoption. Sur un projet neutre, ou qui a vraiment besoin d'orchestrer plusieurs outils et agents, LangChain4j offre un vocabulaire déjà pensé pour ça, que Spring AI n'a pas vocation à couvrir seul.