Communitygithub.com

microsoft/azure-kusto-graph

Construa e consulte grafos Kusto a partir de linguagem natural. Abrange grafos transitórios (make-graph), modelos/snapshots de grafos persistentes, correspondência de padrões (graph-match), caminhos mais curtos, componentes conectados e exportação de grafo para tabela.

O que é azure-kusto-graph?

Esta skill capacita agentes de IA a construir e consultar grafos no Azure Data Explorer (Kusto) usando operadores KQL, diretamente a partir de descrições em linguagem natural. Ela facilita a criação tanto de grafos transitórios, para análises ad-hoc e prototipagem, quanto de grafos persistentes e snapshots, adequados para workflows de produção e dashboards. A skill automatiza o padrão de pensamento 'arestas-primeiro', orientando o agente a definir arestas, tabelas de consulta de nós e unificá-las com o operador `make-graph`. Suporta operações avançadas como `graph-match` para descoberta de padrões, `graph-shortest-paths` para encontrar caminhos mínimos, `graph-mark-components` para identificar componentes conectados, e `graph-to-table` para exportar resultados. Inclui templates prontos para cenários como detecção de movimento lateral e análise de autenticação, além de se integrar com skills complementares como `azure-kusto-irql` para primitivas de segurança e `azure-kusto-irql-graph` para visualização rica no Kusto Explorer. A skill também gerencia o ciclo de vida de grafos persistentes, incluindo criação de modelos e snapshots, sempre com ênfase na segurança e confirmação do usuário antes de executar comandos de modificação.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/microsoft/agent-skills/tree/main/.github/plugins/azure-kusto-graph-skills/skills/azure-kusto-graph

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Semântica de Grafos Kusto

Construa grafos transitórios e persistentes a partir de dados tabulares usando operadores de grafo KQL. Esta skill traduz linguagem natural para o padrão de construção de grafos 'arestas-primeiro' e operadores de consulta de grafo.

Gatilhos de Ativação

Use esta skill quando o usuário:

  • Deseja construir um grafo a partir de dados tabulares (make-graph)
  • Pede para encontrar padrões, caminhos ou relacionamentos em dados
  • Menciona graph-match, graph-shortest-paths, graph-to-table, graph-mark-components
  • Deseja criar um modelo de grafo persistente ou snapshot
  • Diz "construir um grafo", "encontrar o caminho mais curto", "encontrar componentes conectados", "mostrar relacionamentos"
  • Pergunta sobre grafos transitórios vs. persistentes

Não é um conversor de linguagem natural para KQL. A entrada geralmente deve ser uma consulta KQL funcional cujos resultados o usuário deseja converter em um grafo, além de uma descrição em linguagem natural da estrutura de grafo desejada. Solicitações básicas de fonte em linguagem natural são suportadas apenas quando mapeiam diretamente para uma tabela conhecida com colunas óbvias. Para conversão geral de NL para KQL, use uma skill dedicada de geração de consultas (disponível separadamente).

Skills complementares:

  • azure-kusto-irql -- primitivas de consulta de segurança combináveis que produzem as entradas tabulares para grafos
  • azure-kusto-irql-graph -- sistema de mapeamento JSON Lift_To_Graph do IRQL para grafos ricamente tipados e decorados com ícones no Kusto Explorer

A Abordagem Arestas-Primeiro

O padrão fundamental para construir grafos no Kusto:

1. Defina suas ARESTAS       -> src --> dest, com tipo de relacionamento/propriedades
2. Defina suas CONSULTAS DE NÓS -> nomes de exibição, tipos, propriedades para cada ID de nó
3. Unifique tipos de arestas     -> se você tiver vários tipos de relacionamento
4. Unifique consultas de nós     -> se você tiver vários tipos de nó
5. Chame make-graph          -> arestas | make-graph Origem --> Destino com nós em nodeId

É assim que se pensa em make-graph. As arestas são os relacionamentos que você se importa. Os nós são tabelas de consulta que dão a esses IDs uma cara -- nomes de exibição, tipos, propriedades.

Referência de Operadores de Grafo

make-graph -- Construir um grafo a partir de tabelas

Arestas | make-graph SourceId --> TargetId com Nós em NodeId
  • Arestas: fonte tabular onde cada linha é uma aresta
  • SourceId --> TargetId: colunas contendo IDs de nó de origem e destino
  • com Nós em NodeId: tabela opcional de propriedades de nó unida por ID
  • Suporta múltiplas tabelas de nós: com Nós1 em Id1, Nós2 em Id2
  • Nós que aparecem em arestas mas estão ausentes na tabela de nós recebem propriedades vazias

graph-match -- Encontrar padrões

G | graph-match (a)-[e]->(b) onde <restricoes> project <saida>

Notação de padrão:

ElementoNomeadoAnônimo
Nó(n)()
Aresta esquerda->direita-[e]->-->
Aresta direita->esquerda<-[e]-<--
Qualquer direção-[e]---
Comprimento variável-[e*1..5]->-[*1..5]->

Padrões multi-salto: (a)-[e1]->(b)-[e2]->(c) Padrões estrela: (a)--(center)--(b), (c)--(center)--(d) Controle de ciclos: cycles = all | none | unique_edges (padrão: unique_edges)

graph-shortest-paths -- Encontrar caminhos mais curtos

G | graph-shortest-paths (inicio)-[e*1..20]->(fim)
      onde inicio.nome == "Alice" e fim.nome == "Servidor01"
      project Caminho = e, Tamanho = array_length(e)
  • Requer pelo menos uma aresta de comprimento variável
  • output = any (padrão, um caminho por par) ou output = all (todos os caminhos mais curtos de igual comprimento)
  • Propriedades de aresta de comprimento variável retornadas como arrays dinâmicos

graph-to-table -- Exportar grafo para tabelas

G | graph-to-table nodes                                     // exportar nós
G | graph-to-table edges                                     // exportar arestas
G | graph-to-table nodes as N, edges as E                    // exportar ambos
G | graph-to-table nodes with_node_id=Id                     // incluir ID hash do nó
G | graph-to-table edges with_source_id=Src with_target_id=Tgt  // incluir IDs de ponta da aresta

graph-mark-components -- Encontrar componentes conectados

G | graph-mark-components with_component_id=ComponentId
  | graph-to-table nodes
  | summarize Membros = make_list(nome) by ComponentId

Atribui um ComponentId a cada nó. Nós no mesmo componente conectado compartilham o mesmo ID.

Função graph() -- Consultar grafos persistentes

graph("MeuModeloGrafo")                              // snapshot mais recente
graph("MeuModeloGrafo", "Snapshot_2025_01")           // snapshot específico
graph("MeuModeloGrafo", true)                         // transitório a partir da definição do modelo

Grafos Transitórios

Criados dinamicamente durante a execução da consulta. Nenhuma configuração necessária. Ideal para análises ad-hoc, exploração e prototipagem.

Template: Grafo básico de duas entidades

// 1. Definir arestas
let arestas = <TabelaFonte>
    | summarize <agregacoes> by ColOrigem, ColDestino;
// 2. Definir consultas de nós
let nos_origem = arestas
    | distinct ColOrigem
    | project nodeId = ColOrigem, rotulo = ColOrigem, tipoNo = "<TipoOrigem>";
let nos_destino = arestas
    | distinct ColDestino
    | project nodeId = ColDestino, rotulo = ColDestino, tipoNo = "<TipoDestino>";
let todos_nos = union nos_origem, nos_destino;
// 3. Construir e consultar o grafo
arestas
| make-graph ColOrigem --> ColDestino com todos_nos em nodeId
| graph-match (s)-[e]->(t)
    onde <restricoes>
    project Origem = s.rotulo, Destino = t.rotulo, <propriedades da aresta>

Template: Grafo multi-relacionamento

// Múltiplos tipos de aresta -> unificá-los com um esquema comum
let arestas_auth = EventosAutenticacao
    | project Fonte = usuario, Destino = hostname, tipoAresta = "autentica", ts = timestamp;
let arestas_rede = EventosRede
    | project Fonte = src_ip, Destino = url, tipoAresta = "conecta", ts = timestamp;
let todas_arestas = union arestas_auth, arestas_rede;
// Consultas de nós de todas as fontes
let nos_usuario = Funcionarios | project nodeId = usuario, rotulo = nome, tipoNo = "Usuario";
let nos_host = EventosAutenticacao | distinct hostname | project nodeId = hostname, rotulo = hostname, tipoNo = "Host";
let todos_nos = union nos_usuario, nos_host;
todas_arestas
| make-graph Fonte --> Destino com todos_nos em nodeId

Grafos Persistentes

Para grafos reutilizáveis em larga escala. Armazenados em metadados de banco de dados. Suportam snapshots para comparação histórica.

Segurança: Criar ou alterar modelos de grafo e snapshots modifica o banco de dados. Sempre mostre o comando exato e confirme com o usuário antes de executar .create-or-alter graph_model ou .make graph_snapshot.

Passo 1: Criar um modelo de grafo

