Gestion d'une application Java alimentée par l'IA avec API Management

Bobur Umurzokov

Bobur Umurzokov

June 22, 2023

Technology

Dans cet article, nous allons explorer comment intégrer l'API ChatGPT d'OpenAI avec une application Spring Boot et gérer les API à l'aide d'Apache APISIX, un passerelle API open-source. Cette intégration nous permettra de tirer parti de la puissance de ChatGPT, un modèle de langage de pointe développé par OpenAI, dans notre application Spring Boot, tandis qu'APISIX fournira une manière robuste, évolutive et sécurisée de gérer les API.

API ChatGPT d'OpenAI

L'API ChatGPT d'OpenAI est un outil puissant que nous pouvons utiliser pour intégrer les capacités du modèle ChatGPT dans nos propres applications ou services. L'API nous permet d'envoyer une série de messages et de recevoir une réponse générée par un modèle d'IA via REST. Elle propose un ensemble d'API pour créer des réponses textuelles dans un chatbot, compléter du code, générer des images ou répondre à des questions dans une interface conversationnelle. Dans ce tutoriel, nous utiliserons l'API de complétion de chat pour générer des réponses à une invite (en gros, nous pouvons poser n'importe quelle question). Avant de commencer le tutoriel, vous pouvez explorer l'API pour comprendre comment s'authentifier à l'API à l'aide de clés API, à quoi ressemblent les paramètres de requête et la réponse de l'API.

Un exemple de requête cURL à l'API de complétion de chat ressemblerait à ceci. Vous remplacez OPENAI_API_KEY par votre propre clé API et la placez dans l'en-tête Authorization lors de l'appel de l'API.

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "What is Apache APISIX?"}]
}'

Voici un exemple de réponse JSON :

{
  "id": "chatcmpl-7PtycrYOTJGv4jw8FQPD7LCCw0tOE",
  "object": "chat.completion",
  "created": 1686407730,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 104,
    "total_tokens": 119
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Apache APISIX est une passerelle API dynamique, en temps réel et haute performance conçue pour faciliter la gestion et le routage des microservices et des API. Elle fournit des fonctionnalités telles que l'équilibrage de charge, la limitation de débit, l'authentification, l'autorisation et le contrôle du trafic, qui aident à simplifier la gestion des microservices et des API. Apache APISIX est construit sur le serveur Nginx et peut supporter des niveaux élevés de trafic avec une faible latence et une haute disponibilité. Il est open source et publié sous la licence Apache 2.0."
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}

Exemple de code du projet

Le tutoriel se compose de deux parties. La première partie couvre la configuration de l'application Spring Boot et la création d'un nouveau point de terminaison API qui peut gérer nos appels API à l'API de complétion de chat de manière programmatique. Dans la deuxième partie, nous introduirons les fonctionnalités d'APISIX telles que la sécurité et le contrôle du trafic à l'API Spring Boot. Les exemples de code complets pour ce tutoriel sont disponibles sur le dépôt GitHub appelé apisix-java-chatgpt-openaiapi.

Prérequis

Avant de commencer, assurez-vous d'avoir les éléments suivants :

  • Créez une clé API OpenAI : Pour accéder à l'API OpenAI, vous devrez créer une clé API. Vous pouvez le faire en vous connectant au site web d'OpenAI et en naviguant vers la page de gestion des clés API.
  • Docker est installé sur votre machine pour exécuter APISIX et Spring Boot.

Étape 1 : Configuration de votre application Spring Boot

Tout d'abord, nous devons configurer une nouvelle application Spring Boot. Vous pouvez utiliser Spring Initializr pour générer un nouveau projet Maven avec les dépendances nécessaires. Pour ce tutoriel, nous aurons besoin de la dépendance Spring Boot Starter Web. Pour intégrer l'API ChatGPT, nous utiliserons le client Java OpenAI. Il existe une bibliothèque communautaire open-source appelée https://github.com/TheoKanning/openai-java. Elle fournit des classes de service qui créent et appellent le client des API GPT d'OpenAI en Java. Bien sûr, vous pouvez également écrire votre propre implémentation dans Spring qui interagit avec les API OpenAI. Voir d'autres bibliothèques clientes pour différents langages de programmation.

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.theokanning.openai-gpt3-java</groupId>
            <artifactId>service</artifactId>
            <version>0.12.0</version>
        </dependency>
