TP2: O Oráculo RAG

Bancos Vetoriais, Busca Semântica e Spring AI (Fase 3 do Pipeline)

Conteúdo de estudo sobre TP2: O Oráculo RAG para a disciplina de Inteligência Artificial II (Prof. Aléssio M. Jr).
Data de Publicação

08/09/2026

Data de Modificação

02/09/2026

🧭 Por que este TP existe?

No TP1, vocês construíram um classificador que prevê as skills de um exercício. Mas prever skills é apenas a Fase 2 do Pipeline WOKDEX. Na Fase 4, o Agente de I.A. vai precisar gerar cenários de teste do tipo MISCONCEPTION — e ele não pode inventar esses cenários do nada, senão ele alucina (produz informações plausíveis mas incorretas).

Para evitar alucinações, o agente precisa de memória: um banco de dados de exercícios reais que ele possa consultar antes de criar algo novo. Quando o agente recebe um exercício sobre “divisão”, ele precisa poder perguntar: “Quais exercícios parecidos com este já existem no corpus? Quais misconceptions já foram mapeadas para problemas de divisão?”

Essa técnica se chama RAG (Retrieval-Augmented Generation) — Geração Aumentada por Recuperação. É a técnica mais utilizada pela indústria atualmente para fazer I.A. Generativa funcionar com dados reais sem alucinar.

A missão do TP2 é construir o Oráculo: um microsserviço em Java + Spring Boot que armazena o corpus WOKDEX num Banco de Dados Vetorial e devolve exercícios similares via busca semântica.


📖 Leitura Obrigatória (Fundamentação)

Antes de programar, vocês precisam ler e entender estes dois artigos científicos. Eles serão a base do Draft 2 na seção de Trabalhos Relacionados.

Artigo 1: Lewis, P. et al. (2020). “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”. arXiv:2005.11401

Por que ler: Este é O paper que inventou o RAG. Publicado pelo Facebook AI Research, ele demonstra formalmente que buscar documentos relevantes antes de gerar texto reduz drasticamente as alucinações de LLMs. É leitura obrigatória para qualquer engenheiro de I.A. em 2026. O conceito de “Retrieve → Augment → Generate” que vocês implementarão no Spring AI vem diretamente deste paper.

Artigo 2: Mikolov, T. et al. (2013). “Efficient Estimation of Word Representations in Vector Space”. arXiv:1301.3781

Por que ler: Este é o paper do Word2Vec, a pesquisa do Google que revolucionou o NLP ao mostrar que palavras podem ser representadas como vetores numéricos em um espaço geométrico. Sem entender esse conceito, você não sabe o que está sendo salvo no Banco Vetorial. Quando o Spring AI converte um enunciado em um vetor de 1536 dimensões, ele está usando uma evolução direta do Word2Vec.


🔄 O que é RAG? (Retrieval-Augmented Generation)

RAG é um padrão arquitetural que funciona em 4 passos:

  1. Ingestão: Os documentos (os arquivos .md do corpus WOKDEX) são lidos e “quebrados” em pedaços menores (chunks).
  2. Embedding: Cada chunk é convertido num vetor numérico de alta dimensão (ex: 1536 dimensões) usando um modelo de embeddings (como o OpenAI ADA-002 ou similar).
  3. Armazenamento: Os vetores são salvos num Banco de Dados Vetorial (como ChromaDB, PGVector ou Neo4j) que permite busca por similaridade geométrica (KNN — K vizinhos mais próximos).
  4. Recuperação (Retrieve): Quando chega uma pergunta (“exercícios sobre divisão”), o sistema converte a pergunta em vetor e busca os K vetores mais próximos no banco. Os documentos correspondentes são injetados como contexto no prompt do LLM.

[!NOTE] O nome “Oráculo” vem do fato de que este serviço sabe a resposta antes de perguntar ao LLM: ele recupera documentos reais verificados. O LLM então raciocina sobre esses documentos, não sobre seu conhecimento genérico.


