Skip to content

flmoraes01/extagent

Repository files navigation

Projeto — CVE RAG Pipeline

Pipeline de ingestão, consulta RAG de CVEs, scan de segurança com Checkmarx One e correção automática de código via LLM — tudo com MongoDB como vector store, LM Studio como backend e API documentada em OpenAPI 3.0.


Visão Geral

O projeto consome a base pública do CVEProject/cvelistV5, organiza os dados em disco por mês/ano, sincroniza com MongoDB e disponibiliza uma interface RAG para consultas em linguagem natural, detecção de CVEs em relatórios, geração de PDFs técnicos e correção automática de vulnerabilidades diretamente no repositório GitLab via FixAgent.


Arquitetura

Visão Hexagonal

O sistema segue a arquitetura hexagonal (Ports & Adapters): o núcleo de domínio é isolado de frameworks e infraestrutura por portas explícitas. O diagrama completo está em docs/fluxo_arquitetura.mmd.

╔══════════════════╗     ╔════════════════════════════════════════════════╗     ╔══════════════════╗
║  ADAPTADORES     ║     ║               ⬡  NÚCLEO HEXAGONAL  ⬡           ║     ║  ADAPTADORES     ║
║  PRIMÁRIOS       ║     ║                                                ║     ║  SECUNDÁRIOS     ║
║  (entrada)       ║     ║  ┌────────────────────────────────────────┐   ║     ║  (saída)         ║
║                  ║     ║  │  DOMÍNIO                                │   ║     ║                  ║
║  REST API  ──────╫─────╫─►│  RAG Engine    Workaround Cascade      │   ║     ║  MongoDB         ║
║  (Flask)         ║     ║  │  CVEIndexer    PDF Generator            │   ║     ║  (Vector Store)  ║
║                  ║     ║  │  Text Extractor  Code Fixer (LLM)       │   ║     ║                  ║
║  CLI       ──────╫─────╫─►│                                         │   ║     ║  LM Studio       ║
║  (--cve)         ║     ║  └──────────────┬──────────────────────────┘   ║     ║  LLM + Embeddings║
║                  ║     ║                 │                              ║     ║                  ║
╚══════════════════╝     ║  ┌──────────────▼──────────────────────────┐   ║     ║  DuckDuckGo      ║
                         ║  │  CASOS DE USO                            │   ║     ║  cve.org · NVD   ║
                         ║  │  CVEConsultant   (LangGraph 4 nós)       │───╫────►║  CIRCL · OSV     ║
                         ║  │  LiteConsultant  (Cascata 4 etapas)      │   ║     ║                  ║
                         ║  │  CVEAgent        (detecção + PDF)        │   ║     ║  Checkmarx One   ║
                         ║  │  CheckmarxAgent  (LangGraph 7 nós)       │   ║     ║  GitLab API      ║
                         ║  │  FixAgent        (LangGraph 9 nós) ★     │   ║     ║                  ║
                         ║  │  CVEUpdater      (pipeline incremental)  │   ║     ║  CVEProject ZIP  ║
                         ║  └─────────────────────────────────────────┘   ║     ╚══════════════════╝
                         ╚════════════════════════════════════════════════╝

Diagrama de Pipelines

