Как использовать API GPT-4 в PHP?

В этой первой статье вы узнаете, как установить и использовать API OpenAI с PHP. Затем мы увидим, как использовать первые функции API для выполнения запроса с помощью GPT-4. В последующих статьях будут представлены (даже) более продвинутые функции…

На повестке дня шаг за шагом двигаться вперед:

Пакет и технические предпосылки для использования API OpenAI

Чтобы использовать API OpenAI и иметь возможность выполнять подсказки, мы будем использовать пакет https://github.com/openai-php/client

Этот пакет не зависит от платформы. В разделе статьи «идти дальше» вы можете найти ссылки на пакеты, посвященные Symfony или Laravel.

На момент написания этой статьи, чтобы иметь возможность использовать этот пакет, вам нужна среда, позволяющая запускать как минимум PHP 8.1.

Как и любой уважающий себя PHP-пакет, установка осуществляется через Composer, с помощью команды:

composer require openai-php/client

Получить ключ API OpenAI

Использование OpenAI API не является бесплатным. Вам нужно будет создать учетную запись на https://platform.openai.com/ Создание учетной записи бесплатно. Однако вам потребуется предварительно пополнить свою учетную запись кредитами ($), чтобы иметь возможность использовать API.

Стоимость подсказки варьируется в зависимости от используемой модели, количества отправленных данных, количества полученных данных и т. д. Поэтому сложно дать представление о стоимости. Но в любом случае, мы можем оценить стоимость средней подсказки примерно в 1 цент. Это означает, что за 1 доллар вы можете запустить сотню запросов. Таким образом, если вы начнете с внесения от 5 до 10 долларов в виде кредитов, перед вами будет несколько сотен возможных исполнений для тестирования API.

Интерфейсы OpenAI развиваются. На момент написания этой статьи покупку кредитов можно найти в: «Настройки» > «Оплата» > «Добавить к кредитному балансу».

Как только это будет сделано, вы можете создать ключ API через: Ключи API > Создать новый секретный ключ.

Я предлагаю вам создать ключ для каждого проекта, это позволит вам отслеживать его использование и легко деактивировать при необходимости.

Этот ключ API не должен быть общим или иметь версии. Рекомендуется использовать файл среды (.env).

Первый вызов API GPT4 в PHP

Как объяснялось вначале, мы будем работать с GPT-4.

13 мая 2024 года была выпущена последняя версия GPT-4 — GPT-4o. На данный момент это самая быстрая и… самая дешевая модель!

Чтобы правильно организовать ваш код, я предлагаю вам создать класс, предназначенный для выполнения ваших подсказок. Это позволит вам хранить все, что связано с их построением, исполнением и восстановлением данных, в одном месте.

Назовем этот класс «IA»:

class IA
{
    // Modèles disponibles
    public const MODEL_GPT4_TURBO = 'gpt-4-turbo';
    public const MODEL_GPT4_O = 'gpt-4o';
    
    // Mon premier prompt
    public static function myFirstPrompt(): string
    {
        // Définition du prompt
	      $prompt="Explique moi pourquoi PHP est le meilleur langage pour faire du développement web ?";
	      
	      // Initialisation du client
	      $client = OpenAI::client(getenv('OPENAI_API_KEY')); // Clé disponible dans le fichier .env
	      
	      // Appel à l'API
	      $response = $client->chat()->create([
            'model' => self::MODEL_GPT4_O,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt,
                ],
            ],
        ]);
        
        // Récupération de la réponse
        return $response->choices[0]->message->content;
    }
}

Небольшое объяснение:

  • Я решил поместить модели в константы. Таким образом, я мог эффективно вызывать их через константы, не рискуя опечаткой или чем-то еще.
  • Мой метод myFirstPrompt является статическим, поэтому я могу вызвать его, не создавая экземпляр объекта AI.
  • Итак, этот метод возвращает ответ на мое приглашение и все. Это самый простой вариант использования: я передаю статическое приглашение (без изменений между каждым вызовом) и получаю на выходе строку символов. Мы увидим, что можем делать более сложные вещи.

Расширенный вызов API GPT4 с помощью PHP

Случай статического приглашения не очень интересный случай. В контексте сложного веб-приложения приглашение, несомненно, будет разным при каждом вызове по нескольким причинам:

  • Использование информации пользователя
  • Использование деловой информации (например, информации, содержащейся в базе данных)
  • Использование внешней контекстной информации (новостных данных, данных о погоде и т. д.)

Все это подтолкнет нас к созданию более продвинутой логики создания подсказок.

Затем существует концепция инструкций. Если вы знакомы с ChatGPT, вы знаете, что через интерфейс можно определять персонализированные инструкции. Это набор правил и информации, которые будут использоваться при каждом запросе для предоставления дополнительного контекста, а также инструкций о том, как реагировать на различные запросы. В ChatGPT мы пишем их один раз и эти инструкции распространяются на все запросы. С помощью API мы можем определять инструкции при каждом выполнении. Как и в случае с приглашением, эти инструкции могут создаваться динамически с использованием одних и тех же типов информации.

Read more:  Вот советы в последнюю минуту, как платить меньше налогов

Наконец, получить ответ на приглашение — это очень хорошо, но API возвращает другую информацию, часть которой очень интересна для понимания того, как было выполнено приглашение и, например, сколько оно стоило.

Таким образом, в этом новом коде мы:

  • Создать приглашение динамически
  • Создать инструкции
  • Вернуть весь ответ

Я начну с предыдущего примера, за исключением того, что на этот раз я собираюсь передать пользователя в параметры. Будем считать, что этот пользователь соответствует классу User, который имеет определенные общедоступные свойства (только для публичного чтения).

class IA
{
    // Modèles disponibles
    public const MODEL_GPT4_TURBO = 'gpt-4-turbo';
    public const MODEL_GPT4_O = 'gpt-4o';
    
    /**
     * @param User $user un utilisateur de mon application
     * @return OpenAI\Responses\Chat\CreateResponse une réponse de l'API OpenAI
     */
    public static function newsAboutALanguage(User $user): CreateResponse
    {
        // Construction du prompt
        $prompt="Présente moi 4 nouveautés du language : " . $user->favoriteLanguage;
        
        // Construction des instructions
        $instructions="Pour répondre au prompt, tu prendras en compte que je suis " . $user->seniorityLevel . '.' .
								        'Pour chaque nouveauté, tu donneras son nom, une présentation en 1 phrase et un exemple de code pour illustrer';
								        
				// Initialisation du client
	      $client = OpenAI::client(getenv('OPENAI_API_KEY')); // Clé disponible dans le fichier .env
	      
	      // Appel à l'API
	      $response = $client->chat()->create([
            'model' => self::MODEL_GPT4_O,
            'messages' => [
                [
                    'role' => 'system',
                    'content' => $instructions
                ],
                [
                    'role' => 'user',
                    'content' => $prompt
                ],
            ],
        ]);
        
        // Renvoi de la réponse
        return $response;			        
    }

Небольшое объяснение:

  • На этот раз у моего метода есть параметр, это экземпляр User
  • Я использую $user для динамического создания приглашения и инструкций.
  • При вызове API я теперь отправляю 2 сообщения одновременно.
    • Корреспондент “Системы” с инструкциями
    • Один, соответствующий «пользователю» (как в предыдущем примере) с приглашением
  • Я возвращаю $response полностью. Поэтому за обработку ответа будет отвечать остальная часть моего кода.

Почему и как обрабатывать ответ?

В $response вы не просто получаете ответ на приглашение, вы получаете другую интересную информацию, в том числе:

  • Стоимость в токенах вашего сообщения
  • Стоимость предоставленного ответа в токенах

Скорее всего, вам потребуется записать эту информацию в своем приложении, например, чтобы отслеживать, кто какие подсказки выполняет и сколько стоят выполненные подсказки. Если ваш метод класса IA возвращает только ответ на приглашение, то вся эта ценная информация каждый раз теряется.

Таким образом, в этой версии кода класс IA не может записывать эту информацию. Но мы могли бы поступить иначе, используя сложный класс IA+ и метод, предназначенный для записи данных подсказок, примерно так:

class IA
{
    // Modèles disponibles
    public const MODEL_GPT4_TURBO = 'gpt-4-turbo';
    public const MODEL_GPT4_O = 'gpt-4o';
    
    // Mon premier prompt
    public static function mySavedPrompt(): string
    {
        // Définition du prompt
	      $prompt="...";
	      
	      // Initialisation du client
	      $client = OpenAI::client(getenv('OPENAI_API_KEY')); // Clé disponible dans le fichier .env
	      
	      // Appel à l'API
	      $response = $client->chat()->create([
            'model' => self::MODEL_GPT4_O,
            'messages' => [
                [
                    'role' => 'user',
                    'content' => $prompt,
                ],
            ],
        ]);
        
        // Sauvegarde des informations du prompt
        $this->save($prompt, $instructions, $response);
        
        // Renvoi seulement de la réponse
        return $response->choices[0]->message->content;
    }
    
    private static function save(string $prompt, string $instructions, CreateResponse $response): void
    {
        // Logique de sauvegarde (propre à ton application, ton SGBD, ton framework, etc.)
    }
}

Если у вас волосы встают дыбом, когда вы смотрите на этот код, не волнуйтесь, это нормально! Действительно, здесь мы не очень соблюдаем принцип единой ответственности. Класс IA не должен заботиться о резервном копировании с помощью частного метода. Более того, частные методы часто являются хорошим индикатором того, что принцип единой ответственности не соблюдается (тоже не всегда).

Read more:  Мужчина из Массачусетса приговорен за нападение на бортпроводник со сломанной ложкой

Поэтому мы предпочли бы иметь что-то вроде:

class IA
{
    // Modèles disponibles ...
    
    // Mon premier prompt
    public static function mySavedPrompt(): string
    {
        // Définition du prompt ...
	      // Initialisation du client ...
	      // Appel à l'API ...
        
        // Sauvegarde des informations du prompt
        PromptInformations::save($prompt, $instructions, $response);
        // Ou : 
        $prompt = new Prompt($prompt, $instructions, $response);
        $prompt->save();
        
        // Encore une fois à adapter selon ton application, ton framework, etc.
        
        // Renvoi seulement de la réponse ...
    }
}

Идите дальше с GPT4

GPT-4-турбо или GPT-4o?

После нескольких тестов, проведенных сразу после выпуска GPT-4o, мы заметили, что результаты подсказок могут быть другими и более низкого качества при использовании GPT-4o. Поэтому мы приглашаем вас сравнить модели, чтобы определить, какая из них наиболее подходит для вашего использования.

С другой стороны, с точки зрения скорости GPT-4o реагирует гораздо быстрее.

Пакеты, посвященные PHP-фреймворкам

Какое влияние оказывают другие параметры?

Во время обращений к API можно управлять и другими параметрами:

  • температура : этот параметр контролирует креативность или вариативность генерируемых ответов. Его значение находится в диапазоне от 0 до 1. При низком значении, близком к 0, ответы будут более детерминированными и последовательными за счет выбора наиболее вероятных слов. Это делает ответы более предсказуемыми и консервативными. При высоком значении, близком к 1, ответы будут более разнообразными и креативными, что привнесет больше разнообразия в выбор слов. Это может привести к менее предсказуемым и более оригинальным реакциям или даже к галлюцинациям (так что будьте осторожны…).
  • top_p : этот параметр управляет разнообразием ответов, генерируемых путем ограничения выбора слов. Его значение находится в диапазоне от 0 до 1. При значении 1 выборка осуществляется среди всех возможных слов, которые могут давать очень разные ответы. При значении меньше 1, например 0,9, учитываются только слова, совокупная вероятность которых меньше этого процента (здесь 90%). Это может сделать ответы более последовательными и менее случайными.
  • частота_пенальти : этот параметр используется для настройки склонности модели повторять одни и те же предложения или слова. Его значение находится между -2 и 2:
    • -2,0 : Настоятельно поощряет повторение слов.
    • 0 : Никаких штрафов или бонусов за частоту слов (нейтральное поведение).
    • 2.0 : Строго наказывается повторение слов.
  • присутствие_пенальти : этот параметр контролирует вероятность появления новых тем или слов в сгенерированном тексте. Его значение также находится между – 2 и 2.
    • -2,0 : Категорически не поощряет введение новых слов или тем, предпочитая повторение уже использованных слов.
    • 0 : наличие новых слов не регулируется, что обеспечивает более естественное создание текста.
    • 2.0 : Настоятельно поощряет введение новых слов или тем, которые еще не упоминались в сгенерированном тексте.

Пример использования с API:

$response = $client->chat()->create([
    'model' => self::MODEL_GPT4_O,
    'messages' => [
        [
            'role' => 'system',
            'content' => $instructions
        ],
        [
            'role' => 'user',
            'content' => $prompt
        ]
    ],
    'temperature' => 0.5,
    'top_p' => 0.9,
]);

Мы также могли бы определить константы для управления этими параметрами. Вместо использования числовых значений мы бы использовали более явные имена, связанные с настройками, например:

// Constantes définies dans la classe IAClientOpenAI
public const PARAM_TEMPERATURE_CREATIVITY_HIGH = 1;
public const PARAM_TEMPERATURE_CREATIVITY_MEDIUM = 0.5;
public const PARAM_TEMPERATURE_CREATIVITY_LOWH = 0.1;

// Puis l'appel
$response = $client->chat()->create([
    'model' => self::MODEL_GPT4_O,
    'messages' => [
        [
            'role' => 'system',
            'content' => $instructions
        ],
        [
            'role' => 'user',
            'content' => $prompt
        ]
    ],
    'temperature' => self::PARAM_TEMPERATURE_CREATIVITY_MEDIUM,
]);

Благодаря этим элементам у вас есть все необходимое для выполнения первых запросов с помощью API GPT4 в PHP. Если вы планируете использовать несколько разных моделей, то я приглашаю вас продолжить чтение статьи, чтобы эффективно организовать свой код.

Бонус: организация кода для использования других API, интерфейсов и DTO.

OpenAI и GPT4 великолепны, но есть и другие модели. Немного оптом:

  • Мистраль ИИ
  • Клод
  • Близнецы
  • И т. д.

Я намеренно начну с конца, чтобы показать, чего мы пытаемся добиться, а именно возможности создать подсказку с любой моделью без необходимости дублировать логику, связанную с подсказкой. Мой класс IA немного изменится, включая конструктор, который позволит вам определить используемую модель. Я также переименую этот класс, чтобы теперь называть его Prompts, поскольку он используется для создания подсказок:

class Prompts
{
    // Promotion de propriété
    public function __construct(
        private IAClientInterface $client
    ) { }
    
    /**
     * @param User $user un utilisateur de mon application
     * @return IAResponseDTO une réponse d'une API d'IA
     */
    public static function newsAboutALanguage(User $user): IAResponseDTO
    {
        // Construction du prompt
        $prompt="Présente moi 4 nouveautés du language : " . $user->favoriteLanguage;
        
        // Construction des instructions
        $instructions="Pour répondre au prompt, tu prendras en compte que je suis " . $user->seniorityLevel . '.' .
								        'Pour chaque nouveauté, tu donneras son nom, une présentation en 1 phrase et un exemple de code pour illustrer';
								        
	      // Appel à l'API
	      $response = $this->client->response([
            'messages' => [
                [
                    'role' => 'system',
                    'content' => $instructions
                ],
                [
                    'role' => 'user',
                    'content' => $prompt
                ],
            ],
        ]);
        
        // Renvoi de la réponse
        return $response;			        
    }
}

Что изменилось?

  • Мой конструктор создает экземпляр свойства $client, содержащего класс, реализующий интерфейс IAClientInterface.
  • У меня больше нет «нового клиента()», за это будет отвечать другой класс
  • Мой метод newsAboutALanguage возвращает экземпляр IAResponseDTO, который будет моим DTO, содержащим информацию, возвращаемую API.
  • В методе newsAboutALanguage я вызываю $this→client→response, тогда как раньше я вызывал $client->chat()->create(…), специфичный для OpenAI.
Read more:  Иностранные лидеры пытаются обратиться к личным чувствам Трампа.

Итак, мне нужно создать следующие элементы:

  • Интерфейс IAClientInterface
  • DTO IAResponseDTO
  • Клиент OpenAI
  • Клиент MistralAI

Интерфейс IAClientInterface:

interface IAClientInterface
{
    // Chaque client doit avoir cette méthode
    public function response(array $params): IAResponseDTO;
}

DTO IAResponseDTO:

class IAResponseDTO
{
    // Toutes les propriétés sont en public readonly
    // On pourrait les mettre toutes en nullable au cas où une des API ne renverrait pas une donnée
    // Exemple avec la temperature
    public function __construct(
        public readonly string $prompt,
        public readonly string $instructions,
        public readonly string $response,
        public readonly int $nbInputTokens,
        public readonly int $nbOutputTokens,
        public readonly ?float $temperature = null,
        // Etc.
    ) {}
}

Клиент OpenAI:

class IAClientOpenAI implements IAClientInterface
{
    // Les constantes des models sont désormais ici
    public const MODEL_GPT4_TURBO = 'gpt-4-turbo';
    public const MODEL_GPT4_O = 'gpt-4o';

    private Client $client;

    public function __construct(
        private string $model = self::MODEL_GPT4_O
    ) {
        $this->client = OpenAI::client(getenv('OPENAI_API_KEY')); // Clé disponible dans le fichier .env
    }
    
    public function response(array $params): IAResponseDTO
    {
        $response = $this->client->chat()->create([
	          'model' => $this->model,
	          ...$params, // Opérateur de décomposition
        ]);

        // Récupération de prompt et des instructions
        $prompt="";
        $instructions="";

        foreach ($params['messages'] as $message) {

            if ($message['role'] == 'system') {
                $instructions = $message['content'];
                continue;
            }

            if ($message['role'] == 'user') {
                $prompt = $message['content'];
                continue;
            }
        }
    
        // Construction du DTO
        return new IAResponseDTO(
            prompt: $prompt,
            instructions: $instructions,
            response: $response->choices[0]->message->content,

            nbInputTokens: $response->usage->promptTokens,
            nbOutputTokens: $response->usage->completionTokens,
        );
    }
}

AI-клиент Mistral (полностью придуманный код, без связи с каким-либо существующим пакетом):

class IAClientMistralAI implements IAClientInterface
{
    // Modèles
    public const MODEL_7B = 'open-mistral-7b';
    public const MODEL_8X7B = 'open-mixtral-8x7b';

    private Client $client;

    public function __construct(
        private string $model = self::MODEL_7B
    ) {
        $this->client = MistralAI::client(getenv('MISTRALAI_API_KEY')); // Clé disponible dans le fichier .env
    }
    
    public function response(array $params): IAResponseDTO
    {
        $response = $client->chat()->prompt([
	          'model' => $this->model,
	          ...$params // Opérateur de décomposition
        ]);
        
        // Récupération de $prompt et $instructions comme précédemment
    
        // Construction du DTO
        return new IAResponseDTO(
            prompt: $prompt,
            instructions: $instructions,
            response: $response->result,

            // Etc. mapping à faire selon le retour de l'API
            nbInputTokens: $response->tokens->input,
            nbOutputTokens: $response->tokens->output,
        );
    }
}

Напоминание: приведенный выше код полностью выдуман.

И, наконец, в моей основной программе:

// Appel à OpenAI
$ia = new IA(new IAClientOpenAI);
$ia->newsAboutALanguage($user);

// Appel à MistralAI
$ia = new IA(new IAClientMistralAI);
$ia->newsAboutALanguage($user);

Такая организация кода позволяет нам не дублировать логику(ы) управления подсказками, каждый раз существует промежуточный класс, который будет отвечать как за правильный вызов API, так и за обработку полученного ответа для получения последовательный ответ независимо от вызываемого API.

Если вам нужно просмотреть некоторые технические концепции:

И не стесняйтесь Подписывайтесь на нас чтобы быть в курсе следующей статьи 😉

2024-05-27 12:19:26


1717041553
#Как #использовать #API #GPT4 #PHP

По теме

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.