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/config → enabled: true). Quando desabilitado, os endpoints retornam 403 ou AiStatusResponse.enabled=false.
Tabela de endpoints
| Método | Caminho | Auth | Descrição |
|---|---|---|---|
| POST | /ai/stream | Sessão | Resposta em streaming (SSE). |
| POST | /ai/ask | Sessão | Resposta síncrona com fontes e uso de tokens. |
| GET | /ai/status | Sessão | Status do subsistema (KB, DeepSeek, config). |
| POST | /ai/generate-cases | Sessão | Gera casos de teste a partir de XML. |
| POST | /ai/reindex | Sessã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"ounull. 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_exceededcomRetry-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:
- Chama
/ai/generate-casescom o XML do workspace. - Mostra os casos gerados na UI para o usuário revisar.
- 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 emdebug_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.
Links relacionados
- Endpoints de análise — logtest que pode ser alimentado pelos casos gerados.
- Endpoints de projetos — criação de casos.