📦 O que você vai indexar?

A base de conhecimento a ser ingerida no Banco de Dados Vetorial é o Dataset Canônico Bilíngue (PT-BR) (database/leetcode_problems_pt.json ou CSV), contendo 2.830 problemas de programação.

  • Documento a ser Vetorizado (Chunk Textual Enriquecido): A concatenação recomendada para maximizar a fidelidade algorítmica e semântica:

    documento = f"[Tópicos: {topics}] [Dificuldade: {difficulty}]\n{title_pt}\n\n{description_pt}"
  • Metadados Anexados a cada Vetor (Payload):

    • id: Identificador numérico do problema.
    • title_pt: Título em português.
    • difficulty: Dificuldade (Easy, Medium, Hard).
    • topics: Lista de skills/tópicos algorítmicos.
    • hints_pt: Dicas didáticas oficiais traduzidas.
    • acceptance_rate: Taxa de aceitação histórica.

[!TIP] Engenharia de Embeddings: Embutir os tópicos canônicos e o nível no início do chunk antes de gerar o vetor ajuda a busca semântica a não cair na Armadilha da Similaridade Superficial (agrupar problemas apenas pela historinha/metáfora em vez da estrutura técnica subjacente).

A busca semântica vai recuperar exercícios por proximidade de significado vetorial, não por busca exata de palavras.

Data Limite de Entrega (Checkpoint 2): 26/10 (Segunda-feira)

Valor: 10 Pontos (5 em Grupo, 5 Individual)


🧠 Modelo de Embedding (Definição)

Para converter textos em vetores de alta dimensionalidade em Português, o grupo utilizará um dos modelos abaixo, conforme sorteio ou definição do grupo:

Modelo Dimensões Custo / Execução Observação
paraphrase-multilingual-MiniLM-L12-v2 384 🆓 Gratuito (Local) Excelente suporte multilíngue nativo (PT-BR). Roda localmente sem chave de API.
text-embedding-3-small (OpenAI) 1536 💰 Pago / Cota Alta fidelidade semântica para textos técnicos e código.
models/text-embedding-004 (Google) 768 💰 Pago / Cota Modelo robusto do ecossistema Gemini.

[!TIP] 🚀 Starter Template Fornecido pelo Professor:
Para mitigar o salto cognitivo e evitar que a equipe perca tempo com configurações de injeção de dependência e pom.xml, o professor fornecerá o repositório base wokdex-oracle-starter (Spring Boot 3.x + Spring AI + PGVector). O foco da equipe será implementar a lógica de domínio nas interfaces de serviço (IngestionService e SearchService).


👥 A Divisão de Tarefas na Equipe (4 Alunos)

Sua equipe deverá se dividir em duas grandes forças-tarefa.

📚 Dupla 1: Ingestão e Vetorização (O Dado)

Essa dupla foca na extração e na modelagem estrutural do Banco de Dados Vetorial.

  • Aluno A (Engenheiro de Ingestão e Chunking):
    • Trabalho Individual: Criar o pipeline de Ingestão (ETL) que lê o arquivo leetcode_problems_pt.json (ou CSV), extrai o texto em português (title_pt + "\n\n" + description_pt) e programa os Splitters para aplicar técnicas precisas de Chunking preservando blocos de exemplos e restrições.
  • Aluno B (Arquiteto de VectorDB):
    • Trabalho Individual: Sobe e administra o servidor do Banco de Dados Vetorial (VectorDB, ex: PGVector/PostgreSQL, ChromaDB, Qdrant ou Milvus). Configura a persistência em disco, mapeia as coleções vetoriais e é o responsável pela eficiência da indexação de alta dimensão (HNSW / IVFFlat).

☕ Dupla 2: Spring Boot e IA (O Servidor)

Essa dupla constrói o wrapper corporativo, a API robusta que serve os dados para consumo final.

  • Aluno C (Desenvolvedor Spring MVC):
    • Trabalho Individual: Constrói a espinha dorsal web da aplicação em Java (Spring Boot 3.x a partir do starter fornecido). Define os DTOs de entrada e saída, e constrói o robusto @ControllerAdvice para tratamento seguro de exceções.
  • Aluno D (Engenheiro Spring AI / Orquestrador RAG):
    • Trabalho Individual: Utilizando a biblioteca Spring AI, liga todas as peças. Conecta-se ao modelo de Embeddings, dispara o vetor de consulta, realiza o Retrieve (Busca Vetorial por Similaridade de Cosseno) no banco do Aluno B, processa os Prompts de contexto e devolve o pacote formatado para a camada Web.

[!TIP] 🤝 Dinâmica de Pareamento (Pair Programming) e Desenvolvimento Não-Bloqueante:
A Dupla 2 (Spring Boot) não precisa esperar a Dupla 1 concluir a ingestão completa de todos os 2.830 vetores para começar a programar a API.
1. A Dupla 2 pode usar um SimpleVectorStore (em memória) do Spring AI com 5 problemas simulados (mock) para programar os DTOs, a camada de Controllers e os testes de integração imediatamente. 2. Enquanto isso, a Dupla 1 finaliza o pipeline de ETL e a persistência no PGVector. 3. Os membros da dupla devem parear ativamente para garantir compatibilidade dos DTOs e resolver dependências de ambiente em conjunto.


🔌 A API que você vai construir

O produto final de engenharia do TP2 é uma API REST que recebe uma consulta textual e retorna os exercícios mais similares do corpus. Abaixo está o contrato exato:

Requisição: GET /search?q=inverter+lista+encadeada&k=3

Resposta esperada:

{
  "query": "inverter lista encadeada",
  "results": [
    {
      "exercise_id": 206,
      "title": "Reverse Linked List",
      "similarity_score": 0.94,
      "topics": ["Linked List", "Recursion"],
      "difficulty": "Easy",
      "snippet": "Dada a cabeça de uma lista encadeada simplesmente encadeada, inverta a lista e retorne a lista invertida..."
    },
    {
      "exercise_id": 92,
      "title": "Reverse Linked List II",
      "similarity_score": 0.86,
      "topics": ["Linked List"],
      "difficulty": "Medium",
      "snippet": "Dada a cabeça de uma lista encadeada e dois inteiros left e right onde left <= right, inverta os nós da lista..."
    },
    {
      "exercise_id": 24,
      "title": "Swap Nodes in Pairs",
      "similarity_score": 0.75,
      "topics": ["Linked List", "Recursion"],
      "difficulty": "Medium",
      "snippet": "Dada uma lista encadeada, troque cada dois nós adjacentes e retorne sua cabeça..."
    }
  ],
  "search_time_ms": 42
}

[!IMPORTANT] No TP3, o Agente Autônomo vai chamar esta API como uma ferramenta (search_similar_cases()). Se o seu Spring Boot não estiver de pé e respondendo neste formato, o agente não tem contexto e vai alucinar.


🐳 Orquestração Segura via Docker Compose (Multi-Arch & Leve)

Para garantir que o ambiente suba sem conflitos em qualquer sistema operacional (Linux, Windows WSL2 ou macOS Apple Silicon), utilize a seguinte configuração padronizada de docker-compose.yml:

version: '3.8'

services:
  # 1. Banco de Dados Vetorial (PostgreSQL com PGVector)
  vectordb:
    image: pgvector/pgvector:pg16
    container_name: wokdex-vectordb
    restart: always
    environment:
      POSTGRES_DB: wokdex_vectors
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password123
    ports:
      - "5433:5432"  # Porta 5433 evita conflito com Postgres local do aluno
    volumes:
      - pgdata:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          memory: 512M  # Proteção para não esgotar RAM

  # 2. Servidor Spring Boot + Spring AI
  app-oracle:
    build: .
    container_name: wokdex-oracle-api
    depends_on:
      - vectordb
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://vectordb:5432/wokdex_vectors
      SPRING_DATASOURCE_USERNAME: postgres
      SPRING_DATASOURCE_PASSWORD: password123
    ports:
      - "8082:8080"  # Porta 8082 para a API de busca
    deploy:
      resources:
        limits:
          memory: 768M

volumes:
  pgdata:

📝 A Entrega Global (O Grupo)

1. O Código Unificado

Os alunos entregam o projeto Java completo no repositório. O fundamental da Engenharia de Software será avaliado pelo uso do docker-compose.yml. * Auditoria: O professor rodará o Compose do grupo (docker compose up -d). Esse script precisa subir simultaneamente o Banco Vetorial e o Servidor Spring Boot. Um script de teste (uma rota /search) será acionada para garantir que problemas similares do WOKDEX estão sendo recuperados.

2. O Relatório Técnico no README.md

Para manter o foco na infraestrutura de software e bancos de dados, o grupo documentará os resultados técnicos diretamente no README.md do repositório (material que comporá a seção de Recuperação de Informação do Artigo Final no TP3): * Arquitetura RAG: Explicação e ilustração de como o Pipeline foi montado, desde a ingestão da base até a injeção do contexto. * Métricas de Recuperação: Avaliação empírica do sistema (Precision@3, MRR, Latência P95 e discussão de fidelidade no Golden Test Set). * Discussão Crítica (Similaridade Superficial vs. Isomorfismo Algorítmico): Discutir os casos onde a busca vetorial funcionou com excelência (queries técnicas diretas) e os casos onde ela recuperou problemas com historinhas parecidas mas algoritmos diferentes (Transferência Negativa).

(Diferentes bancos vetoriais serão alocados aos grupos para enriquecer a discussão empírica no artigo).


📊 Rubrica de Avaliação Detalhada (8 Pontos)

Nota Individual (4 pts)

Critério Pontos Detalhes
Commits individuais na branch correta 1 Avaliado via Git Blame
Módulo individual funciona isoladamente 2 Ingestão OK (A) OU VectorDB sobe (B) OU Spring MVC responde (C) OU RAG retorna resultados (D)
Qualidade e organização do código 1 Clean Code, DTOs, nomes descritivos

Nota do Grupo (4 pts)

Critério Pontos Detalhes
docker-compose up sobe o banco e a API 1.5 O professor roda uma única linha e tudo funciona
Busca semântica retorna exercícios relevantes 0.5 Precision@3 ≥ 60% no Golden Test Set (ver abaixo)
Relatório Técnico no README.md completo 2 Diagrama da arquitetura, latência P95, MRR e discussão de similaridade superficial

Métricas Obrigatórias no README.md

O grupo deve reportar, no mínimo, as seguintes métricas no README.md:

Métrica O que mede Como calcular
Precision@3 Dos 3 documentos retornados, quantos são relevantes? relevantes_no_top3 / 3
MRR (Mean Reciprocal Rank) Em que posição o documento mais relevante aparece? 1 / posição_do_primeiro_relevante
Latência P95 Tempo de resposta no percentil 95 Medir 100 queries, pegar o 95º valor
Total Indexado Quantos documentos estão no banco Retornado no JSON de resposta

🎯 Golden Test Set (Avaliação Objetiva)

O professor fornecerá um Golden Test Set — um conjunto de queries em português com os IDs dos exercícios esperados no Top-3 (baseado no grafo de similar_questions curado por especialistas). Exemplo:

golden_tests:
  - query: "soma de dois numeros em um array com valor alvo"
    expected_ids: [1, 167, 15]   # Two Sum, Two Sum II, 3Sum
  - query: "inverter lista encadeada simplesmente encadeada"
    expected_ids: [206, 92, 24]  # Reverse Linked List, Reverse Linked List II, Swap Nodes
  - query: "converter algarismos romanos para numero inteiro"
    expected_ids: [13, 12, 273]  # Roman to Integer, Integer to Roman

