Cet article vous expliquera comment intégrer les API d’OpenAI, telles que ChatGPT, dans votre application Spring Boot. Nous aborderons les demandes de modération, l’intégration d’embeddings et les demandes de complétion de chat. Ce contenu fait partie de notre série sur la création d’un chatbot IA en Java.

Conditions préalables

Ce tutoriel suppose que vous avez déjà une application Spring Boot. Le projet exemple que nous allons utiliser est une application Spring Boot avec un front-end React créé avec Hilla. Si vous devez mettre en place une nouvelle application, suivez les instructions fournies dans la documentation de Hilla.

Pour gérer les réponses en streaming, ajoutez la dépendance suivante au fichier pom.xml :

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webfluxartifactId>
dependency>

Obtenir une clé API OpenAI

Pour utiliser les API d’OpenAI, vous devez disposer d’une clé API. Si vous n’en avez pas, vous pouvez en créer une sur la page de la plateforme OpenAI. Enregistrez cette clé en tant que variable d’environnement, OPENAI_API_KEY. Selon vos besoins, vous pouvez le faire dans votre IDE ou à l’échelle du système.

Création d’une classe de service pour les appels OpenAI

Tout le code pour interagir avec OpenAI sera contenu dans une classe de service Spring que nous pouvons utiliser à travers notre application. Créez une nouvelle classe, OpenAIService.java :

@Service
public class OpenAIService {

    private static final String OPENAI_API_URL = "https://api.openai.com";

    @Value("${openai.api.key}")
    private String OPENAI_API_KEY;

}

Nous injectons la variable d’environnement de la clé API dans notre classe de service avec l’annotation @Value.

Configuration de Spring WebClient pour les appels API OpenAI

Ensuite, nous allons utiliser Spring WebClient pour effectuer des appels de service REST vers l’API OpenAI :

private WebClient webClient;

@PostConstruct
void init() {
    var client = HttpClient.create().responseTimeout(Duration.ofSeconds(45));
    this.webClient = WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(client))
            .baseUrl(OPENAI_API_URL)
            .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
            .defaultHeader("Authorization", "Bearer " + OPENAI_API_KEY)
            .build();
}

Modération avec ChatGPT

Le premier type de demande que nous allons traiter est la modération, utilisée pour filtrer les messages pour contenus violant les conditions d’OpenAI :

public Mono<Boolean> moderate(List<ChatCompletionMessage> messages) {
    return Flux.fromIterable(messages)
            .flatMap(this::sendModerationRequest)
            .collectList()
            .map(moderationResponses -> {
                boolean hasFlaggedContent = moderationResponses.stream()
                        .anyMatch(response -> response.getResults().get(0).isFlagged());
                return !hasFlaggedContent;
            });
}

@RegisterReflectionForBinding({ModerationRequest.class, ModerationResponse.class})
private Mono<ModerationResponse> sendModerationRequest(ChatCompletionMessage message) {
    return webClient.post()
            .uri("/v1/moderations")
            .bodyValue(new ModerationRequest(message.getContent()))
            .retrieve()
            .bodyToMono(ModerationResponse.class);
}

Ces méthodes modèrent l’ensemble de l’historique de chat en envoyant chaque ChatCompletionMessage à l’API de modération. Si un message est signalé, il retourne false. Vous pouvez trouver toutes les classes Java utilisées dans ces requêtes et réponses dans le dépôt GitHub du projet.

Génération de vecteurs d’embedding

Le deuxième type de demande que nous allons traiter est celui qui permet de récupérer un vecteur d’embedding pour un texte donné. Ce vecteur d’embedding est utilisé pour des recherches de similarité. Voici comment l’implémenter :

public Mono<List<Double>> createEmbedding(String text) {

    Map<String, Object= Map.of("model", "text-embedding-ada-002", "input", text);

    return webClient.post.uri("/v1/embeddings").bodyValue(body).retrieve.bodyToMono(EmbeddingResponse.class).map(EmbeddingResponse::getEmbedding);
}

Cette méthode appelle l’API d’embeddings et retourne un vecteur de valeurs doubles que nous pouvons utiliser pour effectuer une recherche de similarité dans une base de données vectorielle.

Streaming des réponses de ChatGPT

Le dernier type de demande consiste à appeler l’API de complétion de chat, alias ChatGPT. Pour gérer des temps de réponse potentiellement longs, nous allons streamer la réponse de l’API et afficher la réponse au fur et à mesure qu’elle est générée :

public Flux<StringgenerateCompletionStream(List<ChatCompletionMessage) {

    return webClient
            .post()
            .uri("/v1/chat/completions")
            .bodyValue(Map.of(
                    "model", "gpt-3.5-turbo", "messages", messages,"stream", true
            ))
            .retrieve.bodyToFlux(ChatCompletionChunkResponse.class)
            .onErrorResume(error -> {
                if (error.getMessage().contains"JsonToken.START_ARRAY")) {
                    return Flux.empty();
                }
                else {
                    return Flux.error(error);
                }
            })
            .filter(response -> {
                var content = response.getChoices().get(0).getDelta().getContent();
                return content != null && !content.equals("\n\n");
            })
            .map(response -> response.getChoices().get(0).getDelta().getContent());
}

Le code source de l’application complète est disponible sur GitHub.

Et ensuite ?

Dans la prochaine partie de notre série sur la création d’un chatbot IA en Java, nous discuterons de l’utilisation d’une base de données de vecteurs Pinecone avec Spring Boot.

Notre Point de vue

La montée en puissance des chatbots alimentés par l’IA, tels que ceux basés sur les API d’OpenAI, pose des défis mais aussi des opportunités considérables pour les développeurs et les entreprises. À mesure que la technologie progresse, il est essentiel d’adopter ces outils avec discernement, en s’assurant qu’ils respectent les normes éthiques et juridiques. En tant qu’experts, notre responsabilité est de guider les utilisateurs vers une utilisation responsable et d’assurer la transparence. L’innovation dans ce domaine pourrait transformer notre façon d’interagir avec la technologie, et il est crucial de naviguer dans cette évolution avec prudence et équité.



  • Source image(s) : vaadin.com
  • Source : https://vaadin.com/blog/ai-chatbot-in-java/calling-chatgpt-and-openai-apis-in-spring-boot

Publications similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *