Управление Java-приложением с поддержкой AI с помощью API Management
June 22, 2023
В этой статье мы рассмотрим, как интегрировать API ChatGPT от OpenAI с приложением на Spring Boot и управлять API с помощью Apache APISIX, открытого API-шлюза. Эта интеграция позволит нам использовать возможности ChatGPT, передовой языковой модели, разработанной OpenAI, в нашем приложении на Spring Boot, а APISIX предоставит надежный, масштабируемый и безопасный способ управления API.
API ChatGPT от OpenAI
API ChatGPT от OpenAI — это мощный инструмент, который мы можем использовать для интеграции возможностей модели ChatGPT в наши собственные приложения или сервисы. API позволяет отправлять серию сообщений и получать ответ, сгенерированный моделью ИИ, через REST. Он предлагает множество API для создания текстовых ответов в чат-боте, завершения кода, генерации изображений или ответов на вопросы в диалоговом интерфейсе. В этом руководстве мы будем использовать API завершения чата для генерации ответов на запрос (по сути, мы можем задать любой вопрос). Прежде чем приступить к руководству, вы можете изучить API, чтобы понять, как аутентифицироваться в API с использованием API-ключей, как выглядят параметры запроса и ответа API.
Пример cURL-запроса к API завершения чата будет выглядеть так. Вы заменяете OPENAI_API_KEY на свой собственный API-ключ и помещаете его в заголовок Authorization при вызове 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?"}] }'
Пример 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 — это динамический, высокопроизводительный API-шлюз, предназначенный для управления и маршрутизации микросервисов и API. Он предоставляет такие функции, как балансировка нагрузки, ограничение скорости, аутентификация, авторизация и управление трафиком, что упрощает управление микросервисами и API. Apache APISIX построен на основе сервера Nginx и может поддерживать высокие уровни трафика с низкой задержкой и высокой доступностью. Он является открытым исходным кодом и выпущен под лицензией Apache 2.0." }, "finish_reason": "stop", "index": 0 } ] }
Пример кода проекта
Руководство состоит из двух частей. В первой части рассматривается настройка приложения Spring Boot и создание нового API-эндпоинта, который может обрабатывать наши вызовы к API завершения чата программно. Во второй части мы добавим функции APISIX, такие как безопасность и управление трафиком, к API Spring Boot. Полные примеры кода для этого руководства доступны в репозитории GitHub под названием apisix-java-chatgpt-openaiapi.
Предварительные требования
Прежде чем начать, убедитесь, что у вас есть следующее:
- Создайте API-ключ OpenAI: Для доступа к API OpenAI вам нужно создать API-ключ. Это можно сделать, войдя на сайт OpenAI и перейдя на страницу управления API-ключами.
- Установите Docker на вашем компьютере для запуска APISIX и Spring Boot.
Шаг 1: Настройка приложения Spring Boot
Сначала нам нужно настроить новое приложение Spring Boot. Вы можете использовать Spring Initializr для создания нового Maven-проекта с необходимыми зависимостями. Для этого руководства нам понадобится зависимость Spring Boot Starter Web. Для интеграции API ChatGPT мы будем использовать клиент OpenAI для Java. Существует открытая библиотека сообщества под названием https://github.com/TheoKanning/openai-java. Она предоставляет сервисные классы, которые создают и вызывают клиент API GPT от OpenAI на Java. Конечно, вы можете написать свою собственную реализацию в Spring, которая взаимодействует с API OpenAI. См. другие клиентские библиотеки для различных языков программирования.
<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>
Шаг 2: Создание класса Controller
В классе ChatCompletionController.java вы можете использовать сервис OpenAI для отправки запроса к 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(); } }
API-эндпоинт /ai-chat обрабатывает POST-запросы, создает запрос на чат и отправляет его в API OpenAI. Затем он возвращает первое сообщение из ответа API.
Шаг 3: Определение свойств приложения
Далее мы предоставляем свойства для API, такие как model и API key, в файле application.properties:
openai.model=gpt-3.5-turbo openai.api.key=YOUR_OPENAI_API_TOKEN
Шаг 4: Запуск приложения Spring Boot
Теперь мы можем запустить Application.java и протестировать его с помощью Postman или команды cURL.

