Stack de deploy que sobe o LibreChat junto a um roteador inteligente que escolhe automaticamente entre Claude Sonnet 4.6 e Gemini 2.5 Flash conforme a complexidade do prompt do usuário.
A interface gráfica é o LibreChat oficial. Por trás dela, um pequeno serviço em FastAPI intercepta cada mensagem, classifica o prompt e despacha a requisição para o modelo mais adequado — sem o usuário precisar escolher na UI.
flowchart LR
U[Navegador] --> LC[librechat:3080]
LC --> R[ai-router:8000]
R -->|prompt complexo| C[Claude Sonnet 4.6]
R -->|prompt trivial| G[Gemini 2.5 Flash]
LC --- M[(MongoDB)]
LC --- MS[(Meilisearch)]
Tudo roda em uma rede Docker interna (librechat_net). Só as portas 3080
(UI) e 8000 (router) são expostas no host.
Orquestra quatro serviços:
| Serviço | Imagem / build | Função |
|---|---|---|
ai-router |
build local de ./router |
Classifica e despacha as requisições |
api |
ghcr.io/danny-avila/librechat-dev:latest |
LibreChat (UI + backend Node.js) |
mongodb |
mongo:latest |
Persistência de usuários e conversas |
meilisearch |
getmeili/meilisearch:v1.7.3 |
Busca textual no histórico |
O serviço api recebe um bind mount adicional:
C:\Users\Rafael\source → /app/workspace, expondo a pasta de código do
host dentro do container.
Microserviço Python (FastAPI + LiteLLM) que expõe um endpoint compatível com a API OpenAI.
main.py— implementaPOST /v1/chat/completionscom streaming SSE.Dockerfile—python:3.11-slim+ uvicorn na porta 8000.requirements.txt—fastapi==0.136.1,uvicorn==0.46.0,litellm==1.83.14.
Registra um único endpoint custom chamado "Arquiteto Dinâmico" apontando
para http://ai-router:8000/v1. O modelo listado na UI (auto-router) é
apenas um rótulo — o roteador ignora esse nome e reclassifica cada prompt
internamente.
Centraliza segredos e flags de configuração. O .env.example documenta o
formato; o .env real nunca deve ser commitado.
Cada requisição que chega em POST /v1/chat/completions passa por dois
passos:
- Triagem. A função
triar_promptenvia o último prompt do usuário ao Gemini 2.5 Flash com instrução curta: responderCLAUDEse o pedido exigir raciocínio complexo, arquitetura, refatoração ou debug profundo; responderGEMINIse for tarefa trivial, tradução, código simples ou conversa geral. - Despacho. Conforme a resposta, o roteador chama
litellm.completionapontando paraanthropic/claude-sonnet-4-6ougemini/gemini-2.5-flash, repassando o histórico completo de mensagens.
A resposta é devolvida como Server-Sent Events (data: {...}\n\n +
data: [DONE]\n\n), no mesmo formato que a API da OpenAI usa — o LibreChat
consome direto sem precisar de adaptação.
Se o classificador falhar por qualquer motivo, o roteador cai em fallback para Gemini e registra o erro no log.
Pré-requisitos: Docker e Docker Compose.
# 1. Clonar o repositório e entrar nele
cd LibreChat
# 2. Criar o .env a partir do exemplo e preencher as chaves
cp .env.example .env
# editar .env e preencher GEMINI_API_KEY, ANTHROPIC_API_KEY,
# JWT_SECRET e JWT_REFRESH_SECRET
# 3. Subir o stack
docker compose up -d
# 4. Acessar a UI
# http://localhost:3080Na primeira execução, criar uma conta na tela de cadastro do LibreChat
(controlado por ALLOW_REGISTRATION). Depois selecionar o endpoint
"Arquiteto Dinâmico" com o modelo auto-router e começar a conversar.
| Variável | Obrigatória | Descrição |
|---|---|---|
ALLOW_REGISTRATION |
não | true libera cadastro de novos usuários, false bloqueia |
ENDPOINTS |
não | Lista de endpoints habilitados na UI; aqui só custom é usado |
JWT_SECRET |
sim | Segredo do JWT do LibreChat — string aleatória forte (64 chars hex) |
JWT_REFRESH_SECRET |
sim | Segredo do refresh token — outra string aleatória forte |
GEMINI_API_KEY |
sim | Chave do Google AI Studio (usada pelo classificador e pelo modelo) |
ANTHROPIC_API_KEY |
sim | Chave do Anthropic Console (usada quando o roteador despacha p/ Claude) |
Sugestões para gerar segredos JWT fortes:
# Linux / macOS
openssl rand -hex 32
# PowerShell
-join ((1..64) | ForEach { '{0:x}' -f (Get-Random -Max 16) })| Porta | Serviço | Exposta no host? |
|---|---|---|
3080 |
LibreChat UI | sim |
8000 |
ai-router | sim |
27017 |
MongoDB | não (rede interna) |
7700 |
Meilisearch | não (rede interna) |
- O modelo
auto-routerexposto pela UI é só um placeholder. O roteador sempre reclassifica o prompt antes de despachar — o nome do modelo vindo do cliente é ignorado. - O classificador também consome cota do Gemini (1 chamada extra por turno). Para conversas com muitas mensagens curtas, isso pode pesar mais que o esperado.
- Os segredos JWT precisam ser fortes — não usar os valores de exemplo do
.env.exampleem produção. - O bind mount
C:\Users\Rafael\source:/app/workspaceé específico desta máquina; ajustar o caminho ao mover o stack para outro host.