flowchart TD
    %% ── Entradas ──
    REST(["REST API\nFlask / OpenAPI"])
    CLI(["CLI\n--cve CVE-YYYY-XXXX"])

    %% ── Pipelines ──
    subgraph INGEST["📥 Ingestão  POST /atualizar_cves"]
        I1["CVEUpdater\n(incremental: desde_ano)"] --> I2["CVEIndexer\n(ThreadPoolExecutor)"]
        I2 --> I3["cve_resolver\n(UUIDs + headers)"] --> I4["sincronizar()"] --> I5["vetorizar()"]
    end

    subgraph FULL["🔍 Pipeline Principal  POST /consultar_cve*"]
        F1["buscar_documentos\n(MongoDB × 3 queries)"] --> F2["gerar_resposta\n(LLM)"]
        F2 --> F3["fallback_online\n(cve.org se não encontrado)"] --> F4["enriquecer_workaround\nNVD·CIRCL·OSV·Web·LLM"]
    end

    subgraph LITE["⚡ Pipeline Lite  POST /lite/*"]
        L1{"MongoDB\nID exato · semântica"} -->|encontrado| LOUT["JSON + fonte"]
        L1 -->|não encontrado| L2{"sugestao_correcao?"}
        L2 -->|sim| LOUT
        L2 -->|não| L3{"descricao?"}
        L3 -->|sim| LOUT
        L3 -->|não| L4["DuckDuckGo → LLM"] --> LOUT
    end

    subgraph FIX["🔧 FixAgent  POST /fix_pipeline"]
        FX1["[1] autenticar\nGitLab project_id"] --> FX2["[2] obter_vulnerabilidades\nCheckmarx · lista direta"]
        FX2 --> FX3["[3] planejar_fixes\nLLM: arquivo + ação"] --> FX4["[4] ler_arquivos\nGitLab API"]
        FX4 --> FX5["[5] gerar_solucoes\nLLM por vuln"] --> FX6["[6] gerar_codigo\nLLM: código corrigido"]
        FX6 --> FX7["[7] criar_branch\nagent/fix-cve-YYYYMMDD"] --> FX8["[8] gerar_relatorio\nReportLab PDF"]
        FX8 --> FX9["[9] commit_e_push\natômico: código + PDF"]
    end

    %% ── Infraestrutura compartilhada ──
    MONGO[("MongoDB\ncve_rag.cves")]
    LLM["LM Studio\nLLM + Embeddings"]
    EXT["APIs Externas\ncve.org · NVD · CIRCL\nCheckmarx · GitLab"]

    %% ── Conexões ──
    REST --> INGEST
    REST --> FULL
    REST --> LITE
    REST --> FIX
    CLI  --> FULL

    I5   --> MONGO
    F1   --> MONGO
    L1   --> MONGO
    F2   --> LLM
    F4   --> LLM
    L2   --> LLM
    L3   --> LLM
    FX3  --> LLM
    FX5  --> LLM
    FX6  --> LLM
    F3   --> EXT
    F4   --> EXT
    FX2  --> EXT
    FX4  --> EXT
    FX9  --> EXT

    %% ── Saídas ──
    F4   -->|"JSON Response"| RJSON["JSON\n(workaround · refs)"]
    LOUT -->|"JSON Response"| RLITE["JSON\n(workaround · fonte)"]
    FX9  -->|"branch + PDF + SHA"| RGIT["GitLab\nagent/fix-cve-* branch"]

    %% ── Estilos ──
    classDef pipeline fill:#1d3557,color:#fff,stroke:#457b9d,stroke-width:2px
    classDef node     fill:#2d4a6e,color:#fff,stroke:#4a7fb5
    classDef infra    fill:#2d6a4f,color:#fff,stroke:#1b4332
    classDef out      fill:#e9c46a,color:#333,stroke:#e76f51
    classDef entry    fill:#457b9d,color:#fff,stroke:#1d3557

    class REST,CLI entry
    class MONGO,LLM,EXT infra
    class RJSON,RLITE,RGIT out
Loading

Pipeline de Ingestão

Modo completo (primeira carga) — processa todos os ~350k arquivos do dataset:

main.zip → extrair → CVEIndexer (desde_ano=None) → cve_resolver → sincronizar → vetorizar → MongoDB

Modo incremental (atualizações rotineiras) — detecta automaticamente o último ano indexado e processa apenas os arquivos desse ano em diante (~10% do dataset):

main.zip → extrair → CVEIndexer (desde_ano=último_ano) → cve_resolver → sincronizar → vetorizar → MongoDB
                           ↑
                    ThreadPoolExecutor
                    (cpu×2 workers, chunksize auto)

Pipeline Principal — CVEConsultant (LangGraph)

 START
   │
   ▼
buscar_documentos ──► MongoDB (3 queries paralelas)
   │                   └── DuckDuckGo (fallback se ≤1 resultado)
   ▼
gerar_resposta ──────► LLM → JSON estruturado
   │
   ▼
fallback_online ─────► cve.org API (só se encontrado=false)
   │                   └── salva no MongoDB para consultas futuras
   ▼
enriquecer_workaround → solucao MongoDB
   │                  → NVD ‖ CIRCL ‖ OSV (paralelo)
   │                  → URLs de referência do CVE
   │                  → DuckDuckGo → LLM
   │                  → LLM forçado (nunca retorna vazio)
   ▼
  END → JSON Response

Pipeline Lite — LiteConsultant

Sem chamadas a APIs externas de CVE. Ideal quando o relatório já traz contexto suficiente.

Por vulnerabilidade recebida:
   │
   ├─1─► MongoDB (ID exato → semântica)  ──────────────────► fonte: "mongodb"
   │         └── não encontrado
   │
   ├─2─► sugestao_correcao presente? → LLM elabora ────────► fonte: "sugestao"
   │         └── não
   │
   ├─3─► descricao disponível? → LLM infere ───────────────► fonte: "descricao"
   │         └── não
   │
   └─4─► DuckDuckGo → LLM sintetiza ────────────────────────► fonte: "internet"

Pipeline Fix — FixAgent (LangGraph 9 nós)

Corrige vulnerabilidades diretamente no código-fonte do repositório GitLab, faz commit em nova branch e gera relatório PDF.

[1] autenticar ──► GitLab project_id
[2] obter_vulnerabilidades ──► lista fornecida ou CheckmarxAgent.escanear()
[3] planejar_fixes ──► LLM: { arquivo, acao, descricao } por vuln
[4] ler_arquivos ──► GitLab API: conteúdo de cada arquivo na branch_origem
[5] gerar_solucoes ──► LLM: descrição de solução por vulnerabilidade
[6] gerar_codigo ──► LLM: código corrigido por arquivo (agrupa múltiplas vulns)
[7] criar_branch ──► GitLab: agent/fix-cve-YYYYMMDD ← branch_origem
[8] gerar_relatorio ──► ReportLab: PDF com vulns + soluções + diff
[9] commit_e_push ──► commit atômico: código corrigido + PDF → push

Comparativo entre os pipelines:

Característica Principal Lite Fix
Consulta MongoDB Sim Sim Não
API cve.org / NVD / CIRCL Sim Não Não
Busca web (DuckDuckGo) Sim Último recurso Não
Sugestão de correção Não Sim Não
Corrige código-fonte Não Não Sim
Cria branch no GitLab Não Não Sim
Commit + push automático Não Não Sim
Geração de PDF /analise_extracao_relatorio /lite/analise_extracao_relatorio Incluído no commit
Saída JSON com refs JSON com fonte SHA + branch + PDF

Estrutura de Módulos

src/
├── config/
│   ├── prompt_config.py    # Prompts LLM, schemas JSON, semáforo _LLM_SEM, invocar_llm/invocar_chain
│   └── token_tracker.py    # Contagem tiktoken, ContextVar por request, truncar/extrair seções de código
│
├── loader/
│   ├── cve_loader.py       # Download e extração do main.zip
│   ├── cve_indexer.py      # Parse e indexação de todos os CVEs por mês/ano
│   └── cve_updater.py      # Pipeline completo de atualização via API (upload zip)
│
├── searcher/
│   └── cve_resolver.py     # UUIDs por registro + header JSON (LangGraph async)
│
├── rag/
│   ├── cve_rag_mongo.py    # Conexão MongoDB, sincronizar(), vetorizar(), retriever
│   ├── cve_rag.py          # Retriever, scoring, buscar(), responder(), cve_tools
│   ├── cve_consultant.py   # Consulta completa via LangGraph (CLI + API)
│   └── lite_consultant.py  # Pipeline lite: MongoDB → sugestão → descrição → internet
│
└── agent/
    ├── cve_agent.py        # Detecção de CVEs em texto + orquestração em lote
    ├── text_extractor.py   # Extração de texto de PDF, DOCX, TXT, JSON, CSV, XLSX, XML
    ├── pdf_generator.py    # Geração de relatório técnico em PDF via LLM + ReportLab
    └── fix_agent.py        # FixAgent: corrige código no GitLab via LangGraph (9 nós)

Descrição dos Módulos

prompt_config.py

Fonte única de verdade para toda a comunicação com o LLM:

  • _LLM_SEMthreading.Semaphore(1) compartilhado por todos os módulos. Como o LM Studio processa uma requisição por vez, todas as chamadas ao LLM devem adquirir este semáforo antes de invocar o modelo.
  • invocar_llm(model, msgs) — wrapper que adquire _LLM_SEM, invoca o modelo e registra tokens automaticamente via token_tracker. Substitui with _LLM_SEM: model.invoke(msgs) em todos os módulos.
  • invocar_chain(chain, inputs) — wrapper equivalente para chains do tipo prompt | model | parser.
  • Schemas JSON — contratos de saída dos LLMs: SCHEMA_CVE_DETECTADO, SCHEMA_CVE_RESPOSTA, SCHEMA_RELATORIO, SCHEMA_FX_PLANO
  • Prompt templates (ChatPromptTemplate) — PROMPT_CVE_AGENT, PROMPT_CVE_RESPOSTA, PROMPT_CVE_BATCH, PROMPT_PDF_RELATORIO, PROMPT_RAG_RESPOSTA, PROMPT_FX_PLANEJAR
  • Message builders — funções que retornam listas de tuplas: msgs_traducao(), msgs_extrair_workaround(), msgs_workaround_forcado(), msgs_workaround_web_search(), msgs_enriquecer_workaround(), msgs_workaround_de_sugestao(), msgs_corrigir_codigo(), msgs_descrever_fix()

token_tracker.py

Infraestrutura de rastreamento e redução de tokens por requisição Flask:

  • nova_requisicao() — inicializa um _Acumulador via contextvars.ContextVar, armazenado em g.token_acc pelo before_request do Flask.
  • registrar(response, msgs) — extrai prompt_tokens/completion_tokens do usage_metadata da resposta ou estima via tiktoken quando ausente.
  • stats_da_requisicao() — retorna {prompt_tokens, completion_tokens, total_tokens, llm_calls, estimado}. Injetado automaticamente como chave "tokens" em todas as respostas JSON quando llm_calls > 0.
  • contar_tokens(texto) — contagem exata via cl100k_base (tiktoken) com fallback len/4.
  • truncar_por_tokens(texto, max_tokens) — truncação tiktoken-exata, não por caracteres.
  • extrair_secao_codigo(conteudo, linha, janela=60, max_tokens=3000) — extrai ±60 linhas ao redor da vulnerabilidade antes de enviar ao LLM, reduzindo 70–90% dos tokens em arquivos grandes.
  • compactar_lista_textos(textos, budget) — distribui um budget de tokens entre múltiplos textos, evitando overflow em operações em batch.

Campo tokens na resposta:

{
  "resultado": "...",
  "tokens": {
    "prompt_tokens": 450,
    "completion_tokens": 120,
    "total_tokens": 570,
    "llm_calls": 3,
    "estimado": false
  }
}

cve_loader.py

Responsável exclusivamente por:

  • Baixar o main.zip do repositório oficial do CVEProject no GitHub
  • Verificar se o ZIP mudou (hash SHA-256) para evitar re-extração desnecessária
  • Extrair os arquivos para loader/datasets/cves/

cve_indexer.py

  • Varre os arquivos JSON extraídos pelo loader
  • Parseia CVEs e extrai: cve_registro, data_criacao, Year, Month, descricao, solucao
  • Extrai severidade dos métricas CVSS (preferindo CNA sobre ADP; fallback: "Unknown")
  • Organiza os registros em database/{year}/cve_database_MM_YYYY.json

cve_updater.py

Orquestra o pipeline de atualização via upload da API com detecção automática de modo:

Etapa Ação
validar() Verifica estrutura interna do zip cvelistV5
ja_processado() Compara SHA-256 para evitar reprocessamento
extrair() Descompacta para loader/datasets/cves/
processar() Detecta modo (completo vs incremental) e executa o pipeline sequencial
atualizar_readme() Atualiza automaticamente a seção de estatísticas no README

Detecção de modo em processar():

  • Se database/ não existir → modo completo (desde_ano=None): indexa todos os ~350k arquivos
  • Se database/ existir → modo incremental (desde_ano=último_ano): indexa apenas arquivos do último ano indexado em diante (~10% do total)

Pipeline sequencial:

extrair → CVEIndexer.index(desde_ano) → cve_resolver → sincronizar → vetorizar

cve_resolver.py

Pipeline assíncrono (LangGraph + asyncio) que:

  • Lê todos os arquivos cve_database_*.json do diretório database/
  • Gera UUIDs aleatórios para registros sem id
  • Adiciona/atualiza o header de cada JSON com year, month, mes_ano, gerado_em e total_cves
  • Migra automaticamente o formato legado para o novo formato (header + cves[])
  • Normaliza as chaves Year/Month para year/month

Formato JSON resultante:

{
  "header": {
    "year": 2026,
    "month": 4,
    "mes_ano": "04_2026",
    "gerado_em": "2026-05-31T...",
    "total_cves": 42
  },
  "cves": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "cve_registro": "CVE-2026-12345",
      "Year": 2026,
      "Month": 4,
      "descricao": "...",
      "solucao": "...",
      "severidade": "High"
    }
  ]
}

