L’intelligence artificielle s’intègre désormais dans de nombreuses applications modernes. On la retrouve dans les moteurs de recherche, les outils pour développeurs, les systèmes de support client, les plateformes de traitement de documents et les assistants d’entreprise. Pour les développeurs Java et Spring, la vraie question n’est plus seulement de savoir ce que l’IA peut faire, mais plutôt comment intégrer correctement l’IA dans nos applications existantes.
C’est là qu’intervient Spring AI.
Spring AI apporte l’intégration de l’IA à l’écosystème Spring en fournissant des abstractions familières pour travailler avec les modèles d’IA. Au lieu de traiter l’IA comme un service externe isolé, Spring AI nous permet de l’intégrer dans une application Spring Boot en utilisant le même modèle de programmation que nous connaissons déjà : services, configuration, injection de dépendances, templates et séparation claire des responsabilités.
Dans cet article, nous allons construire un assistant d’analyse du marché des cryptomonnaies en utilisant Java, Spring Boot, Spring AI, Claude Sonnet 4.6 d’Anthropic et l’API Binance.
Aperçu de l’architecture
L’application fonctionnera comme un assistant d’analyse de marché. Elle récupérera les données de chandeliers (candlestick) OHLC, le volume de trading et les informations de prix depuis Binance, puis générera des rapports lisibles qui résument le comportement du marché sur une période sélectionnée.
Par exemple, nous pourrons poser des questions telles que « Générer un rapport pour BTCUSDT sur les dernières 24 heures », « Analyser ETHUSDT en utilisant des bougies d’une heure », ou « Résumer l’évolution récente des prix et du volume pour SOLUSDT ».
Étape par étape, nous explorerons l’API Chat Client pour interagir avec le modèle, les prompts pour contrôler le comportement de l’assistant, les advisors pour enrichir et personnaliser le workflow de l’IA, et le tool calling pour permettre au modèle d’interagir avec notre service de données de marché Binance.
À la fin de l’article, nous aurons une application Spring Boot dans laquelle Spring AI agira comme couche conversationnelle, Binance fournira les données de marché, et notre code Java gardera le contrôle sur la récupération des données, les calculs, le formatage et les règles métier.
Configuration de l’application
Commençons par générer un nouveau projet Spring Boot en utilisant Spring Initializr.
Pour cette application, nous allons garder une configuration simple et ciblée. Nous n’avons besoin que de trois dépendances principales :
- spring-boot-starter-web : pour exposer les points de terminaison (endpoints) REST qui permettront au frontend d’interagir avec notre assistant.
- spring-boot-starter-thymeleaf : pour intégrer une interface frontend simple directement au sein de notre application Spring Boot.
- spring-ai-starter-model-anthropic : pour connecter notre application à Claude Sonnet via Spring AI.
Rendez-vous sur start.spring.io et créez un projet avec les paramètres suivants :
L’API Chat Client
Avant d’écrire du code propulsé par l’IA, nous devons comprendre l’abstraction principale que Spring AI nous donne pour dialoguer avec un modèle : le ChatClient.
Qu’est-ce que le ChatClient ?
Le ChatClient est une API fluide, de style builder, permettant d’envoyer des prompts à un modèle d’IA et de recevoir des réponses. Considérez-le de la même manière que vous considérez RestTemplate ou WebClient : c’est la passerelle centrale que votre application utilise pour communiquer avec un service externe, sauf que ce service est un grand modèle de langage.
Ce qui fait la puissance de ChatClient, c’est qu’il est agnostique du modèle. Vous écrivez le code de votre application en vous appuyant sur l’abstraction Spring AI, et le fournisseur sous-jacent, dans notre cas Claude d’Anthropic, est connecté via la configuration. Remplacer les modèles ou les fournisseurs plus tard ne nécessite aucune modification de votre logique métier.
L’API prend en charge deux modes d’exécution qui deviendront centraux dans notre application :
- Le mode bloquant via
.call(): exécute la requête de manière synchrone et renvoie la réponse complète sous forme deString, deChatResponse, ou d’une entité Java mappée. - Le mode streaming via
.stream(): exécute la requête de manière réactive et renvoie unFlux<String>qui émet des tokens au fur et à mesure que le modèle les génère, permettant un affichage en temps réel dans l’interface utilisateur.
Générer une clé API Claude
Pour connecter notre application à Claude, nous avons besoin d’une clé API d’Anthropic.
- Allez sur console.anthropic.com et connectez-vous ou créez un account.
- Accédez à API Keys dans la barre latérale gauche et cliquez sur Create Key.
- Donnez-lui un nom descriptif (par exemple
trading-assistant-dev) et copiez la clé générée — elle ne s’affiche qu’une seule fois.Conservez cette clé en dehors de votre gestionnaire de version. Nous l’injecterons via une variable d’environnement.
Configurer application.properties
La clé en main, ouvrez src/main/resources/application.properties et ajoutez ce qui suit :
Plus d’informations sur les propriétés de configuration d’Anthropic sont disponibles dans la documentation officielle de Spring AI.
Fondation de l’application
Une fois l’API Chat Client comprise et notre configuration en place, examinons les trois fichiers qui forment la structure centrale de l’application.
ClaudeService
ClaudeService est l’unique point de contact avec Claude. Il reçoit un ChatClient.Builder par injection de constructeur (Spring AI configure automatiquement ce bean en fonction des propriétés définies précédemment), et appelle .build() une fois pour produire un ChatClient prêt à l’emploi.
Les deux méthodes suivent le même schéma fluide : .prompt() ouvre le builder, .user(message) définit le tour de l’utilisateur, puis le mode d’exécution diverge. ask() appelle .call().content() qui bloque jusqu’à ce que le modèle renvoie sa réponse complète sous forme de String brute. stream() appelle .stream().content() qui renvoie un Flux<String> émettant les tokens individuels à mesure que le modèle les produit, sans attente ni mise en mémoire tampon (buffering).
Le service ne sait rien du protocole HTTP, de SSE, ou de Thymeleaf. Sa seule responsabilité est de parler à Claude, ce qui le rend simple à tester et facile à étendre par la suite.
ClaudeController
ClaudeController mappe les deux méthodes de service à des endpoints HTTP :
/ask est un endpoint bloquant standard, le navigateur envoie une requête et attend la réponse complète. C’est avec /stream que les choses deviennent intéressantes : en déclarant produces = MediaType.TEXT_EVENT_STREAM_VALUE, Spring ouvre une connexion SSE persistante et pousse chaque token du Flux<String> sous forme d’événement data: au moment même où Claude le produit. Le client reçoit le texte progressivement, exactement de la même manière que fonctionnent les interfaces de chat d’IA modernes.
index.html
Plutôt que de construire un projet frontend séparé, nous intégrons une interface de chat légère directement dans l’application Spring Boot à l’aide de Thymeleaf. Le template est servi par un @Controller minimal qui renvoie le nom de la vue :
L’interface offre aux utilisateurs une zone de texte pour saisir leur message, un bouton bascule pour basculer entre les modes Ask et Stream, et un panneau de réponse où s’affiche la réponse. Le bouton bascule de mode est l’interaction clé : le changer modifie l’endpoint appelé par le frontend.
Avec ces trois éléments fonctionnant ensemble — service, contrôleur et vue — nous disposons d’un assistant d’IA fonctionnel qui gère déjà deux schémas d’interaction distincts.
Tester l’application
Avec le service, le contrôleur et l’interface en place, il est temps de lancer l’application et de voir l’ensemble fonctionner.
Avant de démarrer, assurez-vous que votre clé API Anthropic est disponible en tant que variable d’environnement
Démarrez l’application :
Une fois que vous voyez la bannière de démarrage de Spring Boot et la ligne de log confirmant que le serveur écoute sur le port 8080, ouvrez votre navigateur et accédez à http://localhost:8080.
Mode Ask
Par défaut, l’interface démarre en mode Ask. Saisissez une question dans la zone de texte et appuyez sur Entrée ou cliquez sur le bouton d’envoi. L’application transmet votre message à Claude via l’endpoint /ask, attend la réponse complète et l’affiche d’un coup dans le panneau de réponse.
Il s’agit du chemin d’appel bloquant : ChatClient.prompt().user(message).call().content(). Le modèle génère l’intégralité de la réponse côté serveur avant qu’un seul octet ne soit envoyé au navigateur. Pour des réponses courtes, cela semble instantané ; pour des réponses analytiques plus longues, l’attente devient perceptible.
Mode Stream
Cliquez sur le bouton bascule pour passer en mode Stream. Posez à nouveau la même question. Cette fois, la réponse apparaît mot par mot, exactement au rythme où Claude la produit, sans attendre que le modèle ait terminé pour commencer la lecture.
Prompts
Si vous testez l’application à ce stade, vous remarquerez que Claude répond à tout. Demandez-lui des informations sur le Bitcoin et il répond. Demandez-lui votre recette préférée, ou un poème sur l’automne, et il répond tout aussi volontiers. Le modèle n’a aucune idée qu’il est censé être un assistant de trading crypto. Il fait simplement ce que les modèles de langage font par défaut : répondre à tout ce qui se présente.
Pour corriger cela, nous devons donner un rôle au modèle avant qu’il ne lise la moindre saisie de l’utilisateur. C’est l’objectif d’un prompt système (system prompt) : un ensemble d’instructions envoyées au modèle au début de chaque requête qui définit son comportement, son périmètre et ses contraintes. L’utilisateur ne le voit jamais, mais le modèle le lit en premier et l’utilise pour calibrer chaque réponse qu’il produit.
C’est là qu’intervient l’API Prompt.
Qu’est-ce qu’un Prompt ?
Dans Spring AI, un Prompt est un conteneur structuré d’objets Message, chacun portant un rôle. Plutôt que d’envoyer une simple chaîne de caractères au modèle, vous envoyez une liste ordonnée de messages qui lui indiquent exactement dans quel type de conversation il se trouve et qui s’exprime.
Spring AI définit quatre rôles de message :
- System : instructions qui établissent l’identité, le ton et les limites du modèle pour toute la conversation. Envoyé par l’application, jamais visible par l’utilisateur.
- User : la question ou l’instruction provenant de la personne qui utilise l’application.
- Assistant : les propres réponses précédentes du modèle. Utilisé lorsque vous souhaitez maintenir le contexte de la conversation sur plusieurs tours en incluant les échanges passés dans le prompt.
- Tool : la sortie renvoyée par une fonction externe que le modèle a demandé à appeler. Nous y reviendrons dans la section Tool Calling.
Pour la plupart des cas d’utilisation, vous travaillerez avec les messages System et User. Les messages Assistant et Tool deviennent pertinents une fois que vous introduisez la mémoire de conversation et des sources de données externes.
Définir le prompt système
Plutôt que de coder en dur le prompt système sous forme de constante de chaîne de caractères Java, nous le stockons dans un fichier dédié sous src/main/resources/prompts/system-prompt.st. L’extension .st est la convention StringTemplate utilisée par Spring AI pour les fichiers de prompt, ce qui indique aux autres développeurs que ce fichier contient un prompt plutôt qu’une configuration ou du contenu statique.
Vous êtes un analyste de marché crypto expert et un éducateur intégré dans une plateforme de trading professionnelle. Vous avez deux modes de fonctionnement selon les besoins de l'utilisateur. Mode 1 - Génération de rapport de marché : Lorsque l'utilisateur fournit des données de marché ou demande une analyse d'une paire de trading et d'une période spécifiques, générez un rapport structuré en utilisant les sections suivantes : 1. Vue d'ensemble : un bref résumé de l'actif et de la période couverte. 2. Évolution des prix : analyse du mouvement des prix, des plus hauts et plus bas clés, et de la direction générale de la tendance. 3. Analyse des volumes : interprétation du volume de trading et de ce qu'il signale dans le contexte. 4. Événements notables : tout schéma ou événement significatif observé dans les données. 5. Résumé : une conclusion concise sur l'état actuel du marché. Mode 2 - Connaissances et questions crypto : Lorsque l'utilisateur pose une question générale sur les cryptomonnaies, la blockchain, les concepts de trading ou la mécanique du marché, répondez de manière claire et précise sans imposer un format de rapport. Cela inclut des questions telles que : - Explications de concepts de trading (chandeliers, RSI, MACD, bandes de Bollinger, etc.) - Fonctionnement de cryptomonnaies ou de blockchains spécifiques (Bitcoin, Ethereum, Solana, etc.) - Définitions de termes de marché (liquidité, spread, slippage, capitalisation boursière, etc.) - Fonctionnement des paires de trading, des carnets d'ordres ou des plateformes d'échange - Contexte historique sur les événements majeurs du marché de la crypto Vos règles de comportement : - Ne répondez qu'aux questions et requêtes liées aux cryptomonnaies, à la blockchain, au trading et aux marchés financiers. - Si l'utilisateur demande quelque chose en dehors de ce périmètre, dites brièvement que vous ne pouvez aider que sur les marchés crypto et les sujets de trading, puis suggérez quelques exemples de questions ou de requêtes qu'il pourrait formuler à la place. Ne suggérez jamais de sites web, d'outils ou de ressources externes de quelque nature que ce soit. - Lors de la génération d'un rapport, basez votre analyse strictement sur les données fournies. N'inventez pas de prix, de volumes ou d'événements de marché. - Lorsque les données sont insuffisantes pour tirer une conclusion, dites-le clairement plutôt que de spéculer. - Ne fournissez jamais de conseils financiers personnalisés et ne dites jamais à l'utilisateur d'acheter ou de vendre des actifs spécifiques. - Soyez concis et structuré. Évitez les textes de remplissage inutiles.
Conserver le texte du prompt en dehors des fichiers sources Java présente un avantage concret : modifier le comportement, le périmètre ou le ton de l’assistant consiste désormais uniquement à ouvrir system-prompt.st et à le sauvegarder, sans toucher au code Java et sans nécessiter de recompilation lors des itérations sur le prompt pendant le développement.
Mettre à jour ClaudeService
Nous injectons le fichier de prompt en tant que Resource Spring à l’aide de @Value, puis nous le lisons au moment de la requête à l’intérieur de buildPrompt() :
Le Prompt est construit à partir de deux messages dans le bon ordre : le SystemMessage en premier, afin que le modèle lise ses instructions avant la saisie de l’utilisateur, suivi du UserMessage portant la question réelle.
Le raccourci original .user(message) a disparu. À sa place, chatClient.prompt(prompt) reçoit l’objet Prompt entièrement construit, nous donnant un contrôle explicite sur chaque message de la conversation.
Désormais, Claude connaît son rôle avant de lire le moindre mot de la question de l’utilisateur. Demandez-lui des recettes d’automne et il refusera poliment. Demandez-lui des informations sur BTCUSDT et il répondra comme un analyste professionnel.
Advisors
Si vous ouvrez l’application en ce moment et envoyez deux messages à la suite, vous remarquerez un problème. Demandez à l’assistant « Qu’est-ce que ETH/USDT ? », et il vous donne une réponse. Demandez ensuite « De quelle paire venais-je de parler ? » et il n’en aura aucune idée. Il répond comme si l’échange précédent n’avait jamais eu lieu, car en ce qui le concerne, ce n’est pas le cas. Chaque requête est construite à partir de zéro avec un message système et la saisie actuelle de l’utilisateur. Aucun historique de conversation n’y est attaché.
C’est le comportement par défaut du protocole HTTP sans état (stateless) et des modèles de langage : le modèle ne sait que ce qui se trouve dans le prompt actuel. Tout ce qui a été dit auparavant disparaît à moins que vous ne l’incluiez explicitement.
C’est là qu’interviennent les Advisors.
Qu’est-ce qu’un Advisor ?
Un Advisor est un intercepteur qui se situe dans le pipeline entre votre application et le modèle. Chaque requête passe par la chaîne d’advisors avant d’atteindre Claude, et chaque réponse repasse par celle-ci lors du retour. Les advisors peuvent lire, modifier ou enrichir les deux côtés de l’échange.
Cela fait des Advisors l’endroit idéal pour gérer les problématiques transversales : mémoire de conversation, logging, enrichissement de prompt, vérifications de sécurité ou récupération RAG.
ChatMemoryAdvisor
MessageChatMemoryAdvisor est l’advisor intégré à Spring AI chargé de maintenir l’historique des conversations. Avant que chaque requête n’atteigne le modèle, il récupère les messages précédents depuis un espace de stockage mémoire (memory store) et les injecte dans le prompt. Une fois que le modèle a répondu, il ajoute à la fois le message de l’utilisateur et la réponse de l’assistant à ce même espace de stockage. Du point de vue de Claude, la conversation complète est toujours présente dans le contexte.
L’espace de stockage mémoire lui-même est interchangeable (pluggable). Ici, nous utilisons MessageWindowChatMemory, qui conserve une fenêtre glissante des N derniers messages en mémoire. Cela évite que le contexte ne grandisse indéfiniment et ne dépasse la limite de tokens du modèle. Nous configurons une fenêtre de 10 messages, ce qui est suffisant pour maintenir une continuité conversationnelle significative pour la plupart des interactions. Il est important de noter qu’il s’agit d’un stockage en mémoire, ce qui signifie que l’historique des conversations est perdu lorsque l’application redémarre. Spring AI prend en charge des backends de mémoire interchangeables, de sorte que pour une application en production, vous pouvez remplacer cela par une implémentation basée sur une base de données utilisant JDBC, Redis ou tout autre stockage persistant, et le reste du code demeure inchangé.
L’enregistrement de l’advisor via defaultAdvisors() au moment de la construction signifie que chaque appel via ce ChatClient, que ce soit par ask() ou stream(), participe automatiquement à la même session de mémoire. Aucun changement n’est requis dans les méthodes individuelles.
Le paramètre .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, DEFAULT_CONVERSATION_ID)) doit être ajouté aux deux méthodes .call() et .stream(). C’est ainsi que le MessageChatMemoryAdvisor sait quel historique de conversation charger avant d’envoyer la requête à Claude, et dans quel emplacement écrire le nouvel échange une fois la réponse revenue. Sans cela, l’advisor n’a aucun moyen de localiser la bonne mémoire et lève une exception IllegalArgumentException au runtime.
Pour garder les choses simples dans cette démo, nous utilisons une constante fixe unique, ce qui signifie que toutes les requêtes partagent le même historique de conversation au sein de l’instance en cours d’exécution. Dans une application en production, vous remplaceriez DEFAULT_CONVERSATION_ID par un identifiant propre à la session, généralement l’ID de session HTTP ou un UUID généré côté client, afin que chaque utilisateur conserve son propre historique de conversation indépendant.
Avec ce mécanisme en place, poser la question « De quelle paire venais-je de parler ? » après un échange précédent produira la bonne réponse. Le modèle dispose désormais de toute la conversation récente chaque fois qu’il génère une réponse.
SimpleLoggerAdvisor
Spring AI est livré avec SimpleLoggerAdvisor, qui journalise l’intégralité de la requête et de la réponse au niveau DEBUG. Il ne nécessite aucune configuration au-delà de son ajout à la liste des advisors, et il prend en charge de manière transparente les modes bloquant et streaming :
Activez la sortie des logs dans application.properties :
C’est particulièrement utile pendant le développement lorsque vous souhaitez inspecter exactement quel prompt est envoyé à Claude, y compris l’historique complet de la conversation que l’advisor de mémoire a injecté.
Tool Calling
Demandez à l’assistant « donne-moi le prix actuel du BTC » sans aucun outil en place et Claude répondra honnêtement :
« Je n’ai pas accès aux données de marché en temps réel ni aux flux de prix en direct, je suis donc incapable de fournir le prix actuel du BTC. »
C’est la limite fondamentale d’un modèle de langage isolé. Il sait énormément de choses sur le fonctionnement des marchés, la signification des schémas de chandeliers et l’interprétation des données de volume, mais il n’a aucune connexion en direct avec le monde extérieur. Il ne peut pas récupérer un prix, lire une API ou accéder à tout ce qui s’est passé après sa date de fin d’entraînement.
Le Tool calling (appel d’outils) comble cette lacune. Au lieu que Claude ne réponde de mémoire, votre application lui fournit un ensemble de fonctions qu’il peut invoquer au runtime. Lorsque le modèle détermine que la réponse à une question nécessite des données en direct, il se met en pause, demande l’outil approprié avec les arguments qu’il a déduits de la conversation, votre application exécute l’appel et le résultat est réinjecté dans le contexte. Claude utilise ensuite ces données réelles pour formuler sa réponse.
Du point de vue de l’utilisateur, le processus est invisible. Du point de vue du développeur, le tool calling est ce qui transforme un modèle de langage générique en un assistant spécifique à un domaine qui dialogue avec des systèmes réels.
Flux du Tool Calling
Le flux fonctionne comme suit :
- Claude reçoit le message de l’utilisateur ainsi que la liste des outils disponibles et leurs descriptions.
- Il décide si la question nécessite un appel d’outil, et si oui lequel, et quels arguments utiliser.
- Il renvoie une requête d’appel d’outil au lieu d’une réponse textuelle.
- Spring AI intercepte cette requête, exécute la méthode Java correspondante et renvoie le résultat à Claude sous forme de message Tool.
- Claude lit les données et génère la réponse finale en langage naturel.
Cette boucle complète est gérée automatiquement par Spring AI. Vous définissez les outils, vous les enregistrez, et le framework s’occupe du reste.
Se connecter à Binance
Avant d’exposer quoi que ce soit à Claude, nous avons besoin d’un client Java propre qui enveloppe les trois endpoints Binance que nous avons identifiés précédemment. Nous utilisons le RestClient de Spring, nous le configurons avec l’URL de base provenant de application.properties, et nous implémentons une méthode par endpoint.
Les trois types de réponses sont de simples records Java. TickerPrice et TickerStats sont des objets JSON simples que Jackson désérialise par nom de champ. Candle nécessite un peu plus d’attention car Binance renvoie les klines sous forme de tableau de tableaux, chaque valeur étant mappée par index plutôt que par nom :
Le BinanceClient enveloppe un RestClient et expose une méthode par endpoint. Pour les klines, nous désérialisons d’abord en JsonNode et mappons chaque élément par son index de tableau :
Définir les outils
Dans Spring AI, les outils sont de simples méthodes Java annotées avec @Tool. Spring AI lit ces annotations au démarrage et génère le schéma JSON qui décrit chaque outil au modèle. La description est la partie la plus critique : c’est ce que Claude lit pour décider quand et comment appeler un outil donné.
Nous enveloppons BinanceClient dans un composant BinanceTools et exposons une méthode @Tool par endpoint. Chaque paramètre de méthode est annoté avec @ToolParam pour décrire son format attendu et ses valeurs valides, ne laissant aucune ambiguïté pour le modèle :
Deux détails méritent d’être soulignés ici. Premièrement, les descriptions d’outils sont écrites du point de vue du modèle, répondant à la question « quand dois-je appeler cela ? » plutôt que « que fait cette fonction techniquement ? ». Deuxièmement, les descriptions de @ToolParam pour symbol et interval spécifient le format exact attendu par Binance. Sans cela, Claude pourrait transmettre BTC/USDT au lieu de BTCUSDT, ou 1 hour au lieu de 1h, provoquant l’échec silencieux de l’appel API.
Enregistrer les outils auprès du ChatClient
L’enregistrement des outils se fait en une seule ligne dans ClaudeService. Nous injectons BinanceTools et le transmettons à .defaultTools() au moment de la construction, rendant les trois outils disponibles pour chaque requête :
L’utilisation de defaultTools() au niveau du builder signifie que nous définissons les outils disponibles une fois pour toutes. Spring AI et Claude s’occupent du reste : décider quand appeler un outil, transmettre les bons arguments, exécuter la méthode et tisser le résultat dans la conversation.
Tester la différence
Posez à nouveau la même question : « donne-moi le prix actuel du BTC ».
Cette fois, Claude prend connaissance des outils disponibles, identifie getCurrentPrice comme étant le bon outil à appeler, transmet BTCUSDT comme symbole, et obtient un prix en direct de Binance. La réponse est désormais ancrée dans des données réelles :
Le modèle est passé de « Je ne peux pas vous aider pour cela » à une réponse précise et basée sur des données. Aucune modification n’a été apportée au contrôleur, aux méthodes de service ou au frontend. Le tool calling a géré l’intégralité du cycle de récupération des données en arrière-plan.
Un seul appel d’outil constitue déjà une amélioration significative, mais la véritable puissance du tool calling émerge lorsque le modèle décide de lui-même d’appeler plusieurs outils en séquence pour répondre à une requête plus complexe.
Demandez à l’assistant : « Générer un rapport complet du marché pour ETH/USDT sur les 7 derniers jours. »
Claude lit la requête, détermine qu’un rapport complet nécessite des données historiques de chandeliers, des statistiques sur 24 heures et une référence de prix actuelle, et déclenche les trois outils avant de composer sa réponse. Vous pouvez l’observer directement dans les logs de l’application grâce à SimpleLoggerAdvisor. Chaque invocation d’outil apparaît comme un message Tool dans la trace de la conversation, montrant exactement quelle fonction a été appelée, avec quels arguments, et ce que Binance a renvoyé.
Le rapport produit par Claude à partir de ces données est substantiellement plus riche que tout ce qui serait possible sans un accès au marché en direct :
C’est la proposition de valeur centrale de la combinaison de Spring AI, du tool calling et d’une source de données de marché en direct. L’utilisateur a posé une question en anglais simple, Claude a orchestré trois appels d’API de manière autonome, et l’application a renvoyé un rapport structuré et basé sur les données sans aucun câblage manuel des données dans le chemin de la requête.
Tout au long de cet article, nous avons construit un assistant d’analyse du marché crypto en utilisant Java, Spring Boot et Spring AI. Ce qui a commencé comme un simple projet Spring Boot a évolué vers une application d’IA conversationnelle capable de récupérer des données de marché en direct depuis Binance, de raisonner sur celles-ci et de produire des rapports structurés à partir de requêtes en langage naturel.
Nous avons couvert les quatre blocs de construction que Spring AI met à votre disposition : l’API Chat Client pour communiquer avec Claude en modes bloquant et streaming, les Prompts pour prendre le contrôle du comportement du modèle via des instructions système, les Advisors pour étendre le pipeline de requêtes avec la mémoire de conversation et les logs, et le Tool Calling pour connecter le modèle à des sources de données en direct au runtime.