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.
439 lines
11 KiB
Markdown
439 lines
11 KiB
Markdown
# 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](https://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
|
|
|
|
```bash
|
|
# Linux
|
|
curl -fsSL https://ollama.com/install.sh | sh
|
|
|
|
# Verificar se está rodando
|
|
ollama --version
|
|
curl http://localhost:11434/api/tags
|
|
```
|
|
|
|
### Download dos Modelos
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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):
|
|
|
|
```bash
|
|
# 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`):
|
|
|
|
```bash
|
|
# ============================================================
|
|
# 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`:
|
|
|
|
```bash
|
|
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`:
|
|
|
|
```yaml
|
|
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`:
|
|
|
|
```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)
|
|
|
|
```bash
|
|
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
|
|
|
|
```yaml
|
|
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)
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```yaml
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# Verificar se está rodando
|
|
systemctl status ollama
|
|
# ou
|
|
ps aux | grep ollama
|
|
|
|
# Reiniciar se necessário
|
|
systemctl restart ollama
|
|
```
|
|
|
|
### Erro: "model not found"
|
|
|
|
```bash
|
|
# 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 `.env` existe e contém `DEEPSEEK_API_KEY=sk-...`
|
|
- Verificar se `spring.config.import: optional:file:.env[.properties]` está no `application.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-size` no `application.yml`
|
|
- Verificar se o Ollama está usando GPU: `ollama run qwen3-embedding --verbose` e checar `eval 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-tokens` em `app.ai.rag`
|
|
- Reduzir `max-history-messages` em `app.ai.chat`
|
|
- Aumentar `chunk-max-chars` (para incluir menos chunks maiores)
|