Mise en œuvre d'un moteur de recherche sémantique avec Spring AI et Milvus

L'intégration de l'intelligence artificielle générative dans l'écosystème Java s'est simplifiée avec l'émergence de Spring AI. L'un des cas d'usage les plus performants consiste à coupler un modèle de langage (LLM) avec une base de données vectorielle pour créer un système de type RAG (Retrieval-Augmented Generation). Cet article détaille comment orchestrer Spring AI et Milvus pour bâtir une solution de questions-réponses intelligente.

Prérequis techniques

  • Java 17 ou version ultérieure
  • Environnement Maven 3.8+
  • Docker pour l'instance de base de données

Configuraton des dépendances

Pour commencer, intégrez les modules nécessaires dans votre fichier pom.xml. Vous aurez besoin du starter web ainsi que du connecteur spécifique pour Milvus fourni par Spring AI.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-milvus-store-spring-boot-starter</artifactId>
        <version>1.0.0-M1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Infrastructure : Déploiement de Milvus

Milvus agit comme le cerveau de stockage pour nos vecteurs. Utilisez Docker pour instancier rapidement un serveur local :

docker run -d --name milvus-standalone \
  -p 19530:19530 \
  -p 9091:9091 \
  milvusdb/milvus:latest

Ensuite, définissez les paramètres de connexion dans le fichier application.yml de votre projet Spring Boot :

spring:
  ai:
    vectorstore:
      milvus:
        client:
          host: localhost
          port: 19530
        collection-name: base_connaissance
        embedding-dimension: 1536

Architecture du service de recherche

La logique métier repose sur l'interface VectorStore. Nous allons créer un composant capable d'indexer des documents et d'intreroger la base vectorielle pour trouver les segments de texte les plus pertinents par rapport à une requête utiilsateur.

@Service
public class MoteurRechercheService {

    private final VectorStore magasinVecteurs;

    public MoteurRechercheService(VectorStore magasinVecteurs) {
        this.magasinVecteurs = magasinVecteurs;
    }

    public List<String> recupererContextes(String requeteUtilisateur) {
        // Recherche par similarité avec un seuil de pertinence
        SearchRequest requeteSearch = SearchRequest.query(requeteUtilisateur)
                .withTopK(3)
                .withSimilarityThreshold(0.7);

        return magasinVecteurs.similaritySearch(requeteSearch)
                .stream()
                .map(Document::getContent)
                .toList();
    }

    public void indexerDonnees(List<Document> documents) {
        magasinVecteurs.add(documents);
    }
}

Exposition via une API REST

Pour interagir avec notre système, nous implémentons un contrôleur simple qui reçoit les interrogations et retourne les fragments de connaissances identifiés par l'IA.

@RestController
@RequestMapping("/api/ia")
public class AssistantController {

    private final MoteurRechercheService rechercheService;

    public AssistantController(MoteurRechercheService rechercheService) {
        this.rechercheService = rechercheService;
    }

    @GetMapping("/demander")
    public ResponseEntity<List<String>> poserQuestion(@RequestParam String texte) {
        var resultats = rechercheService.recupererContextes(texte);
        if (resultats.isEmpty()) {
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(resultats);
    }
}

Optimisation des performances

Lors de la phase d'implémentation, il est crucial de configurer correctement le modèle d'embedding (comme OpenAI, Ollama ou HuggingFace). La dimension spécifiée dans la configuration Milvus doit impérativement correspondre à la sortie du modèle sélectionné. Pour améliorer la précision, l'ajustement du paramètre TopK permet de contrôler la quantité de contexte fournie au LLM final.

Étiquettes: spring-boot Spring-AI Milvus vector-database rag

Publié le 4 septembre à 20h00