• Час читання ~2 хв
  • 14.12.2022

ШІ це модне слово чи це те, про що нам варто подумати? З випуском пакета OpenAI ми можемо зануритися в програми Laravel на основі штучного інтелекту

Отже, що таке OpenAI? Що ми можемо з цим зробити? Здебільшого це стосується обробки природної мови. Ми передаємо йому якийсь текст, а у відповідь він може вразити нас багатьма речами. Від повних текстових прикладів до прикладів коду до всього, що вам потрібно. Головним обмеженням є ваша уява та її поточні можливості.

Нуно відпустив OpenAI PHP клієнт деякий час тому - але що ми можемо з цим зробити? Часто я вважаю, що найскладнішою частиною роботи з цією технологією є розуміння того, що ви можете з нею робити.

Переглядаючи приклади OpenAI, я знайшов безліч зразків, які, ймовірно, підійдуть мені та для загального використання. Давайте пройдемося по моделі для «Оголошення з опису товару». Я вибираю це, оскільки ми часто фіксуємо введений текст від наших користувачів, а потім з різних причин маємо виводити його пізніше. Уявіть, що ви керуєте інтернет-магазином і вам потрібно зафіксувати описи продуктів для своїх товарів, і ви хочете додати текст у стилі «вбивчої реклами», щоб спонукати людей натискати на продукт.

Давай заскочимо.

Я не буду проводити вас через процес встановлення клієнта OpenAI PHP. Оскільки ви читаєте це, я припускаю, що мені не потрібно навчати вас цієї частини. Проте я розповім, як я буду використовувати цей пакет, який, ймовірно, відрізнятиметься від інших посібників.

Перше, що я зробив би, це прив’язати клас OpenAI Client до мого контейнера, щоб мені не потрібно було використовувати фасад або створювати екземпляр клієнта.

final class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(
            abstract: Client::class,
            concrete: fn () => OpenAI::client(
                apiToken: strval(config('openai.api_key')),
            ),
        );
    }
}

Тепер щоразу, коли я намагаюся вставити клас OpenAI Client у конструктор чи будь-де ще, він буде попередньо налаштований для мене.

Наш варіант використання — це коли ми зберігаємо продукт із описом. Ми хочемо автоматично створити текст реклами продукту. Насправді найкращим місцем для цього була б робота. Один ми можемо надіслати як частину процесу створення самої моделі.

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

Коли ми відправляємо фонове завдання, ми передаємо те, що хочемо серіалізувати, у конструктор, а потім, у методі handle, ми можемо розпізнати екземпляри з контейнера DI.

Давайте подивимося, як це виглядатиме, якщо підійти до цього просто.

final class GenerateAdFromProduct implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    public function __construct(
        public readonly string $text,
        public readonly int $product,
    ) {}
    public function handle(Client $client): void
    {
        $response = $client->completions()->create([
            'model' => 'text-davinci-003',
            'prompt' => $this->text,
            'temperature' => 0.5,
            'max_tokens' => 100,
            'top_p' => 1.0,
            'frequency_penalty' => 0.0,
            'presence_penalty' => 0.0,
        ]);
        DB::transaction(fn () => Product::query()->find(
            id: $this->product,
        ))->update(['ai_description' => $response['choices'][0]['text']]);
    }
}

Тут використовуються параметри, описані на прикладі сторінки, без заглиблення в них. Звичайно, якщо ви робите це у виробництві, я настійно рекомендую уважніше переглянути ці налаштування.

Чи можемо ми це покращити? Звичайно, ми можемо - я Стів, і я самовпевнений... Давайте зробимо крок далі.

Що ми тут робимо? Ми використовуємо попередньо визначену модель для створення та повернення відповіді від OpenAI. Параметри, які ми використовуємо, попередньо визначені в прикладах. Звичайно, їх можна налаштувати, але ми можемо використати це, щоб зробити крок далі.

Наш перший крок — сама модель. OpenAI наразі підтримує лише стільки доступних – це може змінитися в якийсь момент, але поки що не буде. Давайте створимо Enum для модельної частини корисного навантаження:

enum Model: string
{
    case ADA = 'text-ada-001';
    case BABBAGE = 'text-babbage-001';
    case CURIE = 'text-curie-001';
    case DAVINCI = 'text-davinci-003';
}

Крок перший завершено. Давайте зараз подивимося на запит клієнта OpenAI.

$client->completions()->create([
    'model' => Model::DAVINCI->value,
    'prompt' => $this->text,
    'temperature' => 0.5,
    'max_tokens' => 100,
    'top_p' => 1.0,
    'frequency_penalty' => 0.0,
    'presence_penalty' => 0.0,
]);

Досить добре. Решта налаштувань є специфічними для моделі та результату, якого я намагаюся досягти з того, що я можу сказати з документації. Отже, це те, що навмисно створено, щоб я міг отримати текст реклами з іншого тексту. Для мене це рекламний трансформер. Він перетворює будь-яку вашу підказку на рекламу. Отже, маючи це на увазі - давайте створимо спеціальний клас для створення цього.

final class AdvertisementTransformer
{
    public static function transform(string $prompt): array
    {
        return [
            'model' => Model::DAVINCI->value,
            'prompt' => $prompt,
            'temperature' => 0.5,
            'max_tokens' => 100,
            'top_p' => 1.0,
            'frequency_penalty' => 0.0,
            'presence_penalty' => 0.0,
        ];
    }
}

Ми витягуємо логіку створення доповнення до виділеного класу, що дозволить нам легко використовувати його повторно. Давайте поглянемо на запит клієнта OpenAI:

$client->completions()->create(
    parameters: AdvertisementTransformer::transform(
        prompt: $this->text,
    ),
);

Це, принаймні для мене, чисто і зрозуміло. Дивлячись на це, я передаю текст із роботи в трансформатор, який трансформується до необхідних параметрів для генератора тексту реклами.

Вихід для цього буде таким:

{
  "object": "text_completion",
  "created": 1672769063,
  "model": "text-davinci-003",
  "choices": [
    {
      "text": "Are you a #Laravel developer looking to stay up-to-date with the latest news and updates? Look no further than Laravel News! With over 10K users daily, you'll be able to stay informed and learn from the official news outlet for the Laravel ecosystem. #LaravelNews #Developers #Ecosystem",
      "index": 0,
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 82,
    "completion_tokens": 72,
    "total_tokens": 154
  }
}

Як бачите, ми маємо низку варіантів, кожен з яких має текстовий ключ. Щоб отримати це, нам просто потрібно отримати до нього доступ, як зазвичай у PHP:

$response = $client->completions()->create(
    parameters: AdvertisementTransformer::transform(
        prompt: $this->text,
    ),
);
DB::transaction(fn () => Product::query()->find(
    id: $this->product,
))->update(['ai_description' => $response['choices'][0]['text']]);

Все, що вам тепер потрібно зробити, це створити стандартні трансформатори, які ви можете використовувати у своїй програмі, налаштувати параметри так, щоб ви були впевнені, що вони будуть працювати для вас, і ви можете продовжувати.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297