Интеграция OpenAI с Node.js и Express: учебник

Интеграция OpenAI с Node.js и Express: учебник

28 февраля 2023 г.

Сегодняшняя статья — первая из серии руководств, состоящей из 3–4 частей, в которой мы будем работать над созданием нашего собственного чат-бота для вопросов и ответов.

Содержание

  • Введение
  • Создание ключа API OpenAI
  • Взаимодействие с конечными точками завершения OpenAI
  • Настройка приложения Node/Express
  • Заключительные мысли

Мы достигнем нашей цели по созданию пользовательского чат-бота для вопросов и ответов:

  • Создание сервера Node/Express для взаимодействия с API OpenAI (сегодняшнее электронное письмо).
  • Использование React для создания пользовательского интерфейса нашего чат-бота для вопросов и ответов.
  • Наконец, мы рассмотрим, как настроить наше приложение, чтобы наш чат-бот для вопросов и ответов возвращал пользовательскую информацию.

Наше окончательное приложение будет выглядеть примерно так:

Сегодня мы сосредоточимся исключительно на создании сервера Node.js, где мы сможем напрямую взаимодействовать с API OpenAI. Это предшествует настройке нашего клиентского приложения, которое затем будет взаимодействовать с локальным API, который мы создадим.

Если вы хотите продолжить, вам потребуются установленные Node и NPM на вашем компьютере и ключ API OpenAI (мы покажем вам, как его получить в следующем разделе).

Создание ключа API OpenAI

Выполните следующие действия, чтобы сгенерировать ключ API с помощью OpenAI:

