Pular para o conteúdo principal

Endpoints do Assistente de IA

Grupo /ai/* — consulta ao assistente com contexto da Knowledge Base (RAG via ChromaDB + DeepSeek R1), geração automática de casos de teste e reindexação da KB.

O recurso está disponível apenas quando habilitado pelo admin da plataforma (PUT /platform/admin/ai/configenabled: true). Quando desabilitado, os endpoints retornam 403 ou AiStatusResponse.enabled=false.

Tabela de endpoints

MétodoCaminhoAuthDescrição
POST/ai/streamSessãoResposta em streaming (SSE).
POST/ai/askSessãoResposta síncrona com fontes e uso de tokens.
GET/ai/statusSessãoStatus do subsistema (KB, DeepSeek, config).
POST/ai/generate-casesSessãoGera casos de teste a partir de XML.
POST/ai/reindexSessão (admin da plataforma)Força reindexação da KB.

Autenticação: os endpoints exigem sessão autenticada (ensure_authenticated). API keys não são aceitas para estes endpoints atualmente — use JWT ou cookie de sessão.

POST /ai/stream (SSE)

Resposta em streaming via Server-Sent Events. Cada chunk é uma linha data: …\n\n. O stream termina com data: [DONE]\n\n.

Request body (AiAskRequest):

{
"query": "Como escrever um decoder para nginx access logs?",
"context_type": "decoder",
"current_xml": "<decoder name=\"meu-nginx\">…</decoder>"
}
  • query — 2–2000 chars.
  • context_type"rule", "decoder", "general" ou null. Filtra a KB para ser relevante.
  • current_xml — XML em edição (até 50 000 chars). Incluído como contexto ao modelo.

Headers de resposta:

Content-Type: text/event-stream
Cache-Control: no-cache
X-Accel-Buffering: no

Formato do stream:

data: {"type":"content","text":"Para criar um decoder de nginx"}

data: {"type":"content","text":", use o padrão <regex>..."}

data: {"type":"sources","sources":[{"record_uid":"...","title":"Nginx decoder example","relevance_score":0.91}]}

data: [DONE]

Exemplo (curl):

curl -N -X POST "$RF_BASE/ai/stream" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"query":"Como escrever um decoder para nginx?", "context_type":"decoder"}'

Limites:

  • Conexões SSE por usuário são limitadas. Excedido → 429 sse_connection_limit_exceeded com Retry-After.
  • Rate limit do assistente: NATIVE_WAZUH_AI_RATE_LIMIT_PER_MINUTE (padrão 20).

POST /ai/ask

Versão síncrona, não-streaming. Retorna a resposta completa + fontes + uso de tokens.

Request body — mesmo AiAskRequest do stream.

Response 200 (AiAskResponse):

{
"answer": "Para criar um decoder de nginx access logs, use o padrão…",
"sources": [
{
"record_uid": "kb_nginx_decoder_01",
"title": "Nginx access log decoder",
"source_trust": "wazuh-docs",
"relevance_score": 0.91
}
],
"token_usage": {
"prompt_tokens": 1243,
"completion_tokens": 287,
"cached_tokens": 1100
}
}
  • sources[] — documentos da KB usados como contexto.
  • token_usage.cached_tokens — tokens reaproveitados do prompt cache (reduz custo).

Exemplo (curl):

curl -X POST "$RF_BASE/ai/ask" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"query":"Explique a tag <prematch>","context_type":"decoder"}' | jq

GET /ai/status

Retorna o status operacional do assistente.

Response 200 (AiStatusResponse):

{
"enabled": true,
"vector_store_count": 12847,
"deepseek_reachable": true,
"error": null,
"model": "deepseek-reasoner",
"base_url_display": "https://api.***seek.com/v1",
"max_context_docs": 4,
"rate_limit_per_minute": 20,
"knowledge_base_path": "data/base_conhecimento"
}
  • enabled — se o subsistema está ligado e a KB está carregada.
  • vector_store_count — documentos indexados no ChromaDB.
  • deepseek_reachable — check live de conectividade com a API do provedor.
  • base_url_display — URL do provedor com middle mascarado (não expõe o domínio completo).

Quando enabled=false, os outros campos podem estar zerados. error é preenchido quando há falha de init.

POST /ai/generate-cases

Gera casos de teste automaticamente a partir do conteúdo XML enviado. O assistente examina rules/decoders e propõe eventos + expectativas.

Request body (AiGenerateCasesRequest):

{
"rules_xml": "<group name=\"custom\"><rule id=\"100010\">…</rule></group>",
"decoders_xml": "<decoder name=\"custom\">…</decoder>",
"max_cases": 5
}
  • rules_xml, decoders_xml — até 200 000 chars cada. Pelo menos um deve ter conteúdo.
  • max_cases — 1–30, padrão 10.

Response 200 (AiGenerateCasesResponse):

{
"cases": [
{
"name": "SSH failed password — root user",
"description": "Evento de tentativa falha de login como root",
"event_text": "Jan 10 12:00:01 web01 sshd[1234]: Failed password for root from 10.0.0.5 port 44218 ssh2",
"log_format": "syslog",
"expected_decoder": "sshd",
"expected_rule": "5716",
"expected_fields": { "dstuser": "root", "srcip": "10.0.0.5" },
"expected_rule_ids": ["5716"]
}
],
"token_usage": { "prompt_tokens": 890, "completion_tokens": 412, "cached_tokens": 0 }
}

O cliente tipicamente:

  1. Chama /ai/generate-cases com o XML do workspace.
  2. Mostra os casos gerados na UI para o usuário revisar.
  3. Persiste os casos aprovados via POST /platform/projects/{id}/cases.

Erros:

  • 400 bad_request — XML vazio ou inválido.
  • 500 internal_error — falha na geração (detalhes em debug_id).

POST /ai/reindex

Força re-indexação completa da Knowledge Base. Limpa a coleção existente e re-importa todos os JSONL de data/base_conhecimento/.

Auth: sessão. Na prática esta operação é feita por administradores; pode demorar alguns segundos a minutos conforme o tamanho da KB.

Response 200:

{ "status": "ok", "indexed_records": 12847 }

ou em caso de falha:

{ "status": "error", "error": "…" }

Configuração (administrador)

Estes endpoints respondem conforme a configuração em:

  • GET /platform/admin/ai/config — exposto ao admin para ler o estado.
  • PUT /platform/admin/ai/config — altera API key, modelo, base URL, rate limit.
  • POST /platform/admin/ai/test — valida conectividade antes de salvar.

Esses endpoints de admin não são documentados aqui — são internos à operação da plataforma.