diff --git a/.env b/.env index 723e228..ed0730d 100644 --- a/.env +++ b/.env @@ -6,9 +6,6 @@ WEBUI_SECRET_KEY=76c7fc044f9e8d6e5eb60b67c82832b67e84739da4827ce1fa7c101ae1a055d DOMAIN=suite.onboardbi.com.br OLLAMA_BASE_URL=http://ollama-ia1upsekrad96at5hq97e4qa:11434 -LLMFIT_BASE_URL=http://llmfit:8000 -LLMFIT_API_KEY=key-arcadia - # ── Superset BI ─────────────────────────────────────────────── SUPERSET_SECRET_KEY=421274b5ba360778a5398d528116a45ea962d1197e3dfc99f36a372ff1025a63 SUPERSET_ADMIN_USERNAME=admin diff --git a/.env.example b/.env.example index 359d87e..6556427 100644 --- a/.env.example +++ b/.env.example @@ -49,13 +49,8 @@ AI_INTEGRATIONS_OPENAI_API_KEY=arcadia-internal # Se Ollama está em outro servidor: OLLAMA_BASE_URL=http://IP_DO_SERVIDOR:11434 OLLAMA_BASE_URL=http://localhost:11434 -# ── IA — LLMFit (modelos fine-tuned locais — habilitar quando disponível) ───── -# LLMFit turbocharge: modelos treinados com dados do seu negócio -# Deixe vazio para desabilitar (LiteLLM cai para Ollama automaticamente) -LLMFIT_BASE_URL= - # ── IA — Providers externos (opt-in — soberania: dados não saem sem configurar) -# Deixe vazio para operação 100% soberana (apenas Ollama + LLMFit) +# Deixe vazio para operação 100% soberana (apenas Ollama) OPENAI_API_KEY= ANTHROPIC_API_KEY= GROQ_API_KEY= diff --git a/CLAUDE.md b/CLAUDE.md index 15241c9..cd19537 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,7 @@ server/ client/ # 66 páginas React shared/schema.ts # Schema do banco (7317 linhas, Drizzle ORM) docker/ - litellm-config.yaml # Roteamento de LLMs (TIER 1: LLMFit, TIER 2: Ollama, TIER 3: externos) + litellm-config.yaml # Roteamento de LLMs (TIER 1: Ollama local, TIER 2: externos) ``` ## Arquitetura de IA @@ -29,9 +29,8 @@ Manus / Agents / Embeddings │ AI_INTEGRATIONS_OPENAI_BASE_URL ▼ LiteLLM :4000 (gateway unificado, loga tudo no banco) - ├──► LLMFit (TIER 1 — fine-tuned, soberano) [slot pronto, comentado] - ├──► Ollama :11434 (TIER 2 — local, padrão) - └──► OpenAI/Anthropic/Groq (TIER 3 — opt-in, só se API key configurada) + ├──► Ollama :11434 (TIER 1 — local, padrão) + └──► OpenAI/Anthropic/Groq (TIER 2 — opt-in, só se API key configurada) ``` **Variáveis chave do Manus:** @@ -96,11 +95,11 @@ arcadia-prod-{contabil,bi,automation,fisco,embeddings}-1 Python services - ✅ Docker dev + prod, LiteLLM gateway ## O que ainda falta -- ❌ LLMFit: slot pronto em `litellm-config.yaml`, só habilitar quando disponível - ❌ Testes automatizados / CI-CD - ❌ Monitoramento (APM, Sentry, métricas) - ❌ Multi-tenancy completo - ❌ Rate limiting em todos os endpoints (parcial) +- ❌ Fine-tuning de modelos locais (dados do Arcádia) ## Comandos úteis ```bash @@ -122,7 +121,6 @@ npm run build ``` SESSION_SECRET, SSO_SECRET # gerar strings seguras em prod AI_INTEGRATIONS_OPENAI_BASE_URL # aponta para LiteLLM -LLMFIT_BASE_URL # LLMFit quando disponível OLLAMA_BASE_URL # Ollama host ou container OPENAI_API_KEY # opcional (soberania: deixar vazio) ``` diff --git a/DEPLOY_COOLIFY.md b/DEPLOY_COOLIFY.md index 9410139..22b8c61 100644 --- a/DEPLOY_COOLIFY.md +++ b/DEPLOY_COOLIFY.md @@ -122,7 +122,6 @@ AUTOMATION_PYTHON_URL=http://automation:8005 OPENAI_API_KEY= ANTHROPIC_API_KEY= GROQ_API_KEY= -LLMFIT_BASE_URL= # habilitar quando LLMFit estiver disponível ``` ### Superset — profile `bi` @@ -256,12 +255,11 @@ Configure backups automáticos no Coolify em **Project → Backups**. ## Stack de IA (LiteLLM + Ollama) -### Três tiers configurados em `docker/litellm-config.yaml` +### Dois tiers configurados em `docker/litellm-config.yaml` ``` -TIER 1 — LLMFit (fine-tuned, soberano) → slot pronto, habilitar via LLMFIT_BASE_URL -TIER 2 — Ollama (local, padrão) → llama3.3, qwen2.5-coder, nomic-embed-text -TIER 3 — Externos (opt-in) → OpenAI, Anthropic, Groq (apenas se API key definida) +TIER 1 — Ollama (local, padrão) → llama3.3, qwen2.5-coder, nomic-embed-text +TIER 2 — Externos (opt-in) → OpenAI, Anthropic, Groq (apenas se API key definida) ``` ### Baixar modelos Ollama após o primeiro deploy @@ -272,12 +270,6 @@ docker exec arcadia-ollama ollama pull qwen2.5-coder:7b docker exec arcadia-ollama ollama pull nomic-embed-text ``` -### Habilitar LLMFit (quando disponível) - -1. Defina `LLMFIT_BASE_URL=http://seu-llmfit:porta` -2. Descomente o bloco TIER 1 em `docker/litellm-config.yaml` -3. Redeploy do serviço `litellm` - --- ## Pós-deploy diff --git a/INTEGRACAO_IA.md b/INTEGRACAO_IA.md index 226791d..2f67962 100644 --- a/INTEGRACAO_IA.md +++ b/INTEGRACAO_IA.md @@ -1,6 +1,6 @@ -# Integração de IA — Ollama + LLMFit no Servidor +# Integração de IA — Ollama no Servidor -Guia para conectar o Arcádia Suite às IAs locais em produção. +Guia para conectar o Arcádia Suite à IA local em produção. --- @@ -13,11 +13,11 @@ Arcádia Suite (Manus, Agents, Embeddings) ▼ LiteLLM (porta 4000) — gateway único │ - ├──► LLMFit (seus modelos fine-tuned) [TIER 1 — prioridade] - └──► Ollama (modelos open source locais) [TIER 2 — padrão/fallback] + ├──► Ollama (modelos open source locais) [TIER 1 — padrão] + └──► OpenAI/Anthropic/Groq (opt-in) [TIER 2 — externo] ``` -Nenhum serviço do Arcádia chama Ollama ou LLMFit diretamente. +Nenhum serviço do Arcádia chama Ollama diretamente. Tudo passa pelo LiteLLM — que roteia, loga e faz fallback automaticamente. --- @@ -89,66 +89,6 @@ docker exec -it $(docker ps -qf "name=ollama") ollama pull deepseek-r1:7b --- -## Configuração do LLMFit - -### 1. Pré-requisito - -O LLMFit deve expor uma API compatível com OpenAI (formato `/v1/chat/completions`). -Verifique se está respondendo: -```bash -curl http://IP_DO_LLMFIT:PORTA/v1/models -``` - -### 2. Configurar variável no Coolify - -``` -LLMFIT_BASE_URL=http://IP_DO_LLMFIT:PORTA -``` - -### 3. Ativar no LiteLLM config - -Edite `docker/litellm-config.yaml` e **descomente** o bloco TIER 1: - -```yaml -model_list: - - # TIER 1 — LLMFit (fine-tuned, prioridade máxima) - - model_name: arcadia-finetuned - litellm_params: - model: openai/NOME_DO_SEU_MODELO # substitua pelo nome real - api_base: os.environ/LLMFIT_BASE_URL - api_key: llmfit-internal - - # Modelo de embeddings fine-tuned (se disponível) - - model_name: arcadia-embed - litellm_params: - model: openai/NOME_DO_MODELO_EMBED - api_base: os.environ/LLMFIT_BASE_URL - api_key: llmfit-internal -``` - -### 4. Definir LLMFit como modelo padrão do Arcádia - -No mesmo arquivo, atualize o `arcadia-default`: - -```yaml - - model_name: arcadia-default - litellm_params: - model: openai/NOME_DO_SEU_MODELO - api_base: os.environ/LLMFIT_BASE_URL - api_key: llmfit-internal - model_info: - fallbacks: ["llama3.3"] # cai para Ollama se LLMFit falhar -``` - -### 5. Reiniciar o LiteLLM para aplicar - -```bash -docker compose -f docker-compose.prod.yml restart litellm -``` - ---- - ## Variáveis de ambiente — resumo completo Configure todas no Coolify antes do deploy: @@ -174,9 +114,6 @@ AI_INTEGRATIONS_OPENAI_API_KEY=${LITELLM_API_KEY} # Ollama em container: http://ollama:11434 OLLAMA_BASE_URL=http://host-gateway:11434 -# ── LLMFit (deixar vazio até estar disponível) ──────────────────────────────── -LLMFIT_BASE_URL= - # ── Providers externos (deixar vazio para soberania total) ─────────────────── OPENAI_API_KEY= ANTHROPIC_API_KEY= @@ -202,7 +139,7 @@ curl http://localhost:4000/v1/chat/completions \ ### 2. Testar Manus via interface Acesse `https://seudominio.com.br` → abra o Manus → envie uma mensagem simples. -O Manus deve responder via Ollama (ou LLMFit se configurado). +O Manus deve responder via Ollama. ### 3. Ver logs em tempo real @@ -253,10 +190,6 @@ docker exec $(docker ps -qf "name=ollama") ollama pull nomic-embed-text → O modelo referenciado em `litellm-config.yaml` não foi baixado no Ollama. → Execute `ollama pull NOME_DO_MODELO` -**LLMFit não está sendo chamado** -→ Confirme que `LLMFIT_BASE_URL` está definido e o serviço está respondendo. -→ Reinicie o LiteLLM após alterar o config: `docker compose restart litellm` - **Ollama no host não é alcançado de dentro do Docker** → Tente `OLLAMA_BASE_URL=http://172.17.0.1:11434` (IP padrão do docker0) → Ou use o IP real da interface de rede: `ip addr show` para descobrir diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 03dd93a..12d28e3 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -283,7 +283,7 @@ services: - arcadia-internal # ── LiteLLM (gateway unificado de LLM — soberania dos dados) ───────────────── - # Roteia: LLMFit (fine-tuned) → Ollama (local) → externo (opt-in) + # Roteia: Ollama (local) → externo (opt-in) litellm: image: ghcr.io/berriai/litellm:main-latest restart: always @@ -297,9 +297,6 @@ services: # Ollama: se instalado no host use http://host-gateway:11434 # Se usar container Docker, mantém http://ollama:11434 OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434} - # LLMFit: URL do serviço de modelos fine-tuned - LLMFIT_BASE_URL: ${LLMFIT_BASE_URL:-} - LLMFIT_API_KEY: ${LLMFIT_API_KEY:-} # Providers externos opcionais (soberania: só habilitados se configurados) ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} GROQ_API_KEY: ${GROQ_API_KEY:-} @@ -322,7 +319,7 @@ services: networks: - arcadia-internal - # ── Open WebUI (interface para Ollama + LLMFit) ─────────────────────────────── + # ── Open WebUI (interface para Ollama) ─────────────────────────────── open-webui: image: ghcr.io/open-webui/open-webui:main restart: always diff --git a/docker-compose.prod.yml.bak b/docker-compose.prod.yml.bak deleted file mode 100644 index af01a8c..0000000 --- a/docker-compose.prod.yml.bak +++ /dev/null @@ -1,237 +0,0 @@ -# ─── Arcádia Suite — Produção (Coolify) ─────────────────────────────────────── -# Este arquivo é usado pelo Coolify para deploy automático. -# NÃO inclui volumes de código-fonte — só artefatos de build. -# Configurar no Coolify: Environment Variables para todas as vars ${...} - -name: arcadia-prod - -services: - - # ── Banco de dados com pgvector ───────────────────────────────────────────── - db: - image: pgvector/pgvector:pg16 - restart: always - environment: - POSTGRES_DB: ${PGDATABASE:-arcadia} - POSTGRES_USER: ${PGUSER:-arcadia} - POSTGRES_PASSWORD: ${PGPASSWORD} - volumes: - - pgdata:/var/lib/postgresql/data - - ./docker/init-pgvector.sql:/docker-entrypoint-initdb.d/01-pgvector.sql - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${PGUSER:-arcadia}"] - interval: 10s - timeout: 5s - retries: 10 - networks: - - arcadia-internal - - # ── Redis ──────────────────────────────────────────────────────────────────── - redis: - image: redis:7-alpine - restart: always - command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru - volumes: - - redis_data:/data - networks: - - arcadia-internal - - # ── App principal ───────────────────────────────────────────────────────── - app: - build: - context: . - dockerfile: Dockerfile - restart: always - environment: - NODE_ENV: production - PORT: 5000 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - REDIS_URL: redis://redis:6379 - DOCKER_MODE: "true" - CONTABIL_PYTHON_URL: http://contabil:8003 - BI_PYTHON_URL: http://bi:8004 - AUTOMATION_PYTHON_URL: http://automation:8005 - FISCO_PYTHON_URL: http://fisco:8002 - PYTHON_SERVICE_URL: http://embeddings:8001 - SESSION_SECRET: ${SESSION_SECRET} - SSO_SECRET: ${SSO_SECRET} - OPENAI_API_KEY: ${OPENAI_API_KEY:-} - LITELLM_BASE_URL: http://litellm:4000 - LITELLM_API_KEY: ${LITELLM_API_KEY} - OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434} - # ── Manus Agent — aponta para LiteLLM como gateway unificado ────────── - # LiteLLM roteia para Ollama (local), LLMFit (fine-tuned) ou externo - AI_INTEGRATIONS_OPENAI_BASE_URL: http://litellm:4000/v1 - AI_INTEGRATIONS_OPENAI_API_KEY: ${LITELLM_API_KEY} - ports: - - "5000:5000" - depends_on: - db: - condition: service_healthy - redis: - condition: service_started - networks: - - arcadia-internal - - arcadia-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.arcadia.rule=Host(`${DOMAIN}`)" - - "traefik.http.routers.arcadia.tls=true" - - "traefik.http.routers.arcadia.tls.certresolver=letsencrypt" - - # ── Microserviços Python ───────────────────────────────────────────────────── - contabil: - build: - context: . - dockerfile: Dockerfile.python - restart: always - environment: - SERVICE_NAME: contabil - SERVICE_PORT: 8003 - CONTABIL_PORT: 8003 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - bi: - build: - context: . - dockerfile: Dockerfile.python - restart: always - environment: - SERVICE_NAME: bi - SERVICE_PORT: 8004 - BI_PORT: 8004 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - automation: - build: - context: . - dockerfile: Dockerfile.python - restart: always - environment: - SERVICE_NAME: automation - SERVICE_PORT: 8005 - AUTOMATION_PORT: 8005 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - fisco: - build: - context: . - dockerfile: Dockerfile.python - restart: always - environment: - SERVICE_NAME: fisco - SERVICE_PORT: 8002 - FISCO_PORT: 8002 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - embeddings: - build: - context: . - dockerfile: Dockerfile.python - restart: always - environment: - SERVICE_NAME: embeddings - SERVICE_PORT: 8001 - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - # ── LiteLLM (gateway unificado de LLM — soberania dos dados) ───────────────── - # Roteia: LLMFit (fine-tuned) → Ollama (local) → externo (opt-in) - litellm: - image: ghcr.io/berriai/litellm:main-latest - restart: always - volumes: - - ./docker/litellm-config.yaml:/app/config.yaml - command: ["--config", "/app/config.yaml", "--port", "4000"] - environment: - OPENAI_API_KEY: ${OPENAI_API_KEY:-} - LITELLM_MASTER_KEY: ${LITELLM_API_KEY} - DATABASE_URL: postgresql://${PGUSER:-arcadia}:${PGPASSWORD}@db:5432/${PGDATABASE:-arcadia} - # Ollama: se instalado no host use http://host-gateway:11434 - # Se usar container Docker, mantém http://ollama:11434 - OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434} - # LLMFit: URL do serviço de modelos fine-tuned - LLMFIT_BASE_URL: ${LLMFIT_BASE_URL:-} - # Providers externos opcionais (soberania: só habilitados se configurados) - ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} - GROQ_API_KEY: ${GROQ_API_KEY:-} - depends_on: - db: - condition: service_healthy - networks: - - arcadia-internal - - # ── Ollama (LLMs locais — soberania total) ──────────────────────────────────── - # OPÇÃO A (padrão): Ollama como container Docker - # OPÇÃO B: Ollama no host → comente este serviço e defina - # OLLAMA_BASE_URL=http://host-gateway:11434 nas env vars - ollama: - image: ollama/ollama:latest - restart: always - volumes: - - ollama_models:/root/.ollama - networks: - - arcadia-internal - # Remova 'profiles: [ai]' para ativar por padrão no deploy - profiles: [ai] - - # ── Open WebUI (interface para Ollama + LLMFit) ─────────────────────────────── - open-webui: - image: ghcr.io/open-webui/open-webui:main - restart: always - environment: - # Pode apontar para LiteLLM para ter acesso a todos os modelos via WebUI - OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434} - OPENAI_API_BASE_URL: http://litellm:4000/v1 - OPENAI_API_KEY: ${LITELLM_API_KEY} - WEBUI_SECRET_KEY: ${WEBUI_SECRET_KEY} - volumes: - - open_webui_data:/app/backend/data - depends_on: - - litellm - networks: - - arcadia-internal - - arcadia-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.webui.rule=Host(`ai.${DOMAIN}`)" - - "traefik.http.routers.webui.tls=true" - - "traefik.http.routers.webui.tls.certresolver=letsencrypt" - - "traefik.http.services.webui.loadbalancer.server.port=8080" - profiles: [ai] - -networks: - arcadia-internal: - driver: bridge - arcadia-public: - driver: bridge - -volumes: - pgdata: - redis_data: - ollama_models: - open_webui_data: diff --git a/docker/litellm-config.yaml b/docker/litellm-config.yaml index 0085857..30f1333 100644 --- a/docker/litellm-config.yaml +++ b/docker/litellm-config.yaml @@ -3,29 +3,15 @@ # # ESTRATÉGIA DE SOBERANIA DOS DADOS: # ┌─────────────────────────────────────────────────────────────────────────┐ -# │ TIER 1 (soberania total): LLMFit — modelos fine-tuned locais │ -# │ TIER 2 (soberania total): Ollama — modelos open source no servidor │ -# │ TIER 3 (opt-in): Providers externos — só com configuração explícita │ +# │ TIER 1 (soberania total): Ollama — modelos open source no servidor │ +# │ TIER 2 (opt-in): Providers externos — só com configuração explícita │ # └─────────────────────────────────────────────────────────────────────────┘ # O Manus, Autonomous Agents e todos os serviços chamam APENAS este proxy. # Nunca chamam APIs externas diretamente. model_list: - # ── TIER 1: LLMFit (modelos fine-tuned locais — máxima soberania) ──────────── - - model_name: arcadia-finetuned - litellm_params: - model: openai/llama3.2:3b - api_base: os.environ/LLMFIT_BASE_URL - api_key: os.environ/LLMFIT_API_KEY - - - model_name: arcadia-embed - litellm_params: - model: openai/nomic-embed-text:latest - api_base: os.environ/LLMFIT_BASE_URL - api_key: os.environ/LLMFIT_API_KEY - - # ── TIER 2: Ollama (LLMs locais — soberania total) ─────────────────────────── + # ── TIER 1: Ollama (LLMs locais — soberania total) ─────────────────────────── - model_name: llama3.2 litellm_params: model: ollama/llama3.2:3b @@ -42,7 +28,7 @@ model_list: model: ollama/nomic-embed-text api_base: os.environ/OLLAMA_BASE_URL - # ── TIER 3: OpenAI (opt-in — só ativo se OPENAI_API_KEY configurado) ───────── + # ── TIER 2: OpenAI (opt-in — só ativo se OPENAI_API_KEY configurado) ───────── - model_name: gpt-4o litellm_params: model: openai/gpt-4o @@ -53,34 +39,30 @@ model_list: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY - # ── TIER 3: Anthropic (opt-in — descomente para habilitar) ─────────────────── + # ── TIER 2: Anthropic (opt-in — descomente para habilitar) ─────────────────── # - model_name: claude-sonnet # litellm_params: # model: anthropic/claude-sonnet-4-6 # api_key: os.environ/ANTHROPIC_API_KEY - # ── TIER 3: Groq (opt-in — inferência rápida sem dados persistidos) ────────── + # ── TIER 2: Groq (opt-in — inferência rápida sem dados persistidos) ────────── # - model_name: groq-llama # litellm_params: # model: groq/llama-3.3-70b-versatile # api_key: os.environ/GROQ_API_KEY # ── Modelo padrão do Arcádia (Manus usa este) ───────────────────────────────── - # Prioridade: LLMFit (TIER 1) → Ollama (TIER 2 — fallback) - model_name: arcadia-default litellm_params: - model: openai/llama3.2:3b - api_base: os.environ/LLMFIT_BASE_URL - api_key: os.environ/LLMFIT_API_KEY + model: ollama/llama3.2:3b + api_base: os.environ/OLLAMA_BASE_URL router_settings: routing_strategy: least-busy - fallbacks: + fallbacks: - {"gpt-4o": ["llama3.2"]} - {"gpt-4o-mini": ["llama3.2"]} - {"arcadia-default": ["llama3.2"]} - - {"arcadia-finetuned": ["llama3.2"]} - - {"arcadia-embed": ["nomic-embed-text"]} litellm_settings: drop_params: true