Verwaltung einer KI-gestützten Java-App mit API Management

In diesem Artikel werden wir untersuchen, wie man OpenAI's ChatGPT API mit einer Spring Boot-Anwendung integriert und die APIs mit Apache APISIX, einem Open-Source-API-Gateway, verwaltet. Diese Integration ermöglicht es uns, die Leistungsfähigkeit von ChatGPT, einem modernen Sprachmodell von OpenAI, in unserer Spring Boot-Anwendung zu nutzen, während APISIX eine robuste, skalierbare und sichere Möglichkeit bietet, die APIs zu verwalten.

OpenAI ChatGPT APIs

OpenAI's ChatGPT API ist ein leistungsstarkes Tool, das wir verwenden können, um die Fähigkeiten des ChatGPT-Modells in unsere eigenen Anwendungen oder Dienste zu integrieren. Die API ermöglicht es uns, eine Reihe von Nachrichten zu senden und eine vom KI-Modell generierte Antwort über REST zu erhalten. Sie bietet eine Vielzahl von APIs, um Textantworten in einem Chatbot zu erstellen, Code zu vervollständigen, Bilder zu generieren oder Fragen in einer Konversationsschnittstelle zu beantworten. In diesem Tutorial werden wir die Chat Completion API verwenden, um Antworten auf eine Eingabeaufforderung zu generieren (im Grunde können wir alles fragen). Bevor wir mit dem Tutorial beginnen, können Sie die API erkunden, um ein Verständnis dafür zu bekommen, wie man sich bei der API authentifiziert und wie API-Anfrageparameter und -Antworten aussehen.

Eine Beispiel-cURL-Anfrage an die Chat Completion API würde so aussehen. Sie ersetzen OPENAI_API_KEY durch Ihren eigenen API-Schlüssel und platzieren ihn im Authorization-Header, wenn Sie die API aufrufen.

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?"}]
}'

Hier ist eine Beispiel-JSON-Antwort:

{
  "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 ist ein dynamisches, Echtzeit-, Hochleistungs-API-Gateway, das entwickelt wurde, um das Management und Routing von Microservices und APIs zu erleichtern. Es bietet Funktionen wie Lastenausgleich, Ratenbegrenzung, Authentifizierung, Autorisierung und Verkehrskontrolle, die alle dazu beitragen, das Management von Microservices und APIs zu vereinfachen. Apache APISIX basiert auf dem Nginx-Server und kann hohe Verkehrslasten mit geringer Latenz und hoher Verfügbarkeit unterstützen. Es ist Open Source und unter der Apache 2.0-Lizenz veröffentlicht."
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}

Projektcode-Beispiel

Das Tutorial besteht aus zwei Teilen. Der erste Teil behandelt die Einrichtung der Spring Boot-Anwendung und die Erstellung eines neuen API-Endpunkts, der unsere API-Aufrufe an die Chat Completion API programmatisch verarbeiten kann. Im zweiten Teil werden wir APISIX-Funktionen wie Sicherheit und Verkehrskontrolle in die Spring Boot-API einführen. Die vollständigen Codebeispiele für dieses Tutorial sind im GitHub-Repository apisix-java-chatgpt-openaiapi verfügbar.

Voraussetzungen

Bevor wir beginnen, stellen Sie sicher, dass Sie Folgendes haben:

  • Erstellen Sie einen OpenAI API-Schlüssel: Um auf die OpenAI API zugreifen zu können, müssen Sie einen API-Schlüssel erstellen. Dies können Sie tun, indem Sie sich auf der OpenAI-Website anmelden und zur API-Schlüsselverwaltungsseite navigieren.
  • Docker ist auf Ihrem Computer installiert, um APISIX und Spring Boot auszuführen.

Schritt 1: Einrichten Ihrer Spring Boot-Anwendung

Zuerst müssen wir eine neue Spring Boot-Anwendung einrichten. Sie können Spring Initializr verwenden, um ein neues Maven-Projekt mit den notwendigen Abhängigkeiten zu generieren. Für dieses Tutorial benötigen wir die Spring Boot Starter Web-Abhängigkeit. Um die ChatGPT API zu integrieren, verwenden wir den OpenAI Java-Client. Es gibt eine Open-Source-Community-Bibliothek namens https://github.com/TheoKanning/openai-java. Sie stellt Dienstklassen bereit, die den OpenAI GPT API-Client in Java erstellen und aufrufen. Natürlich können Sie auch Ihre eigene Implementierung in Spring schreiben, die mit den OpenAI APIs interagiert. Siehe andere Client-Bibliotheken für verschiedene Programmiersprachen.

<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>

Schritt 2: Erstellen einer Controller-Klasse

In der ChatCompletionController.java-Klasse können Sie den OpenAI-Dienst verwenden, um eine Anfrage an die ChatGPT API zu senden.

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();
    }
}

Der Chat-API-Endpunkt /ai-chat verarbeitet POST-Anfragen, erstellt eine Chat-Anfrage und sendet sie an die OpenAI API. Dann gibt er die erste Nachricht aus der API-Antwort zurück.

Schritt 3: Anwendungseigenschaften definieren

Als Nächstes geben wir die Eigenschaften für die API wie model und API-Schlüssel in der Datei application.properties an:

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

Schritt 4: Spring Boot-App ausführen

Wir können jetzt die Application.java ausführen und sie mit Postman oder dem cURL-Befehl testen.

