Como hospedar um chatbot com IA

Um chatbot com IA é uma API sua que recebe a conversa, chama um modelo de linguagem com a chave guardada no servidor e devolve a resposta em streaming. Hospede-a como qualquer API web, em um processo sempre ligado.

Atualizado em 6 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Entender a arquitetura de um chatbot com IA (front, API e modelo)
  • Escrever uma API em FastAPI que responde em streaming
  • Colocar o chatbot no ar protegendo a chave e o custo
Nesta página

Hospedar um chatbot com IA parece um assunto novo, mas a parte que você hospeda é velha conhecida: uma API HTTP. O "cérebro" fica no provedor do modelo (Anthropic, OpenAI, Google). O seu servidor recebe a mensagem, chama o provedor e repassa a resposta.

Isso muda o que importa. Você não precisa de GPU nem de muita memória. Precisa de um processo sempre ligado, uma chave de API bem guardada e proteção contra abuso, porque cada mensagem custa dinheiro.

Navegadorfront-endAPI dochatbotchave em variávelde ambienteProvedordo modeloAPI do LLMPOST /chat1prompt + chave2streaming3texto em streaming4
A chave fica no backend, em variável de ambiente; o navegador só fala com a sua API e recebe o texto em streaming.

Como é a arquitetura de um chatbot com IA?#

São três peças:

  1. Front-end: a tela de chat (um site, um widget, um app). Guarda a conversa e mostra o texto chegando.
  2. Backend (o que você hospeda): uma API com um endpoint como POST /chat. Valida a entrada, adiciona o prompt de sistema, chama o modelo e devolve a resposta.
  3. Provedor do modelo: a API do LLM. Para entender o que ela faz por baixo, veja o que é um LLM.

O backend existe por um motivo central: a chave de API nunca pode ir para o navegador. Quem abrir o DevTools copia a chave. Veja também o que fazer se a chave vazar.

O que você precisa antes de começar?#

  • Uma versão do Python ainda com suporte. A versão mínima exigida pelo SDK da Anthropic, pelo FastAPI e pelo Uvicorn está na documentação de cada um.
  • Uma chave de API do provedor. Aqui usamos a da Anthropic, mas a estrutura é a mesma para qualquer outro.
  • Noção básica de variáveis de ambiente.

Crie a pasta do projeto com um requirements.txt:

text
fastapi
uvicorn
anthropic

Como escrever a API com streaming?#

Sem streaming, o usuário olha para uma tela vazia até o modelo terminar a resposta inteira. Com streaming, o texto aparece conforme é gerado. O SDK da Anthropic expõe isso com client.messages.stream e text_stream, e o FastAPI repassa com StreamingResponse.

python
import os
from typing import Literal

from anthropic import AsyncAnthropic
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pydantic import BaseModel, Field

client = AsyncAnthropic()  # lê ANTHROPIC_API_KEY do ambiente
MODEL = os.environ["ANTHROPIC_MODEL"]  # sem ela, o app falha ao iniciar com KeyError
SYSTEM = "Você é o assistente da loja Exemplo. Responda em português, de forma curta."

app = FastAPI()


class Msg(BaseModel):
    role: Literal["user", "assistant"]
    content: str = Field(max_length=4000)


class ChatIn(BaseModel):
    messages: list[Msg] = Field(min_length=1, max_length=20)


@app.post("/chat")
async def chat(body: ChatIn):
    async def stream_text():
        async with client.messages.stream(
            model=MODEL,
            max_tokens=1024,
            system=SYSTEM,
            messages=[m.model_dump() for m in body.messages],
        ) as stream:
            async for text in stream.text_stream:
                yield text

    return StreamingResponse(stream_text(), media_type="text/plain; charset=utf-8")


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", "8000")))

Salve o código como main.py. O que vale notar:

  • A API é sem estado. O front manda a conversa inteira a cada requisição, e o modelo não "lembra" de nada entre chamadas. Os limites de 20 mensagens e 4.000 caracteres seguram o custo e o tamanho do contexto.
  • O modelo é configuração, não código. A Anthropic aposenta modelos com o tempo, então o ID fica na variável ANTHROPIC_MODEL, sem valor padrão: se ela faltar, o app para logo ao iniciar, em vez de falhar na primeira mensagem. Copie o ID da lista de modelos da Anthropic. Para tarefas de alto volume e baixa latência, a escolha costuma ser um modelo pequeno, rápido e barato, como os da linha Haiku.
  • max_tokens é obrigatório na API e funciona como teto de custo por resposta.
  • O bloco final permite iniciar com python main.py, escutando em 0.0.0.0 na porta da variável PORT (8000 se ela não existir).

Teste local:

bash
pip install -r requirements.txt
export ANTHROPIC_API_KEY="cole-sua-chave-aqui"
export ANTHROPIC_MODEL="id-de-um-modelo-pequeno"
uvicorn main:app --port 8000
curl -N -X POST localhost:8000/chat \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Oi, tudo bem?"}]}'

O -N desliga o buffer do curl, então você vê o texto chegar aos poucos.

Como o front-end lê a resposta em streaming?#

No navegador, fetch já expõe o corpo como um stream:

javascript
async function ask(messages, onText) {
  const res = await fetch("/chat", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ messages }),
  });
  if (!res.ok || !res.body) throw new Error(`Erro ${res.status}`);

  const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
  for (;;) {
    const { value, done } = await reader.read();
    if (done) break;
    onText(value);
  }
}

Chame ask com o histórico e acrescente cada pedaço (onText) à bolha da resposta. Se o front estiver em outro domínio, configure o CORS no FastAPI para aceitar só a origem do seu site.

