Construindo um Chatbot

Backend da Conversa

Endpoint REST, montagem de messages, chamada ao LLM e retorno JSON para o frontend.

Intermediário 25 min 30 pontos Leitura 0%

Nesta aula você vai

  • Criar POST /api/chat com validação de entrada
  • Montar array messages com system prompt
  • Retornar JSON padronizado ao cliente

Backend da Conversa

Objetivos

  • Fechar fluxo completo cliente → servidor → LLM → cliente
  • Endpoint production-ready mínimo

Express (Node.js)

import express from 'express';
import { chat } from './llmClient.js';

const app = express();
app.use(express.json({ limit: '16kb' }));

const SYSTEM = `Você é assistente da Minha Loja.
Responda em português, tom profissional, máximo 150 palavras.`;

app.post('/api/chat', async (req, res) => {
  const { message } = req.body;

  if (!message || typeof message !== 'string' || message.length > 2000) {
    return res.status(400).json({ error: 'Mensagem inválida.' });
  }

  try {
    const reply = await chat(
      [
        { role: 'system', content: SYSTEM },
        { role: 'user', content: message },
      ],
      { temperature: 0.4, max_tokens: 300 },
    );

    res.json({ reply });
  } catch (err) {
    console.error(err);
    res.status(503).json({ error: 'Serviço indisponível.' });
  }
});

app.listen(3000);

PHP (endpoint slim)

<?php
header('Content-Type: application/json');
$body = json_decode(file_get_contents('php://input'), true);
$message = trim($body['message'] ?? '');

if ($message === '' || strlen($message) > 2000) {
    http_response_code(400);
    echo json_encode(['error' => 'Mensagem inválida.']);
    exit;
}

// chame wrapper LLM...
echo json_encode(['reply' => $resposta]);

Contrato de API

Documente para o frontend:

POST /api/chat
Body: { "message": string }
200: { "reply": string }
400: { "error": string }
503: { "error": string }

Session ID (preview matéria 5)

// Gere no primeiro acesso, guarde em cookie httpOnly
const sessionId = req.cookies.chat_session ?? crypto.randomUUID();
res.cookie('chat_session', sessionId, { httpOnly: true, sameSite: 'lax' });
// Próxima aula: carregar histórico por sessionId

CORS

Se frontend em outro domínio:

app.use(cors({ origin: 'https://app.suaempresa.com', credentials: true }));

Resumo

  • Um endpoint, uma responsabilidade: validar → chamar LLM → responder JSON
  • System prompt fixo no servidor
  • Valide tamanho e tipo da entrada
  • Cookie/session prepara histórico na próxima matéria