* Зарегистрируйте учетную запись, перейдя на веб-сайт OpenAI (https://platform.openai.com/). * После создания учетной записи посетите страницу ключей API по адресу https://platform.openai.com/account/api-keys. * Создайте новый ключ, нажав кнопку «Создать новый секретный ключ».

После создания ключа API вы сможете скопировать секретный ключ и использовать его, когда начнете разработку.

<цитата>

Примечание. В настоящее время OpenAI предоставляет бесплатные кредиты в размере 18 долларов США на 3 месяца, и это здорово, поскольку вам не нужно будет вводить свои платежные реквизиты, чтобы начать взаимодействовать с API в первый раз.

Настройка приложения Node/Express

Теперь мы перейдем к созданию нового каталога для нашего проекта Node и назовем его custom_chat_gpt.

mkdir custom_chat_gpt

Мы перейдем в новый каталог и выполним следующую команду, чтобы создать файл package.json.

npm init -y

Как только файл package.json будет создан должным образом, мы установим три зависимости, которые нам сейчас понадобятся.

npm install dotenv express openai

* dotenv: позволит нам загружать переменные среды из файла .env при локальной работе. * express: это платформа Node.js, которую мы будем использовать для запуска сервера Node. * openai: библиотека Node.js для OpenAI API.

Затем мы создадим файл с именем index.js. В файле index.js мы создадим наш сервер Node.js/Express.

В файле index.js мы:

* Включите модуль express с require("express"). * Затем мы запустим функцию express(), чтобы определить экземпляр Express и назначить его константе с меткой app. * Мы укажем промежуточное ПО в нашем экземпляре Express (с помощью app.use()), чтобы анализировать входящие запросы JSON и помещать проанализированные данные в тело req. * Мы укажем переменную port, которой будет присвоено значение из переменной среды PORT или 5000, если PORT переменная среды не определена.

const express = require("express");

const app = express();
app.use(express.json());

const port = process.env.PORT || 5000;

Затем мы настроим маршрут POST с пометкой /ask, который будет действовать как конечная точка, которую будет запускать наш клиент. В этом маршруте мы ожидаем, что значение prompt существует в теле запроса, и если его нет, мы выдадим ошибку. Если значение prompt действительно существует, мы просто вернем ответ со статусом 200, который содержит prompt в сообщении поле.

Наконец, мы запустим функцию app.listen(), чтобы наше приложение прослушивало значение порта, которое мы указали в переменной port.

const express = require("express");

const app = express();
app.use(express.json());

const port = process.env.PORT || 5000;

// POST request endpoint
app.post("/ask", async (req, res) => {
  // getting prompt question from request
  const prompt = req.body.prompt;

  try {
    if (prompt == null) {
      throw new Error("Uh oh, no prompt was provided");
    }

    // return the result
    return res.status(200).json({
      success: true,
      message: prompt,
    });
  } catch (error) {
    console.log(error.message);
  }
});

app.listen(port, () => console.log(`Server is running on port ${port}!!`));

Когда это изменение сохранено, самое время проверить, работают ли наши изменения. Мы запустим сервер с помощью:

node index.js

Когда наш сервер работает, мы можем попытаться инициировать наш POST-запрос /ask с помощью команды CURL, чтобы убедиться, что наш сервер настроен правильно.

curl -X POST 
  http://localhost:5000/ask 
  -H 'Content-Type: application/json' 
  -d '{ "prompt": "Hi! This is a test prompt!" }'

Мы получим успешный ответ и наше приглашение вернется к нам.

Теперь, когда наш сервер работает должным образом, мы можем перейти к тому, чтобы наша конечная точка /ask взаимодействовала с конечной точкой /completions OpenAI.

Взаимодействие с конечной точкой завершения OpenAI

OpenAI предоставляет /completions конечную точку в своем API, которая предлагает варианты завершения ввода текста.

Когда мы отправляем запрос на конечную точку /completions и включаем подсказку или начальный текст, API создает продолжение этого текста на основе данных обучения.

С помощью этой конечной точки /completions мы можем создать собственную версию ChatGPT (с некоторой оговоркой, что ChatGPT, скорее всего, использует более мощную модель машинного обучения, недоступную через API OpenAI).

Для взаимодействия с API OpenAI нам понадобится уникальный ключ API, который мы создали ранее через веб-сайт OpenAI. Конфиденциальная информация, такая как ключи API, не должна быть жестко запрограммирована непосредственно в исходный код приложения.

Мы создадим файл .env в корневом каталоге нашего проекта для хранения переменных среды, содержащих конфиденциальную информацию.

custom_chat_gpt
  .env
  // ...

В файле .env мы создадим новую переменную среды с меткой OPENAI_API_KEY и присвоим ей значение ключа OpenAI API.

# your unique API key value goes here
OPENAI_API_KEY=sk-############

В нашем файле index.js нам потребуется и использовать модуль dotenv для загрузки переменных среды из файла .env в обработать среду нашего приложения. Мы также импортируем необходимые нам классы из библиотеки openai Node.js — классы Configuration и OpenAIApi.

// configure dotenv
require("dotenv").config();

// import modules from OpenAI library
const { Configuration, OpenAIApi } = require("openai");

// ...

Далее мы должны создать объект конфигурации для взаимодействия с API OpenAI. Мы сделаем это, создав экземпляр конструктора Configuration() и передав значение переменной среды OPENAI_API_KEY в поле apiKey.

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});

Затем мы настроим новый экземпляр класса OpenAI API следующим образом:

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});

const openai = new OpenAIApi(configuration);

Теперь мы можем использовать созданную нами переменную openai для выполнения вызовов API и обработки ответов от OpenAI.

В нашей функции запроса POST /ask мы запустим функцию openai.createCompletion(), которая, по сути, инициирует вызов конечной точки завершения OpenAI.

app.post("/ask", async (req, res) => {
  const prompt = req.body.prompt;

  try {
    if (prompt == null) {
      throw new Error("Uh oh, no prompt was provided");
    }

    // trigger OpenAI completion
    const response = await openai.createCompletion();

    // ...
  } catch (error) {
    console.log(error.message);
  }
});

Конечная точка завершений OpenAI позволяет нам передать большое количество необязательных полей в запрос, чтобы изменить то, как мы хотим, чтобы наше завершение текста вело себя. В нашем случае мы рассмотрим только предоставление значений для двух полей — model и prompt.

* model: указывает имя языковой модели, которую API должен использовать для генерации ответа на запрос. OpenAI предоставляет несколько различных языковых моделей, каждая из которых имеет свои сильные стороны и возможности. В нашем случае мы укажем, что хотим использовать модель text-davinci-003, которая является самая мощная модель GPT-3. * prompt: это приглашение, для которого мы хотим, чтобы OpenAI сгенерировал завершение. Здесь мы просто передаем значение prompt, существующее в теле нашего запроса /ask.

app.post("/ask", async (req, res) => {
  const prompt = req.body.prompt;

  try {
    if (prompt == null) {
      throw new Error("Uh oh, no prompt was provided");
    }

    // trigger OpenAI completion
    const response = await openai.createCompletion({
      model: "text-davinci-003",
      prompt,
    });

    // ...
  } catch (error) {
    console.log(error.message);
  }
});

Текст, возвращаемый из ответа OpenAI, существует в массиве choices, который сам находится в объекте response.data. Мы попытаемся получить доступ к тексту, возвращаемому из первого выбора, возвращенного в API, который будет выглядеть следующим образом:

app.post("/ask", async (req, res) => {
  const prompt = req.body.prompt;

  try {
    if (prompt == null) {
      throw new Error("Uh oh, no prompt was provided");
    }

    const response = await openai.createCompletion({
      model: "text-davinci-003",
      prompt,
    });
    // retrieve the completion text from response
    const completion = response.data.choices[0].text;

    // ...
  } catch (error) {
    console.log(error.message);
  }
});

Последнее, что мы сделаем, — это возврат ответа о завершении в успешном ответе на наш запрос /ask. С этим изменением и всеми изменениями, которые мы сделали, наш файл index.js будет выглядеть следующим образом.

require("dotenv").config();
const express = require("express");
const { Configuration, OpenAIApi } = require("openai");

const app = express();
app.use(express.json());

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

const port = process.env.PORT || 5000;

app.post("/ask", async (req, res) => {
  const prompt = req.body.prompt;

  try {
    if (prompt == null) {
      throw new Error("Uh oh, no prompt was provided");
    }

    const response = await openai.createCompletion({
      model: "text-davinci-003",
      prompt,
    });
    const completion = response.data.choices[0].text;

    return res.status(200).json({
      success: true,
      message: completion,
    });
  } catch (error) {
    console.log(error.message);
  }
});

app.listen(port, () => console.log(`Server is running on port ${port}!!`));

Мы сохраним наши изменения и перезапустим наш сервер. Когда наш сервер работает, мы можем задавать определенные вопросы нашему API, например "Какая типичная погода в Дубае?".

curl -X POST 
  http://localhost:5000/ask 
  -H 'Content-Type: application/json' 
  -d '{ "prompt": "What is the typical weather in Dubai?" }'

Подождав несколько секунд, наш API вернет нам действительный ответ на наш вопрос!

Вот и все! Нам удалось создать простой API с Node/Express для взаимодействия с конечной точкой завершения OpenAI.

На следующей неделе мы продолжим работу с этим руководством и создадим приложение React, которое инициирует запрос /ask при отправке поля ввода.

Заключительные мысли

  • Исходный код этой статьи можно найти на странице github.com/djirdehh/. frontend-fresh/articles_source_code.
  • Взаимодействуйте с конечной точкой /completions и не стесняйтесь задавать ей любые подсказки!
  • Если вы не любите использовать curl для локального тестирования запросов, Postman — это популярный инструмент для тестирования запросов API через клиент.
  • Узнайте больше обо всех различных необязательных полях, которые мы можем предоставить в конечной точке OpenAI /completion в Документация по OpenAI API.
  • Подпишитесь на https://www.frontendfresh.com/, чтобы получать больше подобных руководств. ваш почтовый ящик еженедельно!


Эта оригинальная статья была разослана новостным информационным бюллетенем.


Оригинал