O score de Precision@3 é calculado automaticamente contra este gabarito. Isso garante avaliação objetiva e reprodutível.


🧪 Testes de Integração Obrigatórios

# Teste O que verifica
1 test_compose_up docker-compose up sobe banco + API sem erros
2 test_ingest_documents Endpoint de ingestão insere documentos no VectorStore
3 test_search_returns_results GET /search?q=...&k=3 retorna exatamente 3 resultados
4 test_similarity_score_range Cada similarity_score está entre 0.0 e 1.0
5 test_golden_query Pelo menos 2 dos 3 resultados de uma query do Golden Test Set são corretos

📅 Cronograma Sugerido (4 Semanas)

Para não acumular trabalho e perder a data de entrega, sugerimos o seguinte ritmo para a equipe:

Período Foco da Equipe Meta da Semana
Semana 1 Pesquisa e Setup Leitura do artigo (Lewis 2020), setup do Docker (docker-compose com VectorDB) e criação do projeto Spring Boot.
Semana 2 Ingestão de Dados Script/endpoint de geração de embeddings e ingestão de todo o Corpus WOKDEX no banco vetorial.
Semana 3 RAG e Busca Construção do endpoint de busca semântica, integração com Spring AI e testes manuais de similaridade.
Semana 4 Qualidade e README Testes de integração (Precision@3), refinamento dos resultados, relatório no README.md e Merge Request final.

✅ Checklist de Entrega — TP2



🔬 Adendo IC — Taxonomia de Erros e Infra de Agentes (Opcional)

Esta seção é exclusiva para equipes da Trilha IC. As equipes regulares podem ignorá-la. Se uma equipe IC desistir da trilha, o adendo já feito conta como +1 ponto bônus na nota regular do TP2.

Enquanto todas as equipes constroem o RAG, as equipes IC aproveitam para preparar a infraestrutura do TP3 Master em paralelo.

Parte A — Taxonomia de Erros (Pesquisa)

Antes de simular alunos errando (TP3 Master), é preciso saber que tipos de erro existem. A equipe IC documenta:

Nível Tipo de Erro Exemplo Subtipo WOKDEX
CS1 Tipo de dado inadequado int vs double na divisão TYPE
CS1 Formatação de saída Falta de \n, espaço extra FORMAT
CS2 Lógica off-by-one i <= n vs i < n no loop STRATEGY
CS2 Caso-base faltando Recursão sem if (n == 0) STRATEGY
CS3 Força bruta onde cabe DP O(2ⁿ) vs O(N²) STRATEGY

Entregável: Planilha com ≥ 15 tipos de erro catalogados, organizados por nível (CS1/CS2/CS3) e subtipo WOKDEX (TYPE/FORMAT/STRATEGY).

Parte B — Setup LangGraph e vLLM (Infraestrutura)

A equipe IC configura o ambiente que será usado no TP3 Master:

  1. Conectar ao vLLM na AWS (API key fornecida pelo professor).
  2. Instalar LangGraph e criar um grafo mínimo de teste:
    • Nó 1: recebe um enunciado
    • Nó 2: chama o LLM para classificar skills
    • Nó 3: retorna JSON formatado
  3. Documentar a arquitetura dos 3 Agents que serão construídos no TP3 Master (diagrama).

Entregável: Notebook Python (setup_langgraph.ipynb) com o grafo mínimo rodando + diagrama dos 3 Agents.

Checklist IC-TP2

[!TIP] Ao final do TP2, a equipe IC terá: (1) o RAG funcional (como todas), (2) a taxonomia de erros que alimenta o Agent Novice, e (3) o esqueleto do LangGraph pronto. No TP3 Master, é só plugar os agentes.

De volta ao topo