AI-Antwort von Spring Boot

Wie wir sehen können, hat die Anwendung eine Antwort auf unsere Frage in der Eingabeaufforderung generiert.

Schritt 5: Erstellen eines Dockerfiles

Wir verwenden einen Docker-Container, um unsere Spring Boot-Anwendung zu verpacken und sie zusammen mit anderen APISIX-Containern in docker-compose.yml zu verwenden. Dazu können wir ein Dockerfile erstellen, um ein JAR zu erstellen und auszuführen. Siehe das Tutorial zum Dockerisieren einer Spring Boot-App. Dann registrieren wir den Dienst in der Docker Compose YAML-Datei.

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

Schritt 6: Einrichten von Apache APISIX

Um APISIX einzurichten, können wir einfach den Befehl docker compose up ausführen. Da wir bereits alle notwendigen Dienste in docker-compose.yml definiert haben. Diese Datei definiert nur 2 Container, einen für APISIX und einen für die Spring Boot-Anwendung, die wir in den vorherigen Schritten implementiert haben. In diesem Beispielprojekt führen wir APISIX im Standalone-Modus aus. Es gibt auch andere Installationsoptionen und Bereitstellungsmodi für APISIX. Jetzt läuft APISIX als separater Dienst auf localhost:9080 und die Spring Boot-App auf localhost:8080.

Schritt 7: Absichern der API mit APISIX

Sobald APISIX eingerichtet ist, können wir Sicherheitsfunktionen zu unserer bestehenden Spring Boot-API /ai-chat hinzufügen, sodass nur berechtigte API-Konsumenten auf diese API zugreifen können. APISIX bietet mehrere Plugins, um Ihre APIs abzusichern. Zum Beispiel können Sie das jwt-auth-Plugin verwenden, um ein JWT-Token für alle Anfragen zu verlangen. Hier ist ein Beispiel, wie Sie eine Route mit einem Upstream und Plugins mithilfe der apisix.yml-Datei hinzufügen können:

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

Nachdem wir Upstreams, Routen und Consumer-Objekte sowie Routing-Regeln in der APISIX-Konfiguration angegeben haben, wird die Konfigurationsdatei unmittelbar nach dem Start des APISIX-Node-Dienstes in Docker in den Speicher geladen. APISIX versucht regelmäßig, festzustellen, ob der Dateiinhalt aktualisiert wurde, und wenn es eine Aktualisierung gibt, werden die Änderungen automatisch neu geladen.

Mit dieser Konfiguration haben wir einen Upstream, zwei Routen und ein Consumer-Objekt hinzugefügt. In der ersten Route müssen alle Anfragen an /ask-me-anything (was ein benutzerdefinierter URI-Pfad ist, Sie können dort jeden URI definieren) den Authorization: JWT_TOKEN im Header enthalten. Dann schreibt APISIX den benutzerdefinierten URI-Pfad automatisch mit Hilfe des proxy-rewrite-Plugins in den tatsächlichen API-Pfad /ai-chat um und leitet die Anfragen an die Spring Boot-Anwendung weiter, die auf localhost:8080 läuft.

Wenn Sie versuchen, die APISIX-Route anzufordern, wird sie unsere Anfragen ablehnen, indem sie einen Autorisierungsfehler zurückgibt:

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

Das Ergebnis der obigen Anfrage:

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

In der zweiten Routenkonfiguration haben wir das public-api-Plugin aktiviert, um einen neuen Endpunkt /login freizugeben, um neue JWT-Token zu signieren. Da APISIX als Identitätsanbieter fungieren kann, um neue Token für API-Konsumenten oder Client-Apps zu generieren und zu validieren. Siehe Schritt 8, wie wir ein neues Token für unseren API-Konsumenten beanspruchen.

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

Wenn Sie in derselben Konfigurationsdatei bemerkt haben, haben wir einen API-Konsumenten registriert, um die /ask-me-anything-API zu verwenden, und unsere Benutzer können APISIX mit ihrem Geheimnis verwenden, um ein JWT-Token zu generieren und auf die API zuzugreifen:

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

Schritt 8: Ein neues JWT-Token beanspruchen

Jetzt können wir ein neues JWT-Token für unseren bestehenden API-Konsumenten mit dem Schlüssel beanspruchen:

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

Wir erhalten das neue Token als Antwort von APISIX:

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

Schritt 9: Anfrage an die API mit dem JWT-Token

Schließlich können wir eine Anfrage an die API /ask-me-anything mit dem JWT-Token im Header senden, den wir im vorherigen Schritt erhalten haben.

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

Oder mit Postman erhalten wir die KI-Antwort, aber diesmal kommt die Antwort über das APISIX-Gateway:

AI-Antwort von APISIX

Fazit

In diesem Tutorial haben wir die OpenAI ChatGPT API untersucht, um Antworten auf Eingabeaufforderungen zu generieren. Wir haben eine Spring Boot-Anwendung erstellt, die die API aufruft, um Antworten auf Eingabeaufforderungen zu generieren. Als Nächstes können Sie zusätzliche Funktionen zu Ihrer Integration hinzufügen, indem Sie die bestehende apisix.yml-Datei aktualisieren. Außerdem können Sie den Branch namens with-frontend auschecken und das Projekt ausführen, um die mit Appsmith erstellte Benutzeroberfläche zu sehen, die mit APISIX arbeitet.

Verwandte Ressourcen

Empfohlene Inhalte

Share article link