</dependencies>

Étape 2 : Créer une classe Controller

Dans la classe ChatCompletionController.java, vous pouvez utiliser le service OpenAI pour envoyer une requête à l'API ChatGPT.

import com.theokanning.openai.completion.chat.ChatCompletionChoice;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatMessage;
import com.theokanning.openai.completion.chat.ChatMessageRole;
import com.theokanning.openai.service.OpenAiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class ChatCompletionController {

    @Value("${openai.model}")
    private String model;

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

    @PostMapping("/ai-chat")
    public String chat(@RequestBody String prompt) {
        OpenAiService service = new OpenAiService(openaiApiKey);

        final List<ChatMessage> messages = new ArrayList<>();
        final ChatMessage systemMessage = new ChatMessage(
       ChatMessageRole.USER.value(), prompt);
        messages.add(systemMessage);

        ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest
            .builder()
            .model(model)
            .messages(messages)
            .maxTokens(250)
            .build();

        List<ChatCompletionChoice> choices = service
      .createChatCompletion(chatCompletionRequest).getChoices();

        if (choices == null || choices.isEmpty()) {
            return "No response";
        }

        return choices.get(0).getMessage().getContent();
    }
}

Le point de terminaison API /ai-chat gère les requêtes POST, crée une requête de chat et l'envoie à l'API OpenAI. Ensuite, il renvoie le premier message de la réponse de l'API.

Étape 3 : Définir les propriétés de l'application

Ensuite, nous fournissons les propriétés pour l'API comme model et clé API dans le fichier application.properties :

openai.model=gpt-3.5-turbo
openai.api.key=YOUR_OPENAI_API_TOKEN

Étape 4 : Exécuter l'application Spring Boot

Nous pouvons maintenant exécuter Application.java et la tester avec Postman ou la commande cURL.

Réponse IA de Spring Boot

Comme nous pouvons le voir, l'application a généré une réponse à notre question dans le corps de la requête d'invite.

Étape 5 : Créer un Dockerfile

Nous utilisons un conteneur Docker pour encapsuler notre application Spring Boot et l'utiliser avec d'autres conteneurs APISIX dans docker-compose.yml. Pour ce faire, nous pouvons créer un Dockerfile pour construire un JAR et l'exécuter. Voir le tutoriel sur la dockerisation d'une application Spring Boot. Ensuite, enregistrez le service dans le fichier yaml de docker compose.

openaiapi:
    build: openaiapi
    ports:
      - "8080:8080"
    networks:
      apisix:

Étape 6 : Configuration d'Apache APISIX

Pour configurer APISIX, nous pouvons simplement exécuter la commande docker compose up. Parce que nous avons déjà défini tous les services nécessaires dans docker-compose.yml. Ce fichier définit seulement 2 conteneurs, un pour APISIX et un autre pour l'application Spring Boot que nous avons implémentée dans les étapes précédentes. Dans ce projet d'exemple, nous exécutons APISIX en mode autonome. Il existe d'autres options d'installation et modes de déploiement pour APISIX. Maintenant, APISIX en tant que service séparé fonctionne sur localhost:9080 et l'application Spring Boot sur localhost:8080

Étape 7 : Sécuriser l'API avec APISIX

Une fois APISIX configuré, nous pouvons ajouter des fonctionnalités de sécurité à notre API Spring Boot existante /ai-chat afin que seuls les consommateurs d'API autorisés puissent accéder à cette API. APISIX fournit plusieurs plugins pour sécuriser vos API. Par exemple, vous pouvez utiliser le plugin jwt-auth pour exiger un jeton JWT pour toutes les requêtes. Voici un exemple de comment ajouter une route avec un upstream et des plugins en utilisant le fichier apisix.yml :

upstreams:
  - id: 1
    type: roundrobin
    nodes:
      "openaiapi:8080": 1
routes:
  - uri: /ask-me-anything
    upstream_id: 1
    plugins:
      proxy-rewrite:
        uri: /ai-chat
      jwt-auth: {}
  - uri: /login
    plugins:
      public-api:
        uri: /apisix/plugin/jwt/sign