cve_rag_mongo.py

  • sincronizar() — Lê todos os JSONs de database/ e salva um documento MongoDB por arquivo (mes_ano), com os CVEs como array aninhado no campo cves:
    • Chave única: mes_ano (ex: "04_2026")
    • Usa $setOnInsert — documentos existentes não são sobrescritos
  • vetorizar() — Calcula embeddings (modelo text-embedding-qwen3-embedding-0.6b via LM Studio) para cada CVE sem embedding dentro dos documentos mês/ano, usando o operador posicional $set cves.<idx>.embedding
  • MongoDBCVERetriever — Faz unwind dos CVEs em memória, calcula score composto ponderado e filtra por score >= 0.6

Schema do documento MongoDB:

{
  "mes_ano": "04_2026",
  "year": 2026,
  "month": 4,
  "cves": [
    {
      "cve_registro": "CVE-2026-12345",
      "data_criacao": "2026-04-15T...",
      "Year": 2026,
      "Month": 4,
      "descricao": "...",
      "solucao": "...",
      "severidade": "High",
      "embedding": [0.123, "..."]
    }
  ]
}

cve_rag.py

Centraliza a lógica de recuperação e geração:

  • coseno(a, b) — Similaridade coseno entre dois vetores NumPy
  • calcular_score(...) — Score composto normalizado [0, 1] com pesos: CVE-ID (4) > semântica (3) > ano (2) > mês (1)
  • MongoDBCVERetriever — Retriever LangChain com scoring ponderado, threshold 0.6, filtro por ano
  • buscar(query, k) — Busca os k documentos mais relevantes no MongoDB
  • responder(pergunta) — Pipeline RAG completo: busca + geração de resposta pelo LLM
  • @tool buscar_workarounds_cve + cve_tools — Ferramenta exposta para uso por agentes LLM

cve_consultant.py

Orquestrador completo via LangGraph com 4 nós em sequência:

Função
buscar_documentos Gera 3 queries estáticas internamente e consulta o MongoDB em paralelo. Se ≤ 1 resultado, faz busca web (DuckDuckGo) filtrando por score > 0.6
gerar_resposta Sintetiza os documentos em JSON estruturado via LLM; inclui referências MongoDB (mes_ano, score)
fallback_online Se encontrado: false, busca na API pública cveawg.mitre.org. Tradução PT-BR e busca de workaround executadas em paralelo
enriquecer_workaround Se workaround for null: cascata de fontes até garantir valor não-nulo

Grafo LangGraph:

START → buscar_documentos → gerar_resposta → fallback_online → enriquecer_workaround → END

Busca de workaround — cascata de fontes (workaround nunca é nulo):

  1. Campo solucao já gravado no MongoDB
  2. Campo workarounds do JSON da API cve.org
  3. NVD / CIRCL / OSV — consultados em paralelo, retorna ao primeiro resultado
  4. URLs de referência do próprio CVE (fetch + extração via LLM)
  5. Busca web DuckDuckGo → LLM sintetiza em PT-BR
  6. LLM forçado com descrição da vulnerabilidade (nunca retorna vazio)
  7. Fallback estático com recomendações genéricas (garantia absoluta)

Saída JSON:

{
  "cve": "CVE-2026-12345",
  "encontrado": true,
  "descricao": "Descrição em PT-BR",
  "severidade": "High",
  "workaround": "Passos de mitigação em PT-BR...",
  "referencias": [
    "https://nvd.nist.gov/...",
    "MongoDB[cve_rag.cves/04_2026]: CVE-2026-12345 (score: 0.91)"
  ]
}

Uso via CLI:

python src/rag/cve_consultant.py --cve CVE-2026-12345

consultar_multiplos — fluxo em lote (não usa o grafo LangGraph):

Fase Ação Paralelismo
1. Busca de documentos Executa buscar_documentos para todos os CVEs no MongoDB 8 workers em paralelo
2. Chamadas ao LLM Agrupa CVEs em batches de CVE_BATCH_SIZE e envia um batch por chamada Sequencial (serializado por _LLM_SEM)
3. Fallback + enriquecimento Executa fallback_online e enriquecer_workaround só para CVEs que precisam 3 workers em paralelo

O contexto por CVE no batch é limitado a 10000 ÷ batch_size caracteres para respeitar o context window do modelo.

Uso via API:

from src.rag.cve_consultant import CVEConsultant

consultant = CVEConsultant()