Como proteger a chave e o custo?#

Um endpoint de chat público atrai abuso. Antes de divulgar o link:

  • Chave só em variável de ambiente, nunca no código nem no repositório.
  • Limite de requisições por IP ou por usuário, aplicado na borda ou com uma biblioteca no FastAPI.
  • Teto de gasto no painel do provedor. É a rede de segurança se o limite do seu código falhar.
  • Exija autenticação se o bot é de uso interno ou de clientes.
  • Trate o texto do usuário como não confiável. Alguém pode tentar fazer o modelo ignorar o prompt de sistema. Leia o que é prompt injection antes de dar ferramentas ou dados sensíveis ao modelo.

Para estimar a conta, veja quanto custa uma API de LLM.

O que o servidor precisa ter para hospedar isso?#

  • Processo sempre ligado. Plataformas que suspendem o app por inatividade deixam a primeira resposta lenta. Para chat, prefira um container que não hiberna.
  • HTTPS. O navegador bloqueia chamadas inseguras a partir de páginas HTTPS.
  • Suporte a respostas em streaming. Proxies que fazem buffer da resposta quebram o efeito. Teste com curl -N já no ambiente final.
  • Pouca RAM. O servidor só repassa texto, então o consumo é baixo. Meça com carga real e veja como dimensionar RAM e CPU.
  • Logs. Você vai precisar deles para descobrir por que o provedor devolveu erro 429 ou 5xx. Para o framework em si, veja hospedar FastAPI, Flask e Django.

Quais erros são comuns?#

  • Streaming que chega tudo de uma vez: há um proxy ou compressão fazendo buffer entre o app e o navegador. Teste direto no app com curl -N.
  • Erro 401 do provedor: a variável ANTHROPIC_API_KEY não foi definida no ambiente de produção.
  • Erro 404 ou "model not found": o ID em ANTHROPIC_MODEL está errado ou o modelo foi aposentado. Escolha outro na lista oficial e reinicie o app, sem mexer no código.
  • Erro 422 do FastAPI: o corpo não bate com o modelo Pydantic (por exemplo, role fora de user/assistant, ou conversa vazia).
  • Conta alta no fim do mês: falta limite por usuário ou max_tokens alto demais. Veja a seção de proteção.

Como fazer isso na Square Cloud#

A seção sobre o servidor pediu processo sempre ligado, HTTPS, streaming sem buffer e logs. Na Square Cloud, a API roda num container isolado e sempre ligado, sem cold start nem modo de suspensão, e toda aplicação web ganha um subdomínio *.squareweb.app com HTTPS. O proxy na frente da aplicação não corta conexões longas e deixa SSE e WebSocket passarem sem buffer; mesmo assim, repita o teste com curl -N no subdomínio.

  1. Envie main.py e requirements.txt por upload de ZIP no painel, CLI, GitHub ou extensão do VS Code. No start, a plataforma instala o requirements.txt. O arquivo squarecloud.app é opcional: o painel o gera no deploy, ou você o escreve na raiz do projeto.
  2. Escolha main.py como arquivo principal. O bloco final do código já escuta em 0.0.0.0, na porta da variável PORT, que a plataforma define. Uma aplicação web usa pelo menos 512 MB do pool de RAM do plano.
  3. Cadastre ANTHROPIC_API_KEY e ANTHROPIC_MODEL nas variáveis de ambiente da aplicação. A mudança vale no próximo restart, sem rebuild.
  4. Acompanhe os logs em tempo real para ver os erros 429 ou 5xx do provedor.

Se você preferir não manter uma conta num provedor de modelo, o AI Gateway, disponível a partir do plano Standard (R$ 44,99 por mês), é uma API compatível com a da OpenAI para o modelo cubic, em beta com acesso antecipado sem custo extra. Com o SDK openai, você usa a base URL https://api.squarecloud.app/v2/ai, uma chave da conta com o escopo ai:chat e model="cubic"; o modelo também pode chamar funções suas (até 32 tools) e buscar na web por conta própria. Para este chatbot há duas ressalvas: o gateway ainda não faz streaming, então a resposta chega inteira no fim; e o Standard atende uma requisição por vez, até 1.000 por dia. Um chat público com muitos visitantes simultâneos continua mais bem servido por um provedor com streaming. Limites e planos podem mudar quando o beta acabar.

O Hobby, a partir de R$ 12,49 por mês, hospeda a API, mas não inclui o gateway. Veja os planos em hospedagem de APIs.

IA

Hospede apps com IA em containers sempre ligados

Saiba mais

Perguntas frequentes

Preciso de GPU para hospedar um chatbot com IA?

Não, se você usa um modelo por API (Claude, GPT, Gemini). Quem roda a inferência é o provedor, e o seu servidor só repassa texto. GPU só entra se você mesmo hospedar um modelo aberto.

Posso chamar a API do modelo direto do navegador?

Não. A chave ficaria visível para qualquer visitante e outra pessoa poderia gastar o seu crédito. A chamada tem de sair de um backend seu.

Quanta memória um chatbot desses usa?

Pouca, porque ele só repassa texto. Meça com carga real antes de dimensionar.

Como evito que alguém gaste meu crédito de IA?

Limite requisições por IP ou por usuário, limite o tamanho da conversa e o max_tokens, e configure um teto de gasto no painel do provedor.

Próximo artigoQuanto custa usar a API de um LLM no seu bot ou appA API de um LLM cobra por token, e a saída custa mais que a entrada. Veja uma conta passo a passo para um bot e como cortar o gasto.