Integrando ChatGPT en nuestra aplicación Symfony

Artificial intelligence
Solucionex
11
Jun 25

Para integrar la API de OpenAI en nuestras aplicaciones symfony usaremos el paquete openai-php/symfony el cual es una implementacion de openai-php/client para Symfony, lo instalamos mediante

composer require openai-php/symfony

Necesitaremos una API Key de OpenAI la podemos obtener de https://platform.openai.com/api-keys. Una vez obtenida hay que incluirla en la aplicación como una variable de entorno de nombre OPENAI_API_KEY

Sobre las API keys de OpenAI, si no tienes un método de pago asociado a tu cuenta de OpenAI Platform, que no es la misma que la de ChatGPT, solo podrás acceder al listado de modelos disponibles, si quieres hacer uso de las funcionalidades de la API tienes que estar en una cuenta de pago, con una API key creada después de haber pasado a una cuenta de pago y que la clave tenga los permisos adecuados

Una vez que tenemos todo configurado podremos hacer uso de la API y sus funcionalidades, como puedan ser chatbots, generación de imágenes, traducción de audios y un largo etcétera que se puede consultar desde la referencia de la API

Vamos a ver un ejemplo de como crear un interfaz para un chatbot sencillo en nuestra web utilizando el modelo gpt-3.5-turbo

Lo primero es crear un LiveComponent para el chat en el que tenemos el histórico de mensajes (history), el mensaje que vamos a mandar a OpenAI (current) y un método para enviar el mensaje a la API (sendText)  

// src/Twig/Components/OpenAIChat.php

namespace App\Twig\Components;

use OpenAI\Client;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent]
final class OpenAIChat
{
   use DefaultActionTrait;

   #[LiveProp]
   public array $history = [];

   #[LiveProp(writable: true)]
   public string $current = '';

   #[LiveAction]
   public function sendText(Client $client)
   {
       $this->history[] = ['role' => 'user', "content" => $this->current];
       $this->current = '';

       $response = $client->responses()->create([
           'model' => 'gpt-3.5-turbo',
           'input' => $this->history,
           'store' => false
       ]);

       foreach ($response->output as $output) {
           foreach ($output->content as $content) {
               $this->history[] = ['role' => $output->role, "content" => $content->text];
           }
       }
   }
}

La parte importante es la línea en la que llamamos a $client->responses()->create que es donde estamos llamando al endpoint de Responses de OpenAI, en este caso estamos utilizando el índice input como el histórico de la conversación junto con el store a false para que el modelo tenga el estado de la conversación, hay otra alternativa para mantener el estado de la conversación que es usar el índice store a true y pasarle el previous_response_id con el valor del id que hemos guardado de la variable response de la respuesta anterior

Estamos utilizando el endpoint de Responses y no el de Chat porque el de Chat está deprecado

La plantilla del componente

{# templates/components/OpenAIChat.html.twig #}
<div{{ attributes }} class="mx-auto max-w-4xl">

 <div>Open AI Chat</div>
 <div id="openai-chat">

   {% for history in this.history %}
     <div class="{{ history.role }} px-2 my-2 rounded-md border-2">
       {{ history.content }}
     </div>
   {% endfor %}

   <textarea data-model="norender|current" id="current-text" cols="30" rows="10" class="w-full bg-gray-300 text-black rounded-md"></textarea>
   <button data-action="live#action" data-live-action-param="sendText">Chat</button>
 </div>

</div>

Y un poco de css para las cajas de la conversación

// assets/styles/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;

#openai-chat {
 display: flex;
 flex-flow: column;
}

#openai-chat > .user {
 width: 90%;
 align-self: start;
}

#openai-chat > .assistant {
 width: 90%;
 align-self: end;
 text-align: right;
}

A partir de ahora integrar el chat en nuestra aplicación Symfony sólo requeriría de incluir el componente en el lugar deseado mediante el tag 

<twig:OpenAIChat />
symfony
Inteligencia artificial