.create-or-alter graph_model GrafoSeguranca
{
  "Schema": {
    "Nodes": {
      "Usuario": {"nome": "string", "papel": "string"},
      "Host": {"hostname": "string"},
      "IP":   {"ip": "string"}
    },
    "Edges": {
      "AutenticaPara": {"timestamp": "datetime", "resultado": "string"},
      "ConectaDe":    {"timestamp": "datetime"}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "Funcionarios | project nome, papel",
        "NodeIdColumn": "nome",
        "Labels": ["Usuario"]
      },
      {
        "Kind": "AddNodes",
        "Query": "EventosAutenticacao | distinct hostname | project hostname",
        "NodeIdColumn": "hostname",
        "Labels": ["Host"]
      },
      {
        "Kind": "AddEdges",
        "Query": "EventosAutenticacao | project usuario, hostname, timestamp, resultado",
        "SourceColumn": "usuario",
        "TargetColumn": "hostname",
        "Labels": ["AutenticaPara"]
      }
    ]
  }
}

Passo 2: Criar um snapshot

.make graph_snapshot GrafoSeguranca Snapshot_2025_07

Passo 3: Consultar o snapshot

graph("GrafoSeguranca")
| graph-match (usuario)-[auth]->(host)
    onde usuario.papel == "Admin" e auth.resultado == "Falha de Login"
    project Usuario = usuario.nome, Host = host.hostname, Hora = auth.timestamp

Comandos de gerenciamento

Segurança: Todos os comandos de controle abaixo modificam ou excluem objetos do banco de dados. Nunca execute .drop, .create-or-alter graph_model ou .make graph_snapshot automaticamente. Sempre mostre o comando exato, cluster, banco de dados e objeto afetado, e exija confirmação explícita do usuário antes da execução.

.show graph_models                        // listar todos os modelos
.show graph_model GrafoSeguranca           // mostrar detalhes do modelo
.show graph_snapshots GrafoSeguranca       // listar snapshots
.drop graph_snapshot GrafoSeguranca Snapshot_2025_07  // excluir um snapshot (CONFIRME PRIMEIRO)
.drop graph_model GrafoSeguranca           // excluir modelo e todos os snapshots (CONFIRME PRIMEIRO)

Transitório vs Persistente: Quando Usar Cada Um

FatorTransitório (make-graph)Persistente (graph())
ConfiguraçãoNenhuma -- embutido na consultaCriar modelo + snapshot
Tempo de vidaApenas execução da consultaArmazenado em metadados do banco
Atualização dos dadosSempre atualSnapshot no momento da criação
EscalaLimitado pela memória da consultaEscala empresarial
ReusoReconstruído a cada consultaCompartilhado entre usuários/consultas
Melhor paraCaças ad-hoc, prototipagemWorkflows de produção, dashboards

Exemplos de Segurança & Caça a Ameaças

Grafo de autenticação: quem logou no que e de onde

let arestas_auth = EventosAutenticacao
    | summarize
        logins = count(),
        falhas = countif(resultado == "Falha de Login")
      by src_ip, usuario, hostname;
let nos_ip = arestas_auth | distinct src_ip
    | project nodeId = src_ip, rotulo = src_ip, tipoNo = "IP";
let nos_usuario = arestas_auth | distinct usuario
    | project nodeId = usuario, rotulo = usuario, tipoNo = "Usuario";
let nos_host = arestas_auth | distinct hostname
    | project nodeId = hostname, rotulo = hostname, tipoNo = "Host";
let todos_nos = union nos_ip, nos_usuario, nos_host;
// Arestas IP -> Usuario
let ip_usuario = arestas_auth
    | project Fonte = src_ip, Destino = usuario, logins, falhas;
// Arestas Usuario -> Host
let usuario_host = arestas_auth
    | project Fonte = usuario, Destino = hostname, logins, falhas;
union ip_usuario, usuario_host
| make-graph Fonte --> Destino com todos_nos em nodeId
| graph-match (ip)-[e1]->(usuario)-[e2]->(host)
    onde e2.falhas > 20
    project
        IP = ip.rotulo,
        Usuario = usuario.rotulo,
        Host = host.rotulo,
        Falhas = e2.falhas
| order by Falhas desc

Detecção de movimento lateral: usuários compartilhando hosts comprometidos

// Padrão: (usuario1)-[auth1]->(host)<-[auth2]-(usuario2)
// Dois usuários falhando no mesmo host = possível spray de credenciais
let arestas = EventosAutenticacao
    | summarize falhas = countif(resultado == "Falha de Login"), logins = count()
      by usuario, hostname;
let nos = union
    (arestas | distinct usuario | project nodeId = usuario, tipoNo = "Usuario"),
    (arestas | distinct hostname | project nodeId = hostname, tipoNo = "Host");
arestas
| make-graph usuario --> hostname com nos em nodeId
| graph-match (u1)-[e1]->(h)<-[e2]-(u2)
    onde u1.nodeId != u2.nodeId and e1.falhas > 10 and e2.falhas > 10
    project
        Usuario1 = u1.nodeId, Usuario2 = u2.nodeId,
        HostCompartilhado = h.nodeId,
        FalhasU1 = e1.falhas, FalhasU2 = e2.falhas
| distinct Usuario1, HostCompartilhado, Usuario2, FalhasU1, FalhasU2
| order by FalhasU1 + FalhasU2 desc

Caminho de ataque mais curto

let arestas = EventosSeguranca
    | project Fonte = entidade_origem, Destino = entidade_destino, acao, timestamp;
let nos = union
    (arestas | distinct Fonte | project nodeId = Fonte),
    (arestas | distinct Destino | project nodeId = Destino);
arestas
| make-graph Fonte --> Destino com nos em nodeId
| graph-shortest-paths (inicio)-[e*1..10]->(fim)
    onde inicio.nodeId == "IPExterno_1.2.3.4" e fim.nodeId == "ServidorBD"
    project
        TamanhoCaminho = array_length(e),
        Acoes = e.acao,
        Saltos = e.Destino

Componentes conectados: encontrar clusters isolados

let arestas = FluxosRede
    | project Fonte = src_ip, Destino = dst_ip;
let nos = union
    (arestas | distinct Fonte | project nodeId = Fonte),
    (arestas | distinct Destino | project nodeId = Destino);
arestas
| make-graph Fonte --> Destino com nos em nodeId
| graph-mark-components with_component_id = ComponentId
| graph-to-table nodes
| summarize Membros = make_list(nodeId), Tamanho = count() by ComponentId
| order by Tamanho desc

Visualizar no Kusto Explorer

Termine uma consulta em make-graph (sem canalizar para graph-match) para acionar a janela de visualização interativa de grafos do Kusto Explorer:

arestas
| make-graph Fonte --> Destino com todos_nos em nodeId
// <- pare aqui. O Kusto Explorer renderiza o grafo visualmente.

Para achatar de volta para uma tabela para dashboards ou exportação, canalize através de graph-match | project ou graph-to-table.

Usando com IRQL

Ao trabalhar com dados de segurança, considere usar seletores IRQL (Get_*) da skill azure-kusto-irql como fonte de dados. O IRQL fornece um esquema unificado sem memorizar nomes de tabelas brutas ou mapeamentos de colunas. Para visualização rica com ícones e dobramento de nós, o Lift_To_Graph da skill azure-kusto-irql-graph é o caminho mais rápido.

AbordagemMelhor Para
make-graph bruto (esta skill)Controle total, modelos persistentes, caminhos mais curtos, componentes conectados, esquemas personalizados
Lift_To_Graph (azure-kusto-irql-graph)Visualização rápida decorada com ícones no Kusto Explorer, dobramento de nós
IRQL Get_* -> make-graphEsquema unificado do IRQL como entrada, depois operadores de grafo brutos para análise
IRQL Get_* -> Lift_To_Graph -> Graph_Render_ViewCaminho mais rápido da pergunta ao grafo visual

Nota: Lift_To_Graph, Graph_Render_View e Graph_Fold_By_Property são funções armazenadas, não operadores internos. Elas são pré-implantadas no cluster de exemplo kc7001, mas podem precisar de implantação em outros clusters. Veja azure-kusto-irql-graph/references/DEPLOY_IRQL_FUNCTIONS.md para definições de funções e instruções de implantação.

Exemplo: Seletores IRQL -> make-graph -> caminho mais curto

O IRQL lida com a recuperação de dados; make-graph lida com a análise de grafo.

Individual skills in this repo

This repo contains 12 individual skills — each has its own dedicated page.

microsoft/azure-ai-agents-persistent-dotnet

Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: "PersistentAgentsClient", "persistent agents", "agent threads", "agent runs", "streaming agents", "function calling agents .NET".

microsoft/azure-ai-document-intelligence-dotnet

Azure AI Document Intelligence SDK for .NET. Extract text, tables, and structured data from documents using prebuilt and custom models. Use for invoice processing, receipt extraction, ID document analysis, and custom document models. Triggers: "Document Intelligence", "DocumentIntelligenceClient", "form recognizer", "invoice extraction", "receipt OCR", "document analysis .NET".

microsoft/azure-ai-openai-dotnet

Azure OpenAI SDK for .NET. Client library for Azure OpenAI and OpenAI services. Use for chat completions, embeddings, image generation, audio transcription, and assistants. Triggers: "Azure OpenAI", "AzureOpenAIClient", "ChatClient", "chat completions .NET", "GPT-4", "embeddings", "DALL-E", "Whisper", "OpenAI .NET".

microsoft/azure-ai-projects-dotnet

Azure AI Projects SDK for .NET. High-level client for Azure AI Foundry projects including agents, connections, datasets, deployments, evaluations, and indexes. Use for AI Foundry project management, versioned agents, and orchestration. Triggers: "AI Projects", "AIProjectClient", "Foundry project", "versioned agents", "evaluations", "datasets", "connections", "deployments .NET".

microsoft/azure-ai-voicelive-dotnet

Azure AI Voice Live SDK for .NET. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots. Triggers: "voice live", "real-time voice", "VoiceLiveClient", "VoiceLiveSession", "voice assistant .NET", "bidirectional audio", "speech-to-speech".

microsoft/azure-eventgrid-dotnet

Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub/sub messaging, CloudEvents, and EventGridEvents. Triggers: "Event Grid", "EventGridPublisherClient", "CloudEvent", "EventGridEvent", "publish events .NET", "event-driven", "pub/sub".

microsoft/azure-eventhub-dotnet

Azure Event Hubs SDK for .NET. Use for high-throughput event streaming: sending events (EventHubProducerClient, EventHubBufferedProducerClient), receiving events (EventProcessorClient with checkpointing), partition management, and real-time data ingestion. Triggers: "Event Hubs", "event streaming", "EventHubProducerClient", "EventProcessorClient", "send events", "receive events", "checkpointing", "partition".

microsoft/azure-identity-dotnet

Azure Identity library for .NET. Authentication library for Azure SDK clients using Microsoft Entra ID. Use for DefaultAzureCredential, managed identity, service principals, and developer credentials. Triggers: "Azure Identity", "DefaultAzureCredential", "ManagedIdentityCredential", "ClientSecretCredential", "authentication .NET", "Azure auth", "credential chain".

microsoft/azure-kusto-irql

Compose IRQL (Incident Response Query Language) queries for Kusto cybersecurity investigations. Translates natural language hunting questions into composable IRQL pipelines using Get_*, Extract_*, and Enrich_* functions. WHEN: IRQL query, security hunt, threat hunting KQL, incident response query, compose hunting pipeline, failed logins, phishing investigation, lateral movement, process execution, file creation events.

microsoft/azure-kusto-irql-graph

Apply IRQL graph functions to KQL or IRQL query results for Kusto Explorer visualization. Generates Lift_To_Graph mappings and composes Graph_Render_View, Graph_Fold_By_Property, Extract_Node_*, Enrich_Node_*, and Enrich_Graph_* calls. Accepts a supplied query or limited basic natural-language source request; it is not a general natural-language-to-KQL/IRQL skill. WHEN: Lift_To_Graph, Graph_Render_View, Graph_Fold_By_Property, IRQL graph enrichment, graph mapping for existing query results, icon-decorated graph, fold graph nodes. Use azure-kusto-graph for native make-graph analysis, graph-match, shortest paths, components, or persistent graphs.

microsoft/azure-local

Plan, deploy, operate, and troubleshoot Azure Local (formerly Azure Stack HCI): sizing and prerequisites, Arc registration, lifecycle updates, workloads (Azure Local VMs, AKS on Azure Local, images, disks, logical networks), SDN and network security, and failure triage — starting read-only and confirming before risky changes. WHEN: Azure Local, Azure Stack HCI, Arc resource bridge, custom location, Azure Local VM, Arc VM, AKS on Azure Local, AKS hybrid, SDN, Lifecycle Manager, Azure Local update, disconnected site.

microsoft/azure-local-multi-rack

Plan, deploy, operate, and troubleshoot multi-rack (rack scale) deployments of Azure Local — preintegrated racks scaling to hundreds of machines, built on Network Fabric Controller, Cluster Manager, SAN storage, and managed network fabric. Use for the Microsoft.NetworkCloud and Microsoft.ManagedNetworkFabric control plane. NOT for standard 1-16 node Azure Local, and NOT for rack-aware clusters (two racks as availability zones, up to 8 nodes, synchronous replication) — those are standard scale. WHEN: multi-rack, rack scale Azure Local, aggregation rack, compute rack, Network Fabric Controller, NFC, Cluster Manager, network fabric, isolation domain, az networkcloud, az networkfabric, multi-rack logical network, multi-rack Arc VM.

Habilidades Relacionadas