Как мы видим, приложение сгенерировало ответ на наш вопрос в теле запроса.
Шаг 5: Создание Dockerfile
Мы используем контейнер Docker для упаковки нашего приложения Spring Boot и используем его вместе с другими контейнерами APISIX в docker-compose.yml. Для этого мы можем создать Dockerfile для сборки JAR и его выполнения. См. руководство по dockerization приложения Spring Boot. Затем зарегистрируйте сервис в файле docker-compose yaml.
openaiapi: build: openaiapi ports: - "8080:8080" networks: apisix:
Шаг 6: Настройка Apache APISIX
Для настройки APISIX мы можем просто выполнить команду docker compose up. Поскольку мы уже определили все необходимые сервисы в docker-compose.yml. Этот файл определяет только 2 контейнера: один для APISIX, а другой для приложения Spring Boot, которое мы реализовали на предыдущих шагах. В этом примере проекта мы запускаем APISIX в автономном режиме. Существуют и другие варианты установки APISIX и режимы развертывания. Теперь APISIX как отдельный сервис работает на localhost:9080, а приложение Spring Boot — на localhost:8080.
Шаг 7: Защита API с помощью APISIX
После настройки APISIX мы можем добавить функции безопасности к нашему существующему API Spring Boot /ai-chat, чтобы только разрешенные потребители API могли получить доступ к этому API. APISIX предоставляет несколько плагинов для защиты ваших API. Например, вы можете использовать плагин jwt-auth для требования JWT-токена для всех запросов. Вот пример того, как добавить маршрут с апстримом и плагинами с использованием файла 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
После того как мы указали апстримы, маршруты и объекты потребителей, а также правила маршрутизации в конфигурации APISIX, конфигурационный файл загружается в память сразу после запуска службы узла APISIX в Docker. APISIX периодически пытается обнаружить, обновлено ли содержимое файла, и если есть обновление, он автоматически перезагружает изменения.
С этой конфигурацией мы добавили один апстрим, два маршрута и один объект потребителя. В первом маршруте все запросы к /ask-me-anything (который является пользовательским URI, вы можете определить любой URI) должны включать Authorization: JWT_TOKEN в заголовке. Затем APISIX автоматически переписывает пользовательский URI на фактический API /ai-chat с помощью плагина proxy-rewrite и перенаправляет запросы в приложение Spring Boot, работающее на localhost:8080.
Если вы попытаетесь запросить маршрут APISIX, он отклонит наши запросы, возвращая ошибку авторизации:
curl -i http://localhost:9080/ask-me-anything -X POST -d ' { "prompt":"What is Apache APISIX?" }'
Результат вышеуказанного запроса:
HTTP/1.1 401 Unauthorized {"message":"Missing JWT token in request"}
Во втором маршруте мы включили плагин public-api, чтобы открыть новый эндпоинт /login для подписи новых JWT-токенов. Поскольку APISIX может выступать в качестве поставщика идентификации для генерации и проверки нового токена от потребителя API или клиентских приложений. См. Шаг 8, как мы запрашиваем новый токен для нашего потребителя API.
- uri: /login plugins: public-api: uri: /apisix/plugin/jwt/sign
Если вы заметили, в том же конфигурационном файле мы зарегистрировали потребителя API для использования API /ask-me-anything с поддержкой ИИ, и наши пользователи могут запрашивать APISIX, используя свой секрет, чтобы сгенерировать JWT-токен для доступа к API:
consumers: - username: appsmithuser plugins: jwt-auth: key: appsmithuser@gmail.com secret: my-secret-key
Шаг 8: Запрос нового JWT-токена
Теперь мы можем запросить новый JWT-токен для нашего существующего потребителя API с ключом:
curl -i http://127.0.0.1:9080/login?key=user-key -i
Мы получим новый токен в ответе от APISIX:
Server: APISIX/3.0.0 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTY4NjU5MjE0NH0.4Kn9c2DBYKthyUx824Ah97-z0Eu2Ul9WGO2WB3IfURA
Шаг 9: Запрос API с JWT-токеном
Наконец, мы можем отправить запрос к API /ask-me-anything с JWT-токеном в заголовке, который мы получили на предыдущем шаге.
curl -i http://localhost:9080/ask-me-anything -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTY4NjU5Mjk4N30.lhom9db3XMkcVd86ScpM6s4eP1_YzR-tfmXPckszsYo' -X POST -d ' { "prompt":"What is Apache APISIX?" }'
Или с помощью Postman, мы получим ответ ИИ, но на этот раз ответ приходит через шлюз APISIX:

Заключение
В этом руководстве мы изучили API ChatGPT от OpenAI для генерации ответов на запросы. Мы создали приложение Spring Boot, которое вызывает API для генерации ответов на запросы. Далее вы можете добавить дополнительные функции к вашей интеграции, обновив существующий файл apisix.yml. Также вы можете проверить ветку под названием with-frontend и запустить проект, чтобы увидеть интерфейс, созданный с использованием Appsmith, который работает с APISIX.