consumers:
  - username: appsmithuser
    plugins:
        jwt-auth:
            key: appsmithuser@gmail.com
            secret: my-secret-key

Après avoir spécifié les upstreams, les routes et les objets consommateurs ainsi que les règles de routage dans la configuration d'APISIX, le fichier de configuration est chargé en mémoire immédiatement après le démarrage du service de nœud APISIX dans Docker. Apisix essaie périodiquement de détecter si le contenu du fichier est mis à jour, s'il y a une mise à jour, il recharge automatiquement les changements.

Avec cette configuration, nous avons ajouté un upstream, deux routes et un objet consommateur. Dans la première route, toutes les requêtes à /ask-me-anything (qui est un chemin d'URI personnalisé, vous pouvez définir n'importe quel URI ici) doivent inclure l'en-tête Authorization: JWT_TOKEN. Ensuite, APISIX réécrit le chemin d'URI personnalisé vers l'API réelle /ai-chat automatiquement à l'aide du plugin proxy-rewrite et transfère les requêtes à l'application Spring Boot fonctionnant sur localhost:8080.

Si vous essayez de demander la route APISIX, elle rejettera nos requêtes en renvoyant une erreur d'autorisation :

curl -i http://localhost:9080/ask-me-anything -X POST -d '
{
   "prompt":"What is Apache APISIX?"
}'

Le résultat de la requête ci-dessus :

HTTP/1.1 401 Unauthorized
{"message":"Missing JWT token in request"}

Dans la deuxième configuration de route, nous avons activé le plugin public-api pour exposer un nouveau point de terminaison /login pour signer de nouveaux jetons JWT. Parce qu'APISIX peut agir comme un fournisseur d'identité pour générer et valider un nouveau jeton pour le consommateur d'API ou les applications clientes. Voir Étape 8, comment nous réclamons un nouveau jeton pour notre consommateur d'API.

  - uri: /login
    plugins:
      public-api:
        uri: /apisix/plugin/jwt/sign

Si vous avez remarqué dans le même fichier de configuration, nous avons enregistré un consommateur d'API pour utiliser l'API /ask-me-anything alimentée par l'IA et nos utilisateurs peuvent réclamer APISIX en utilisant leur secret pour générer un jeton JWT pour accéder à l'API :

consumers:
  - username: appsmithuser
    plugins:
        jwt-auth:
            key: appsmithuser@gmail.com
            secret: my-secret-key

Étape 8 : Réclamer un nouveau jeton JWT

Maintenant, nous pouvons réclamer un nouveau jeton JWT pour notre consommateur d'API existant avec la clé :

curl -i http://127.0.0.1:9080/login?key=user-key -i

Nous obtiendrons le nouveau jeton en réponse d'APISIX :

Server: APISIX/3.0.0
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTY4NjU5MjE0NH0.4Kn9c2DBYKthyUx824Ah97-z0Eu2Ul9WGO2WB3IfURA

Étape 9 : Demander l'API avec le jeton JWT

Enfin, nous pouvons envoyer une requête à l'API /ask-me-anything avec le jeton JWT dans l'en-tête que nous avons obtenu à l'étape précédente.

curl -i http://localhost:9080/ask-me-anything -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTY4NjU5Mjk4N30.lhom9db3XMkcVd86ScpM6s4eP1_YzR-tfmXPckszsYo' -X POST -d '
{
   "prompt":"What is Apache APISIX?"
}'

Ou en utilisant Postman, nous obtiendrons une réponse IA mais cette fois la réponse passe par la passerelle APISIX :

Réponse IA d'APISIX

Conclusion

Dans ce tutoriel, nous avons exploré l'API ChatGPT d'OpenAI pour générer des réponses à des invites. Nous avons créé une application Spring Boot qui appelle l'API pour générer des réponses à des invites. Ensuite, vous pouvez introduire des fonctionnalités supplémentaires à votre intégration en mettant à jour le fichier apisix.yml existant. Vous pouvez également consulter la branche appelée with-frontend et exécuter le projet pour voir l'interface utilisateur construite avec Appsmith qui fonctionne avec APISIX.

Ressources connexes

Contenu recommandé

Tags: