Imaginez que vous faites des achats en ligne et que vous tombez sur un produit que vous aimez mais dont vous ne connaissez pas le nom. Ne serait-il pas génial de télécharger une photo et que l'application la trouve pour vous ?
Dans cet article, nous allons vous montrer comment créer exactement cela : une fonctionnalité de recherche de produits basée sur des images à l'aide de Spring Boot et de Google Cloud Vertex AI.
Cette fonctionnalité permet aux utilisateurs de télécharger une image et de recevoir une liste de produits qui lui correspondent, ce qui rend l'expérience de recherche plus intuitive et visuelle.
La fonctionnalité de recherche de produits basée sur des images exploite Google Cloud Vertex AI pour traiter les images et extraire des mots-clés pertinents. Ces mots-clés sont ensuite utilisés pour rechercher les produits correspondants dans la base de données.
Nous allons parcourir le processus de configuration de cette fonctionnalité étape par étape.
Tout d'abord, nous devons créer un nouveau projet sur Google Console pour cela.
Nous devons aller sur https://console.cloud.google.com et créer un nouveau compte si vous en avez déjà un. Si vous en avez un, connectez-vous au compte.
Si vous ajoutez votre compte bancaire, Google Cloud vous proposera un essai gratuit.
Une fois que vous avez créé un compte ou connecté à un compte déjà existant, vous pouvez créer un nouveau projet.
Dans la barre de recherche, nous devons trouver Vertex AI et activer toutes les API recommandées.
Vertex AI est la plate-forme de machine learning (ML) entièrement gérée de Google Cloud, conçue pour simplifier le développement, le déploiement et la gestion des modèles de ML. Il vous permet de créer, former et déployer des modèles ML à grande échelle en fournissant des outils et des services tels qu'AutoML, la formation de modèles personnalisés, le réglage des hyperparamètres et la surveillance des modèles
Gemini 1.5 Flash fait partie de la famille de modèles Gemini de Google, spécialement conçus pour une inférence efficace et hautes performances dans les applications ML. Les modèles Gemini sont une série de modèles d'IA avancés développés par Google, souvent utilisés dans le traitement du langage naturel (NLP), les tâches de vision et d'autres applications basées sur l'IA
Remarque : Pour les autres frameworks, vous pouvez utiliser l'API Gemini directement sur https://aistudio.google.com/app/prompts/new_chat. Utilisez la fonction d'invite de structure car vous pouvez personnaliser votre sortie pour qu'elle corresponde à l'entrée afin d'obtenir de meilleurs résultats.
À cette étape, nous devons personnaliser une invite correspondant à votre candidature.
Vertex AI Studio a fourni de nombreux exemples d'invites dans la Galerie d'invites. Nous utilisons un exemple de Texte de l'image en JSON pour extraire les mots-clés liés à l'image du produit.
Mon application est un CarShop, je crée donc une invite comme celle-ci. Mon attente que le modèle me réponde avec une liste de mots clés relatifs à l'image.
Mon invite : Extrayez le nom de la voiture dans un mot-clé de liste et affichez-le en JSON. Si vous ne trouvez aucune information sur la voiture, veuillez afficher la liste vide. Exemple de réponse : ["rolls", "royce", "wraith"]
Après avoir personnalisé une invite appropriée avec votre application. Maintenant, nous allons explorer comment intégrer l'application Spring Boot.
J'ai créé une application E-commerce sur les voitures. Je veux donc trouver des voitures par l'image.
Tout d'abord, dans le fichier pom.xml, vous devez mettre à jour votre dépendance :
<!-- config version for dependency--> <properties> <spring-cloud-gcp.version>5.1.2</spring-cloud-gcp.version> <google-cloud-bom.version>26.32.0</google-cloud-bom.version> </properties> <!-- In your dependencyManagement, please add 2 dependencies below --> <dependencyManagement> <dependencies> <dependency> <groupId>com.google.cloud</groupId> <artifactId>spring-cloud-gcp-dependencies</artifactId> <version>${spring-cloud-gcp.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.google.cloud</groupId> <artifactId>libraries-bom</artifactId> <version>${google-cloud-bom.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- In your tab dependencies, please add the dependency below --> <dependencies> <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-vertexai</artifactId> </dependency> </dependencies>
Après avoir effectué la configuration dans le fichier pom.xml, vous créez une classe de configuration GeminiConfig.java
import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.generativeai.GenerativeModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) public class GeminiConfig { private static final String MODEL_NAME = "gemini-1.5-flash"; private static final String LOCATION = "asia-southeast1"; private static final String PROJECT_ID = "yasmini"; @Bean public VertexAI vertexAI() { return new VertexAI(PROJECT_ID, LOCATION); } @Bean public GenerativeModel getModel(VertexAI vertexAI) { return new GenerativeModel(MODEL_NAME, vertexAI); } }
Deuxièmement, créez les couches Service, Contrôleur pour implémenter la fonction de recherche de voiture. Créez un service de classe.
Étant donné que l'API Gemini répond au format markdown, nous devons créer une fonction pour aider à la conversion en JSON, et à partir de JSON, nous convertirons en chaîne de liste en Java.
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.cloud.vertexai.api.Content; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.api.Part; import com.google.cloud.vertexai.generativeai.*; import com.learning.yasminishop.common.entity.Product; import com.learning.yasminishop.common.exception.AppException; import com.learning.yasminishop.common.exception.ErrorCode; import com.learning.yasminishop.product.ProductRepository; import com.learning.yasminishop.product.dto.response.ProductResponse; import com.learning.yasminishop.product.mapper.ProductMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @Service @RequiredArgsConstructor @Slf4j @Transactional(readOnly = true) public class YasMiniAIService { private final GenerativeModel generativeModel; private final ProductRepository productRepository; private final ProductMapper productMapper; public List<ProductResponse> findCarByImage(MultipartFile file){ try { var prompt = "Extract the name car to a list keyword and output them in JSON. If you don't find any information about the car, please output the list empty.\nExample response: [\"rolls\", \"royce\", \"wraith\"]"; var content = this.generativeModel.generateContent( ContentMaker.fromMultiModalData( PartMaker.fromMimeTypeAndData(Objects.requireNonNull(file.getContentType()), file.getBytes()), prompt ) ); String jsonContent = ResponseHandler.getText(content); log.info("Extracted keywords from image: {}", jsonContent); List<String> keywords = convertJsonToList(jsonContent).stream() .map(String::toLowerCase) .toList(); Set<Product> results = new HashSet<>(); for (String keyword : keywords) { List<Product> products = productRepository.searchByKeyword(keyword); results.addAll(products); } return results.stream() .map(productMapper::toProductResponse) .toList(); } catch (Exception e) { log.error("Error finding car by image", e); return List.of(); } } private List<String> convertJsonToList(String markdown) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String parseJson = markdown; if(markdown.contains("``` json")){ parseJson = extractJsonFromMarkdown(markdown); } return objectMapper.readValue(parseJson, List.class); } private String extractJsonFromMarkdown(String markdown) { return markdown.replace(" ```json\n", "").replace("\n``` ", ""); } }
Nous devons créer une classe de contrôleur pour créer un point de terminaison pour le front-end
import com.learning.yasminishop.product.dto.response.ProductResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @RestController @RequestMapping("/ai") @RequiredArgsConstructor @Slf4j public class YasMiniAIController { private final YasMiniAIService yasMiniAIService; @PostMapping public List<ProductResponse> findCar(@RequestParam("file") MultipartFile file) { var response = yasMiniAIService.findCarByImage(file); return response; } }
L'application Spring Boot ne peut pas vérifier qui vous êtes et ne peut pas vous permettre d'accepter la ressource dans Google Cloud.
Nous devons donc nous connecter à Google et fournir une autorisation.
Tutoriel de lien : https://cloud.google.com/sdk/docs/install
Vérifiez le lien ci-dessus et installez-le sur votre machine
gcloud auth login
Remarque : Une fois connecté, les informations d'identification sont enregistrées dans le package Google Maven et vous n'avez pas besoin de vous reconnecter lorsque vous redémarrez l'application Spring Boot.
Donc, ceux-ci sont implémentés ci-dessus en fonction de mon projet E-commerce, vous pouvez modifier la correspondance avec votre projet et votre framework. Dans d'autres frameworks, pas Spring Boot (NestJs, ..), vous pouvez utiliser https://aistudio.google.com/app/prompts/new_chat. et vous n'avez pas besoin de créer un nouveau compte Google Cloud.
Vous pouvez vérifier la mise en œuvre détaillée sur mon dépôt :
Backend : https://github.com/duongminhhieu/YasMiniShop
Front-end : https://github.com/duongminhhieu/YasMini-Frontend
Bon apprentissage !!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!