Comprehensive documentation for the AI module covering architecture, API design, data model, RAG pipeline, configuration, integration points, and frontend integration guide. Includes IDA5 extraction points reference and AGENTS.md with project conventions and coding standards.
11 KiB
11 KiB
Guia de Configuração — Módulo AI
Pré-requisitos
| Componente | Como obter | Status |
|---|---|---|
| Ollama (host) | curl -fsSL https://ollama.com/install.sh | sh |
Local, necessário |
| qwen3-embedding | ollama pull qwen3-embedding:latest |
Modelo de embedding |
| gemma4:12b | ollama pull gemma4:12b |
LLM para chat local |
| DeepSeek API key | platform.deepseek.com | LLM cloud (opcional) |
| PostgreSQL + pgvector | docker compose up -d postgres |
Já configurado |
| RabbitMQ | docker compose up -d rabbit-mq |
Já configurado |
1. Setup do Ollama (Host)
Instalação
# Linux
curl -fsSL https://ollama.com/install.sh | sh
# Verificar se está rodando
ollama --version
curl http://localhost:11434/api/tags
Download dos Modelos
# Embedding (4.7 GB)
ollama pull qwen3-embedding:latest
# Chat local (7.6 GB)
ollama pull gemma4:12b
# Alternativa menor para máquinas com pouca RAM (9.6 GB, MoE)
# ollama pull gemma4:e4b
# Verificar modelos instalados
ollama list
Hardware recomendado:
| Modelo | RAM mínima | RAM recomendada | GPU VRAM (opcional) |
|---|---|---|---|
qwen3-embedding:latest (8B) |
8 GB | 16 GB | 6 GB |
gemma4:12b |
10 GB | 16 GB | 8 GB |
gemma4:e4b |
6 GB | 12 GB | 6 GB |
Configuração do Ollama
Por padrão, o Ollama escuta em localhost:11434. Se precisar acessar de outro host:
# Editar /etc/systemd/system/ollama.service ou usar env var
export OLLAMA_HOST=0.0.0.0:11434
Para otimizar performance com GPU (se disponível):
# Verificar se GPU está sendo usada
ollama run gemma4:12b --verbose
# Saída: "total duration: ..." — procure por "eval rate: XX tokens/s"
2. Arquivo .env
Criar na raiz do projeto (backend/.env):
# ============================================================
# Decompile-AI — Environment Variables
# ============================================================
# --- LLM Providers ---
# DeepSeek API Key (obter em https://platform.deepseek.com)
DEEPSEEK_API_KEY=sk-your-api-key-here
# --- Override de modelos (opcional) ---
# Provedor padrão de chat: ollama | deepseek
AI_DEFAULT_CHAT_PROVIDER=ollama
# Modelo de chat Ollama (padrão: gemma4:12b)
# AI_CHAT_MODEL_OLLAMA=gemma4:12b
# Modelo de chat DeepSeek (padrão: deepseek-chat)
# AI_CHAT_MODEL_DEEPSEEK=deepseek-chat
# Modelo de embedding (padrão: qwen3-embedding:latest)
# AI_EMBEDDING_MODEL=qwen3-embedding:latest
# Dimensão do embedding (padrão: 1024, max 4096 para qwen3)
# AI_EMBEDDING_DIMENSION=1024
# --- Database ---
# Sobrescrever credenciais do Postgres se necessário
# SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/decompile_ai
# SPRING_DATASOURCE_USERNAME=decompile_ai
# SPRING_DATASOURCE_PASSWORD=decompile_ai
Importante: Adicione .env ao .gitignore:
echo ".env" >> .gitignore
3. Carregamento do .env
O Spring Boot precisa saber como carregar o .env. Opções:
Opção A: spring.config.import (nativo Spring Boot)
Adicionar ao application.yml:
spring:
config:
import: optional:file:.env[.properties]
Isso carrega o .env como um arquivo de propriedades. Limitação: não suporta substituição de variáveis inline como ${VAR} dentro de outras variáveis no .env, mas funciona bem para definir valores.
Opção B: Plugin dotenv (recomendado para desenvolvimento)
Adicionar dependência ao pom.xml:
<dependency>
<groupId>me.paulschwarz</groupId>
<artifactId>spring-dotenv</artifactId>
<version>4.0.0</version>
</dependency>
Suporta interpolação de variáveis e convenção .env padrão.
Opção C: Export manual (desenvolvimento)
set -a && source .env && set +a
./mvnw spring-boot:run
4. application.yml — Configuração do Módulo AI
Blocos a adicionar ao arquivo existente
spring:
# ... configurações existentes (datasource, jpa, flyway, rabbitmq) ...
ai:
ollama:
base-url: http://localhost:11434
embedding:
options:
model: ${AI_EMBEDDING_MODEL:qwen3-embedding:latest}
chat:
options:
model: ${AI_CHAT_MODEL_OLLAMA:gemma4:12b}
temperature: 0.3 # respostas determinísticas para análise técnica
top-p: 0.95
top-k: 64
openai:
base-url: https://api.deepseek.com
api-key: ${DEEPSEEK_API_KEY}
chat:
options:
model: ${AI_CHAT_MODEL_DEEPSEEK:deepseek-chat}
temperature: 0.3
max-tokens: 4096
app:
# ... configurações existentes (storage, rabbitmq, docker, die, engines) ...
ai:
# Provedor padrão de chat quando a sessão não especifica modelo
default-chat-provider: ${AI_DEFAULT_CHAT_PROVIDER:ollama}
# --- Configurações de Embedding ---
embedding:
# Dimensão do vetor (qwen3-embedding suporta 32-4096)
# DEVE corresponder à coluna vector(N) na migration V008
dimension: ${AI_EMBEDDING_DIMENSION:1024}
# Tamanho máximo do chunk em caracteres
chunk-max-chars: 3000
# Quantas funções processar por batch na API de embedding
batch-size: 20
# --- Configurações de RAG ---
rag:
# Quantos chunks retornar na busca semântica
top-k: 10
# Similaridade mínima para incluir um chunk (0.0 a 1.0)
similarity-threshold: 0.6
# Máximo de tokens de contexto enviados à LLM
max-context-tokens: 8000
# --- Configurações de Chat ---
chat:
# Quantas mensagens de histórico incluir no prompt
max-history-messages: 20
# Temperatura padrão para geração
temperature: 0.3
Configuração completa do application.yml (após merge)
spring:
threads:
virtual:
enabled: true
application:
name: decompile-ai
config:
import: optional:file:.env[.properties]
datasource:
url: jdbc:postgresql://localhost:5432/decompile_ai
username: decompile_ai
password: decompile_ai
jpa:
hibernate:
ddl-auto: validate
flyway:
enabled: true
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
ai:
ollama:
base-url: http://localhost:11434
embedding:
options:
model: ${AI_EMBEDDING_MODEL:qwen3-embedding:latest}
chat:
options:
model: ${AI_CHAT_MODEL_OLLAMA:gemma4:12b}
temperature: 0.3
top-p: 0.95
top-k: 64
openai:
base-url: https://api.deepseek.com
api-key: ${DEEPSEEK_API_KEY}
chat:
options:
model: ${AI_CHAT_MODEL_DEEPSEEK:deepseek-chat}
temperature: 0.3
max-tokens: 4096
app:
storage:
upload-dir: ./uploads/binaries
rabbitmq:
exchange: decompile.jobs
queue: decompile.jobs.queue
routing-key: decompile.jobs.created
docker:
enabled: true
die:
image: decompile-ai/diec:latest
timeout-seconds: 60
docker-host: unix:///var/run/docker.sock
engines:
ida5:
image: decompile-ai/ida5:latest
timeout-seconds: 300
ghidra:
image: decompile-ai/ghidra:latest
timeout-seconds: 600
ai:
default-chat-provider: ${AI_DEFAULT_CHAT_PROVIDER:ollama}
embedding:
dimension: ${AI_EMBEDDING_DIMENSION:1024}
chunk-max-chars: 3000
batch-size: 20
rag:
top-k: 10
similarity-threshold: 0.6
max-context-tokens: 8000
chat:
max-history-messages: 20
temperature: 0.3
logging:
level:
org.springframework.modulith: DEBUG
ai.decompile.ai: DEBUG # Logs do módulo AI
org.springframework.ai: INFO # Logs do Spring AI
5. docker-compose.yml (sem alterações)
O docker-compose.yml atual já atende todos os requisitos:
services:
postgres:
container_name: decompile-ai-postgres
image: pgvector/pgvector:pg18 # PostgreSQL 18 + pgvector nativo
environment:
- POSTGRES_USER=decompile_ai
- POSTGRES_PASSWORD=decompile_ai
- POSTGRES_DB=decompile_ai
ports:
- "5432:5432"
volumes:
- postgres:/var/lib/postgresql
networks:
- decompile-ai-network
rabbit-mq:
container_name: decompile-ai-rabbitmq
image: rabbitmq:4-management
ports:
- "5672:5672"
- "15672:15672"
networks:
- decompile-ai-network
networks:
decompile-ai-network:
driver: bridge
volumes:
postgres:
Não adicionamos Ollama ao docker-compose porque ele roda no host.
6. Startup
Ordem de inicialização
# 1. Infraestrutura Docker
docker compose up -d postgres rabbit-mq
# 2. Verificar Ollama no host
ollama list
# Deve mostrar: qwen3-embedding:latest, gemma4:12b
# 3. Configurar .env
cp .env.example .env
# Editar com a DEEPSEEK_API_KEY
# 4. Iniciar o backend
./mvnw spring-boot:run
# 5. Verificar health
curl http://localhost:8080/actuator/health
Verificação de saúde dos componentes AI
# Ollama
curl http://localhost:11434/api/tags | jq '.models[].name'
# Testar embedding
curl http://localhost:11434/api/embed -d '{
"model": "qwen3-embedding:latest",
"input": "test"
}' | jq '.embeddings[0] | length'
# Deve retornar 1024 (ou dimensão configurada)
# Testar chat local
curl http://localhost:11434/api/chat -d '{
"model": "gemma4:12b",
"messages": [{"role": "user", "content": "Hello"}],
"stream": false
}' | jq '.message.content'
7. Troubleshooting
Ollama não responde
# Verificar se está rodando
systemctl status ollama
# ou
ps aux | grep ollama
# Reiniciar se necessário
systemctl restart ollama
Erro: "model not found"
# Listar modelos disponíveis
ollama list
# Baixar modelo faltante
ollama pull qwen3-embedding:latest
ollama pull gemma4:12b
Erro: "DeepSeek API key not configured"
- Verificar se
.envexiste e contémDEEPSEEK_API_KEY=sk-... - Verificar se
spring.config.import: optional:file:.env[.properties]está noapplication.yml - Alternativa:
export DEEPSEEK_API_KEY=sk-...no terminal
Erro: "relation 'vector_store' does not exist"
- Verificar se Flyway rodou a migration V008:
SELECT * FROM flyway_schema_history; - Rodar manualmente se necessário:
./mvnw flyway:migrate
Erro: "column 'embedding' type vector not supported"
- Verificar se a extensão pgvector está ativada:
SELECT * FROM pg_extension WHERE extname = 'vector'; - Ativar manualmente:
CREATE EXTENSION IF NOT EXISTS vector;
Performance lenta nos embeddings
- Reduzir
batch-sizenoapplication.yml - Verificar se o Ollama está usando GPU:
ollama run qwen3-embedding --verbosee checareval rate - Sem GPU, o modelo 8B pode ser lento para centenas de funções (esperar 2-5 minutos)
Contexto da LLM estourando
- Reduzir
max-context-tokensemapp.ai.rag - Reduzir
max-history-messagesemapp.ai.chat - Aumentar
chunk-max-chars(para incluir menos chunks maiores)