Consumindo Modelos de IA

Primeira Chamada ao LLM

Exemplos práticos em Node.js, Python e PHP — enviar pergunta e receber resposta via código.

Intermediário 35 min 30 pontos Leitura 0%

Nesta aula você vai

  • Implementar chamada HTTP ao LLM em pelo menos uma linguagem
  • Extrair texto da resposta JSON
  • Configurar variável de ambiente para API key

Primeira Chamada ao LLM

Objetivos

  • Consumir um LLM via código — não via interface web
  • Replicar o padrão na sua stack (Node, Python ou PHP)

O momento "funcionou"

Até aqui foi teoria. Agora vem o clique mental: você roda um script, digita uma pergunta e o terminal imprime uma resposta gerada por um modelo na nuvem.

Esse momento parece pequeno, mas muda a forma de pensar. Deixa de ser "ferramenta no navegador" e vira componente do seu sistema — como qualquer outra API que você integra.

Escolha uma linguagem abaixo. Não precisa dominar as três; precisa entender o padrão que se repete em todas.

Node.js (fetch nativo)

// chat.js — Node 18+
const API_KEY = process.env.OPENAI_API_KEY;

async function ask(question) {
  const res = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'gpt-4o-mini',
      messages: [{ role: 'user', content: question }],
      temperature: 0.3,
      max_tokens: 500,
    }),
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error?.message ?? res.statusText);
  }

  const data = await res.json();
  return data.choices[0].message.content;
}

ask('O que é REST em uma frase?').then(console.log);

Execute: OPENAI_API_KEY=sk-... node chat.js

Se aparecer texto no terminal, parabéns — você acabou de fazer o mesmo que o ChatGPT faz por baixo dos panos, só que do seu lado do código.

Python (requests)

import os
import requests

API_KEY = os.environ["OPENAI_API_KEY"]
URL = "https://api.openai.com/v1/chat/completions"

def ask(question: str) -> str:
    response = requests.post(
        URL,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "model": "gpt-4o-mini",
            "messages": [{"role": "user", "content": question}],
            "temperature": 0.3,
            "max_tokens": 500,
        },
        timeout=60,
    )
    response.raise_for_status()
    data = response.json()
    return data["choices"][0]["message"]["content"]

print(ask("O que é REST em uma frase?"))

Mesma lógica, outra sintaxe. O contrato JSON é o que importa.

PHP (cURL)

<?php
$apiKey = getenv('OPENAI_API_KEY');
$payload = json_encode([
    'model' => 'gpt-4o-mini',
    'messages' => [['role' => 'user', 'content' => 'O que é REST em uma frase?']],
    'temperature' => 0.3,
    'max_tokens' => 500,
]);

$ch = curl_init('https://api.openai.com/v1/chat/completions');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 60,
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200) {
    throw new RuntimeException("API error: $response");
}

$data = json_decode($response, true);
echo $data['choices'][0]['message']['content'];

Exercício guiado

  1. Escolha uma linguagem acima
  2. Envie: "Explique idempotência em APIs REST com exemplo HTTP"
  3. Logue usage.total_tokens no console — conecte com a aula anterior
  4. Altere temperature de 0 para 0.9 e compare as duas respostas

O que observar:

Com temperature 0, a explicação tende a ser direta e repetível.
Com 0.9, o modelo pode usar analogias diferentes ou mudar a ordem dos exemplos.

Isso não é bug — é o parâmetro funcionando.

Wrapper mínimo (padrão recomendado)

Antes de espalhar fetch pelo projeto, centralize:

export async function chat(messages, options = {}) {
  // uma função, um lugar para timeout, retry, logging
}

Todo endpoint do seu app chama chat() — nunca fetch espalhado em dez arquivos. Quando precisar mudar modelo, timeout ou provedor, você altera um lugar.

Analogia: chat() é o motorista; os endpoints são os passageiros. Ninguém dirige o carro da API direto do banco de dados.

Resumo

  • Três linguagens, mesmo contrato JSON
  • choices[0].message.content = resposta
  • API key via process.env / os.environ / getenv
  • Encapsule em cliente reutilizável desde o dia 1

Funcionar no script local é o primeiro passo. O segundo — e onde muitos projetos quebram — é tratar erro como adulto. É o assunto da próxima aula.