← Voltar na listagem

25 de novembro de 20247 min de leitura

Integrando OpenAI com Node.js Um Guia Prático

Aprenda a integrar a poderosa biblioteca da OpenAI com Node.js para elevar seus projetos de desenvolvimento.

Se você é desenvolvedor e quer utilizar a poderosa API da OpenAI em seus projetos Node.js, este guia vai te ajudar a fazer essa integração de maneira simples e didática. Vamos aprender juntos como instalar, configurar e utilizar a biblioteca OpenAI, tornando seus aplicativos mais inteligentes e eficientes!

🛠️ Instalação

Antes de mais nada, precisamos instalar a biblioteca da OpenAI para Node.js. Você pode fazer isso com o seguinte comando no terminal:

npm install openai

Se você estiver usando o runtime JavaScript Deno, também pode adicionar diretamente:

deno add jsr:@openai/openai

🚀 Esses comandos tornam o módulo importável a partir do escopo @openai/openai, facilitando o uso da API da OpenAI em seu projeto.

💻 Começando a Usar a API OpenAI

A biblioteca OpenAI oferece acesso conveniente à API REST, permitindo criar funções com inteligência artificial. Aqui está um exemplo básico para começar:

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env['OPENAI_API_KEY'], // Chave da API para autenticar
});

async function main() {
  const chatCompletion = await client.chat.completions.create({
    messages: [{ role: 'user', content: 'Diga que isso é um teste' }],
    model: 'gpt-4o',
  });
  console.log(chatCompletion);
}

main();

🔎 Observação: é importante definir sua apiKey usando variáveis de ambiente para garantir a segurança.

🛠 Streaming de Respostas

Você pode precisar receber respostas em tempo real, e a OpenAI fornece suporte para isso usando Server Sent Events (SSE). Vamos ver um exemplo prático:

import OpenAI from 'openai';

const client = new OpenAI();

async function main() {
  const stream = await client.chat.completions.create({
    model: 'gpt-4o',
    messages: [{ role: 'user', content: 'Diga que isso é um teste' }],
    stream: true,
  });
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }
}

main();

Se precisar cancelar um fluxo, é possível interromper o loop ou chamar stream.controller.abort().

Outra forma de utilizar o streaming é usando os helpers que fornecem eventos específicos, como on('content') para processar o que foi recebido durante o streaming:

const openai = new OpenAI();

async function main() {
  const stream = await openai.beta.chat.completions.stream({
    model: 'gpt-4o',
    messages: [{ role: 'user', content: 'Diga que isso é um teste' }],
    stream: true,
  });

  stream.on('content', (delta, snapshot) => {
    process.stdout.write(delta);
  });

  // ou, de maneira equivalente:
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }

  const chatCompletion = await stream.finalChatCompletion();
  console.log(chatCompletion); // {id: "...", choices: [...], ...}
}

main();

📘 Tipos de Requisição e Resposta

Uma das grandes vantagens de usar TypeScript é a tipagem. A biblioteca OpenAI inclui definições de tipos para todos os parâmetros de requisição e campos de resposta. Veja um exemplo:

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env['OPENAI_API_KEY'],
});

async function main() {
  const params: OpenAI.Chat.ChatCompletionCreateParams = {
    messages: [{ role: 'user', content: 'Diga que isso é um teste' }],
    model: 'gpt-4o',
  };
  const chatCompletion: OpenAI.Chat.ChatCompletion =
    await client.chat.completions.create(params);
  console.log(chatCompletion);
}

main();

Isso torna o desenvolvimento mais seguro e fácil, pois você tem as informações necessárias diretamente no editor!

💃 Funções Automáticas com runTools

O helper runTools permite chamadas de função automáticas, onde a API da OpenAI chama suas funções em JavaScript e envia os resultados de volta ao endpoint /chat/completions. Aqui está um exemplo:

import OpenAI from 'openai';

const client = new OpenAI();

async function main() {
  const runner = client.beta.chat.completions
    .runTools({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: 'Como está o clima esta semana?' }],
      tools: [
        {
          type: 'function',
          function: {
            function: getCurrentLocation,
            parameters: { type: 'object', properties: {} },
          },
        },
        {
          type: 'function',
          function: {
            function: getWeather,
            parse: JSON.parse,
            parameters: {
              type: 'object',
              properties: {
                location: { type: 'string' },
              },
            },
          },
        },
      ],
    })
    .on('message', (message) => console.log(message));

  const finalContent = await runner.finalContent();
  console.log('Conteúdo final:', finalContent);
}

async function getCurrentLocation() {
  return 'Boston';
}

async function getWeather(args) {
  const { location } = args;
  return { temperature: '15°C', precipitation: 'Moderado' };
}

main();

🏠 Upload de Arquivos

Você também pode fazer uploads de arquivos como parte dos seus pedidos para a OpenAI. Abaixo temos alguns exemplos:

import fs from 'fs';
import OpenAI from 'openai';

const client = new OpenAI();

// Usando fs para criar um stream de leitura
await client.files.create({
  file: fs.createReadStream('input.jsonl'),
  purpose: 'fine-tune',
});

Isso facilita a fine-tuning dos modelos com arquivos personalizados.

❌ Tratamento de Erros

Em caso de erros, a biblioteca lançará uma subclass de APIError.

async function main() {
  const job = await client.fineTuning.jobs
    .create({ model: 'gpt-4o', training_file: 'file-abc123' })
    .catch(async (err) => {
      if (err instanceof OpenAI.APIError) {
        console.log(err.status); // 400
        console.log(err.name); // BadRequestError
      } else {
        throw err;
      }
    });
}

main();

⌛ Paginando e Fazendo Várias Requisições

Métodos de listagem são paginados, mas você pode usar for await ... of para iterar entre todas as páginas:

async function fetchAllJobs() {
  const allJobs = [];
  for await (const job of client.fineTuning.jobs.list({ limit: 20 })) {
    allJobs.push(job);
  }
  return allJobs;
}

💡 Essa abordagem é ótima para buscar todos os registros sem se preocupar com as páginas manualmente.

🛡 Dicas de Boas Práticas

  • Sempre use variáveis de ambiente para armazenar chaves sensíveis.
  • Use o streaming para receber respostas gradualmente, caso precise de maior interatividade.
  • Utilize tipagem TypeScript para evitar erros comuns e garantir segurança no desenvolvimento.

Espero que esse guia te ajude a explorar o mundo de possibilidades que a integração com a OpenAI pode oferecer! Se tiver dúvidas ou sugestões, deixe um comentário. 🙌🏼

Boa codificação! 💻🚀