Saltar al contenido

Primeros pasos con la API de OpenAI

Los nuevos modelos de lenguaje nos dan acceso a servicios como ChatGPT o Dall-E, útiles y accesibles para todo el mundo; pero la forma mas básica de acceder a estos modelos es a través de su API.

La API nos permite hacer un uso más fino de las capacidades de los modelos, además de poder integrarlos en nuestras propias aplicaciones.

En esta entrada empezaremos por ver cómo crear una cuenta en OpenAI para empezar a llamar a su API, y veremos cómo podemos empezar a usarlas para hacernos nuestro propio clon de ChatGPT en Python y Node.js, muy rudimentario pero con su propia personalidad.

La clave de API (API key)

Lo primero que necesitaremos es una cuenta en OpenAI. Si hemos usado ChatGPT alguna vez ya tendremos una, pero si no, hay que darse de alta en openai.com. Una vez en nuestra cuenta, necesitaremos generar una clave (API key), que será nuestra forma de identificarnos a la hora de hacer cualquier llamada a la API, yendo a la sección API keys.

Es importante no compartir ni hacer nunca pública nuestra clave, ya que cualquiera que tenga acceso a ella podrá usarla para hacer llamadas con cargo a nuestra cuenta. Si te das cuenta de que tu clave ha sido comprometida de alguna manera, es necesario volver a la sección API keys, generar una clave nueva (el sistema siempre nos obligará a tener al menos una clave generada, aunque podemos tener más) y borrar (delete) la anterior con lo que a partir de ese momento cualquier llamada con la clave vieja será rechazada.

Gestión de claves de API
Esta pantalla nos permite generar claves y borrar claves antiguas o comprometidas.

Pago por uso

Mientras que OpenAI ofrece gratuitamente acceso a algunos de sus servicios (ChatGPT con GTP 3.5, o Dall-E 2) todas las llamadas a API tienen un coste, el cual varia en función del tipo de llamada, el modelo y el tamaño. Por tanto, antes de poder empezar a hacer uso de la API, aunque sólo sea para pruebas, necesitaremos ir a la sección Billing para introducir una forma de pago (que, a la hora de escribir esta entrada, sólo admite tarjeta de crédito) y hacer un primer ingreso de fondos.

La forma en que funciona la facturación con OpenAI es mediante ingresos que nos dan crédito, y el uso que hagamos de la API se ira descontando de nuestro crédito. Este formato de pago, aunque ventajoso para OpenAI porque realizamos el pago por adelantado, tiene la parte buena de que nos da la tranquilidad de que nuestro gasto no nos va a dar un susto demasiado grande, ya que nuestro crédito actúa como techo que nunca se superará. Una vez que estemos más familiarizados con el uso de la API y su facturación, podemos hacer uso de la opción de recarga automática (desactivada por defecto) y configurar nuestros límites de gasto en el sistema para asegurar que nuestro gasto se mantiene acorde a nuestro presupuesto.

Balance cargado en la cuenta de OpenAI
Ejemplo de cuenta con (pequeño) balance cargado. Con esto estaríamos listos para empezar a experimentar.

Primera llamada a API: lista de modelos

Con nuestra cuenta creada y cargada, y la clave preparada, ya estamos listos para empezar a hacer llamadas a la API.

OpenAI publica su API como servicios web REST accesibles de forma genérica, además de librerías para Python y Node.js que encapsulan y simplifican su uso para estas plataformas. Para empezar, podemos hacer una primera llamada directa a un servicio web usando curl (sustituyendo nuestra clave de API):

curl https://api.openai.com/v1/models -H "Authorization: Bearer clave-de-api"

Aquí estamos llamando al servicio de listar modelos, que es un servicio GET que no tiene parámetros de entrada y nos devuelve la lista de modelos actualmente soportados por OpenAI. Además de habernos servido para hacer una primera prueba y ver que nuestra clave funciona, esta llamada nos da pie a comentar los modelos disponibles que podremos usar en subsiguientes llamadas.

Como podemos comprobar por la respuesta a nuestra llamada, OpenAI soporta un buen número de modelos de distintos tipos, incluyendo generación de imágenes, generación de audio, transcripción, … Por lo pronto nos centraremos sólo en los modelos de lenguaje natural, y de entre ellos los principales (en el momento de escribir esta entrada) son:

  • gpt-3.5-turbo: Modelo GPT 3.5, actualmente usado por la versión gratuita de ChatGPT.
  • gpt-4: Modelo GPT 4, usado en la versión de pago de ChatGPT.
  • gpt-4-1106-preview: GPT 4-Turbo, su modelo más poderoso, actualmente en beta y sólo accesible a través de APIs.

Curiosamente, el modelo más reciente, GPT 4-Turbo, es ahora mismo más barato que GPT 4 (probablemente por encontrarse en beta). Aprovecharemos esto para sacarle partido a este nuevo modelo.

El servicio chat completions

El servicio básico que tendremos que usar para construir nuestro chatbot es chat completions, que nos permite hacer consultas al modelo con entrada y salida de texto. Este servicio POST que acepta una gran variedad de parámetros que nos permiten hacer ajustes de la consulta, pero solo dos de ellos son obligatorios:

  • model, mediante el cual identificaremos el modelo que queremos consultar, usando una de las posibilidades que nos devolvió la consulta al servicio de lista de modelos.
  • messages, esta es la chicha del servicio; aquí le pasaremos la lista mensajes de la conversación a la que esperamos que nos dé respuesta.

Cada mensaje de la lista que enviamos a servicio, además del texto en sí del mensaje, va acompañado de uno de estos tres roles:

  • user: mensajes enviados por el usuario. Por ejemplo, si entramos en ChatGPT y le hacemos una pregunta, ésta se enviará al modelo con este rol.
  • assistant: mensajes devueltos por el modelo.
  • system: mensaje que describe el comportamiento general que esperamos del modelo durante toda la conversación. Su uso es opcional.

Es necesario tener en cuenta que las llamadas al modelo no tienen estado; el modelo no tiene memoria de nuestras llamadas anteriores. Cada llamada es recibida y contestada por el modelo de forma completamente independiente.

Entonces … ¿cómo hace ChatGPT para mantener una conversación, y ser capaz de hacer referencia a lo que hemos hablado antes?

Pues la forma de hacerlo es enviar en cada llamada la conversación completa, todo lo que le hemos enviado, y todo lo que nos ha contestado con anterioridad. Esa es la razón de la existencia del rol assistant: es el rol que usaremos para marcar, cuando enviemos los anteriores mensajes de la conversación, las respuestas que el servicio nos había dado, y diferenciarlos de nuestros propios mensajes.

Chatbot cascarrabias

Llegó el momento de, con todo lo que hemos visto, construir nuestro propio chatbot. ChatGPT está bien, pero es un poco insípido y falto de personalidad. Al nuestro le daremos un poco más de chispa … construiremos el chatbot cascarrabias.

Para construirlo usaremos las librerías que nos facilita OpenAI para Python o Node.js. El código completo en ambos lenguajes está disponible en GitHub. Para describir el funcionamiento voy a basarme en la versión de Node.js, pero ambos scripts son prácticamente iguales.

Empezamos por instanciar el objeto OpenAI, que es el que nos da acceso a toda la funcionalidad de la librería. Aquí deberemos pasarle la clave de API, ya sea explícitamente pasando el valor a apiKey en el objeto de entrada, o dejando que lo coja de la variable de entorno OPENAI_API_KEY.

const client = new OpenAI();
o
const client = new OpenAI({ apiKey: 'clave-de-api' });

Mantendremos una lista (array) con los mensajes de la conversación. La crearemos con un mensaje inicial con el rol system, que es el que nos permitirá modificar el comportamiento general de nuestro chatbot, y que le otorgará su especial personalidad:

let mensajes = [{ 'role': 'system', 'content': 'Eres un viejo gruñón y cascarrabias. Responde a todo con quejas y desgana, aunque termina ayudando en lo que se te pide.' }];

Entramos en el bucle principal del script, en el cual capturaremos el mensaje de entrada del usuario, y se repetirá hasta que lo deje vacío. El mensaje del usuario, lo añadimos a la lista de mensajes con el rol user:

mensajes.push({ 'role': 'user', 'content': texto });

Llamamos al servicio chat completions con la lista de mensajes y el modelo que queremos usar (en este caso GPT 4-Turbo):

const respuesta = await client.chat.completions.create({
    model: 'gpt-4-1106-preview',
    messages: mensajes
});

Por último, la respuesta que recibimos del modelo, además de mostrarla al usuario, la guardamos en la lista de mensajes con el rol assistant para que la siguiente llamada tenga la conversación completa:

mensajes.push({ 'role': 'assistant', 'content': respuesta.choices[0].message.content });

¡Y con eso ya tenemos nuestro chatbot funcionando! Por supuesto, este chatbot tan sencillo, aunque funciona, adolece de varios problemas, siendo el principal de ellos la falta de control sobre el tamaño creciente de la conversación almacenada, con lo que si ésta se alarga, llegará un momento en que exceda del límite de tamaño permitido en la llamada. En la próxima entrada veremos posibles soluciones a este problema, y otras mejoras que podemos hacer a nuestro chatbot.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *