Gestion d'une application Java alimentée par l'IA avec API Management
June 22, 2023
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.
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 :
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.