# Consulta individual (usa LangGraph completo)
resultado = consultant.consultar("CVE-2026-12345")

# Consulta em lote com batch LLM (recebe payload do CVEAgent)
resultados = consultant.consultar_multiplos([
    {"cve_id": "CVE-2026-12345", "severidade": "High"},
    {"cve_id": "CVE-2026-67890", "severidade": "Unknown"},
])

lite_consultant.py

Pipeline simplificado para extração de correções sem dependência de APIs externas de CVE.

Classe LiteConsultant:

Método Descrição
consultar(vuln_id, descricao, sugestao_correcao, severidade) Consulta individual com lógica em cascata
consultar_lista(vulnerabilidades) Processa lista em paralelo (I/O) com LLM serializado

Ordem de consulta por vulnerabilidade:

Passo Condição Fonte reportada
1 MongoDB — ID exato (cve_registro) com solucao preenchida "mongodb"
2 MongoDB — similaridade semântica (score composto ≥ 0.6) com solucao "mongodb"
3 sugestao_correcao fornecida → msgs_workaround_de_sugestao() → LLM elabora "sugestao"
4 descricao disponível → msgs_workaround_forcado() → LLM infere "descricao"
5 DuckDuckGo → LLM sintetiza (último recurso) "internet"

O campo fonte no JSON de saída indica qual caminho foi percorrido, facilitando auditoria e fine-tuning.

Diferença em relação ao CVEConsultant: não consulta cve.org, NVD, CIRCL, OSV nem URLs de referência do CVE. Ideal quando o relatório de scan já fornece sugestões de correção (Checkmarx One, Snyk, Veracode) — o LLM as elabora localmente, sem chamadas externas.

Saída JSON por item:

{
  "id": "CVE-2021-44228",
  "nome": "Log4Shell",
  "descricao": "Desserialização insegura no Log4j 2 permite RCE via JNDI.",
  "severidade": "Critical",
  "workaround": "Atualizar Log4j para 2.17.1+. Definir log4j2.formatMsgNoLookups=true...",
  "fonte": "sugestao"
}

cve_agent.py

Agente de detecção e orquestração:

  • CVEAgent.analisar(input_text) — Recebe texto livre (log, relatório, código, mensagem) e usa LLM para identificar todos os CVEs mencionados e suas severidades
  • CVEAgent.gerar_relatorio(texto) — Detecta CVEs, consulta detalhes via CVEConsultant e delega geração do PDF ao pdf_generator
  • Retorna JSON estruturado com array cves_detected

Fluxo típico de uso:

from src.agent.cve_agent import CVEAgent
from src.rag.cve_consultant import CVEConsultant

agent = CVEAgent()
consultant = CVEConsultant()

# 1. Detecta CVEs no texto
deteccao = agent.analisar(texto_do_sistema)
# {"cves_detected": [{"cve_id": "CVE-2026-0049", "severidade": "Medium"}, ...]}

# 2. Consulta todos em lote
resultados = consultant.consultar_multiplos(deteccao["cves_detected"])
# [{"cve": "CVE-2026-0049", "encontrado": true, "workaround": "...", ...}, ...]

Saída do CVEAgent.analisar():

{
  "cves_detected": [
    {"cve_id": "CVE-2026-0049", "severidade": "Medium"},
    {"cve_id": "CVE-2026-1115", "severidade": "High"}
  ]
}

text_extractor.py

Extração de texto de múltiplos formatos de arquivo:

Extensão Biblioteca
.pdf pypdf
.docx / .doc python-docx
.xlsx openpyxl
.xml xml.etree.ElementTree / lxml (fallback)
.json json stdlib
.csv csv stdlib
.txt / .md decode UTF-8 direto

pdf_generator.py

Geração de relatórios técnicos em PDF:

  • gerar_estrutura(contexto, detalhes_cves) — Chama LLM com schema padronizado e retorna JSON estruturado do relatório
  • renderizar_pdf(estrutura) — Renderiza o JSON em PDF via ReportLab com layout completo (capa, cabeçalho, rodapé, badges de severidade coloridos)

fix_agent.py

Agente de correção automática de vulnerabilidades em repositórios GitLab.

Classe FixAgent:

Método Descrição
executar(gitlab_url, gitlab_token, branch_origem, vulnerabilidades) Executa o pipeline completo via LangGraph

Grafo LangGraph — 9 nós sequenciais:

Log prefix Responsabilidade
autenticar [1/9] Valida token, obtém project_id, define branch_fix = agent/fix-cve-YYYYMMDD
obter_vulnerabilidades [2/9] Usa lista fornecida ou aciona CheckmarxAgent.escanear()
planejar_fixes [3/9] LLM analisa vulns → {vuln_id, arquivo, acao, descricao}
ler_arquivos [4/9] GitLab API: GET /repository/files/{path}?ref=branch_origem
gerar_solucoes [5/9] LLM: descrição de solução por vulnerabilidade (para o relatório)
gerar_codigo [6/9] LLM: código corrigido por arquivo (agrupa todas as vulns do arquivo)
criar_branch [7/9] GitLab: POST /repository/branches {ref: branch_origem}
gerar_relatorio [8/9] ReportLab: PDF com vulns, soluções, diff resumido
commit_e_push [9/9] GitLab Commit API: commit atômico de código + PDF

Prompt para correção de código (msgs_corrigir_codigo):

  • Fornece ao LLM: arquivo, todas as vulnerabilidades do arquivo, código original completo
  • Instrui: não alterar nada além do necessário, manter lógica de negócio, gerar código funcional
  • Guia específico por tipo: SQL Injection → prepared statements; XSS → escape; secrets → env vars

Saída de executar():

{
  "branch":                      "agent/fix-cve-20260603",
  "commit_sha":                  "a1b2c3d4e5f6...",
  "vulnerabilidades_encontradas": 8,
  "vulnerabilidades_corrigidas":  6,
  "arquivos_modificados":        ["pom.xml", "src/main/java/UserRepo.java"],
  "pdf_path":                    "relatorio_final_20260603.pdf",
  "erro":                        null
}

Scoring de Relevância

O retriever usa um score composto normalizado para rankear os CVEs recuperados:

score = (4 × cve_id_match + 3 × coseno_semântico + 2 × year_match + 1 × month_match) / 10
Componente Peso Critério
cve_id_match 4 CVE ID exato presente na query
coseno_semântico 3 Similaridade coseno entre embeddings
year_match 2 Ano do CVE presente na query
month_match 1 Mês do CVE presente na query

Apenas documentos com score >= 0.6 são retornados. Limite padrão: k=6 documentos.

Quando o MongoDB retorna ≤ 1 documento, o pipeline dispara busca web (DuckDuckGo) e só inclui resultados com score de embedding >= 0.6.


Qualidade do RAG — Decisões de Implementação

Decisão Valor Motivo
temperature LLM (RAG chain) 0.0 Respostas factuais devem ser determinísticas
temperature LLM (consulta/fallback) 0.0 Idem — sem criatividade em dados de CVE
temperature LLM (PDF generator) 0.3 Geração de texto técnico aceita leve variação
Threshold de score >= 0.6 Balanceia precisão e cobertura
Semáforo _LLM_SEM Semaphore(1) em prompt_config.py LM Studio processa uma requisição por vez; evita timeout em cascata
consultar_multiplos — busca 8 workers paralelos (I/O, sem LLM) Busca MongoDB de todos os CVEs antes de acionar o LLM
consultar_multiplos — LLM CVE_BATCH_SIZE CVEs por chamada Reduz N chamadas para ⌈N/batch_size⌉
consultar_multiplos — fallback 3 workers paralelos Fallback/enriquecimento apenas nos CVEs que precisam
Índices MongoDB Criados no load do módulo Evita recriação a cada sincronizar()
Hash de conteúdo (MD5) descricao + solucao + severidade + data_criacao Detecta mudanças reais, ignora campos de infra
Re-vetorização $unset embedding ao atualizar Forçada automaticamente na próxima vetorizar()
Indexação incremental desde_ano = último ano em database/ Reduz ~350k arquivos para ~30-50k em atualizações rotineiras
Parsing paralelo ThreadPoolExecutor(min(cpu×2, 32)) Maximiza I/O em datasets com centenas de milhares de arquivos JSON
Vetorização paralela EMBED_WORKERS=2 workers Aproveita APIs de embedding que aceitam múltiplas requisições
Token tracking ContextVar por request + invocar_llm wrapper Rastreia uso real sem alterar assinaturas dos módulos
Redução de tokens (código) extrair_secao_codigo(±60 linhas) em fix_agent 70–90% menos tokens enviados ao LLM em arquivos grandes
Truncação exata truncar_por_tokens(texto, max) via tiktoken Evita overflow silencioso por contagem de chars

Configuração

Pré-requisitos

  • Python 3.11+
  • MongoDB rodando localmente (padrão: localhost:27017)
  • LM Studio com os modelos carregados:
    • LLM: configurado via LLM_MODEL no .env (padrão: meta-llama-3-8b-instruct)
    • Embeddings: text-embedding-qwen3-embedding-0.6b (fixo em cve_rag_mongo.py)

Variáveis de ambiente (.env)

MONGO_DB_USER=
MONGO_DB_PASSWORD=
MONGO_DB_HOST=
MONGO_DB_PORT=
MONGO_DB_CLUSTER=
MONGO_DB_COLLECTION=
LM_STUDIO_API_KEY=            # Opcional; fallback para OPENAI_API_KEY ou "unused"
LLM_MODEL=meta-llama-3-8b-instruct
CVE_BATCH_SIZE=5              # CVEs por chamada ao LLM em consultar_multiplos (padrão: 5)

Instalação

python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt

Execução da API

python app.py
# Swagger UI:    http://localhost:3000/openapi/swagger
# OpenAPI spec:  http://localhost:3000/openapi/openapi.json

Execução do Pipeline

Execute cada etapa em sequência:

# 1. Download e extração
python src/loader/cve_loader.py

# 2. Indexação por mês/ano
python src/loader/cve_indexer.py

# 3. Geração de UUIDs e headers JSON
python src/searcher/cve_resolver.py

# 4. Sincronização com MongoDB + embeddings
python src/rag/cve_rag_mongo.py

# 5. Consulta individual (CLI)
python src/rag/cve_consultant.py --cve CVE-2026-12345

Ou via API, envie o main.zip para /atualizar_cves — o pipeline completo (etapas 1–4) é executado automaticamente pelo CVEUpdater.


Dependências Principais

Biblioteca Uso
LangChain Chains, prompts, retrievers, output parsers
LangGraph Orquestração do pipeline de consulta (grafo de nós)
PyMongo Driver MongoDB
OpenAI SDK Compatibilidade com LM Studio (LLM + embeddings)
NumPy Cálculo de similaridade coseno
python-dotenv Configuração via .env
requests Fallback para APIs externas (cve.org, NVD, CIRCL, OSV)
ddgs Busca web DuckDuckGo (fallback de documentos e workaround)
pypdf Extração de texto de arquivos PDF
python-docx Extração de texto de arquivos DOCX/DOC
openpyxl Extração de texto de planilhas XLSX
lxml Parser XML alternativo (fallback do stdlib)
ReportLab Renderização de relatórios técnicos em PDF
tiktoken Contagem de tokens (cl100k_base), truncação precisa e redução de contexto LLM
flask-openapi3 Swagger UI + validação OpenAPI 3.0 integrados ao Flask

API REST

Pipeline Principal (CVE / RAG):

Método Rota Tag Descrição
POST /consultar_cve CVE Consulta detalhes de um CVE via RAG + LangGraph
POST /consultar_cve_lista CVE Consulta múltiplos CVEs em batch
POST /atualizar_cves Ingestão Atualiza a base via upload de main.zip
POST /analisar_relatorio Agent Extrai CVEs de relatório (PDF, DOCX, TXT, JSON, CSV, XLSX, XML)
POST /extrair_relatorio Agent Texto → PDF técnico de vulnerabilidades
POST /analise_extracao_relatorio Agent One-shot: arquivo → PDF técnico
POST /checkmarx_pipeline Agent Scan Checkmarx One + GitLab → JSON classificado

Pipeline Lite (/lite):

Método Rota Tag Descrição
POST /lite/consultar_vulnerabilidades Lite Lista estruturada → workaround por item
POST /lite/analisar_relatorio Lite Arquivo → workaround via pipeline lite
POST /lite/analise_extracao_relatorio Lite One-shot lite: arquivo → PDF
POST /lite/checkmarx_pipeline Lite Scan Checkmarx + workaround (sem APIs CVE externas)

Pipeline Fix:

Método Rota Tag Descrição
POST /fix_pipeline Fix Corrige código no GitLab, cria branch, commita PDF e código corrigido

Última Atualização da Base

  • Data: 2026-06-03 21:11 UTC
  • CVEs indexados: 98
  • Inseridos/atualizados no MongoDB: 0
  • Vetorizados: 0
  • Total no banco: 354663

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages