Communitygithub.com

microsoft/azure-kusto-graph

Construye y consulta grafos de Kusto a partir de lenguaje natural. Cubre grafos transitorios (make-graph), modelos/instantáneas de grafos persistentes, coincidencia de patrones (graph-match), caminos más cortos, componentes conectados y exportación de grafo a tabla.

¿Qué es azure-kusto-graph?

Esta habilidad permite a un agente de IA construir y consultar grafos en Azure Data Explorer (Kusto) utilizando operadores de grafos en KQL, partiendo de descripciones en lenguaje natural. Es útil para analistas de seguridad, ingenieros de datos y desarrolladores que necesitan modelar relaciones entre entidades (como usuarios, hosts o IPs) para detectar patrones de ataque o rutas de acceso sospechosas. Soporta la creación de grafos transitorios (make-graph) para análisis ad-hoc, así como modelos de grafos persistentes y sus instantáneas para escenarios de producción y reutilización a gran escala. La habilidad se activa cuando el usuario menciona términos como 'make-graph', 'graph-match', 'graph-shortest-paths', 'find connected components' o 'persistent graph', y sigue un enfoque 'edges-first' para definir aristas, nodos y luego construir el grafo. También incluye ejemplos prácticos de caza de amenazas, detección de movimiento lateral y caminos de ataque, e integración con otras habilidades como azure-kusto-irql para obtener datos de seguridad con un esquema unificado.

Compatible con~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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Semántica de Grafos en Kusto

Construye grafos transitorios y persistentes a partir de datos tabulares usando operadores de grafos en KQL. Esta habilidad traduce lenguaje natural al patrón de construcción de grafos basado en aristas y operadores de consulta de grafos.

Disparadores de Activación

Usa esta habilidad cuando el usuario:

  • Quiere construir un grafo a partir de datos tabulares (make-graph)
  • Pide encontrar patrones, caminos o relaciones en los datos
  • Menciona graph-match, graph-shortest-paths, graph-to-table, graph-mark-components
  • Quiere crear un modelo de grafo persistente o una instantánea
  • Dice "construye un grafo", "encuentra el camino más corto", "encuentra componentes conectados", "muestra relaciones"
  • Pregunta sobre grafos transitorios vs. persistentes

No es un conversor de lenguaje natural a KQL. La entrada generalmente debe ser una consulta KQL funcional cuyos resultados el usuario quiere convertir a un grafo, más una descripción en lenguaje natural de la estructura de grafo deseada. Las solicitudes básicas en lenguaje natural solo se admiten cuando se asignan directamente a una tabla conocida con columnas obvias. Para la conversión general de NL a KQL, utiliza una habilidad de generación de consultas dedicada (disponible por separado).

Habilidades complementarias:

  • azure-kusto-irql -- primitivas de consulta de seguridad componibles que producen las entradas tabulares para los grafos
  • azure-kusto-irql-graph -- el sistema de mapeo JSON Lift_To_Graph de IRQL para grafos con tipos enriquecidos y decorados con iconos en Kusto Explorer

El Enfoque de Aristas Primero

El patrón fundamental para construir grafos en Kusto:

1. Define tus ARISTAS       -> src --> dest, con tipo de relación/propiedades
2. Define tus BÚSQUEDAS DE NODOS -> nombres para mostrar, tipos, propiedades para cada ID de nodo
3. Une los tipos de aristas         -> si tienes múltiples tipos de relación
4. Une las búsquedas de nodos       -> si tienes múltiples tipos de nodo
5. Llama a make-graph          -> edges | make-graph Source --> Target with nodes on nodeId

Así es como se piensa en make-graph. Las aristas son las relaciones que te importan. Los nodos son tablas de búsqueda que dan una cara a esos IDs: nombres para mostrar, tipos, propiedades.

Referencia de Operadores de Grafos

make-graph -- Construye un grafo a partir de tablas

Edges | make-graph SourceId --> TargetId with Nodes on NodeId
  • Edges: fuente tabular donde cada fila es una arista
  • SourceId --> TargetId: columnas que contienen los IDs de nodo origen y destino
  • with Nodes on NodeId: tabla opcional de propiedades de nodo unida por ID
  • Soporta múltiples tablas de nodos: with Nodes1 on Id1, Nodes2 on Id2
  • Los nodos que aparecen en las aristas pero faltan en la tabla de nodos obtienen propiedades vacías

graph-match -- Busca patrones

G | graph-match (a)-[e]->(b) where <restricciones> project <salida>

Notación de patrones:

ElementoNombradoAnónimo
Nodo(n)()
Arista izquierda->derecha-[e]->-->
Arista derecha->izquierda<-[e]-<--
Cualquier dirección-[e]---
Longitud variable-[e*1..5]->-[*1..5]->

Patrones de múltiples saltos: (a)-[e1]->(b)-[e2]->(c) Patrones de estrella: (a)--(centro)--(b), (c)--(centro)--(d) Control de ciclos: cycles = all | none | unique_edges (por defecto: unique_edges)

graph-shortest-paths -- Encuentra caminos más cortos

G | graph-shortest-paths (inicio)-[e*1..20]->(fin)
      where inicio.name == "Alice" and fin.name == "Server01"
      project Camino = e, Longitud = array_length(e)
  • Requiere al menos una arista de longitud variable
  • output = any (por defecto, un camino por par) o output = all (todos los caminos más cortos de igual longitud)
  • Las propiedades de arista de longitud variable se devuelven como arrays dinámicos

graph-to-table -- Exporta grafo a tablas

G | graph-to-table nodes                                     // exportar nodos
G | graph-to-table edges                                     // exportar aristas
G | graph-to-table nodes as N, edges as E                    // exportar ambos
G | graph-to-table nodes with_node_id=Id                     // incluir ID hash del nodo
G | graph-to-table edges with_source_id=Src with_target_id=Tgt  // incluir IDs de extremos de arista

graph-mark-components -- Encuentra componentes conectados

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

Asigna un ComponentId a cada nodo. Los nodos en el mismo componente conectado comparten el mismo ID.

graph() función -- Consulta grafos persistentes

graph("MiModeloDeGrafo")                              // última instantánea
graph("MiModeloDeGrafo", "Snapshot_2025_01")           // instantánea específica
graph("MiModeloDeGrafo", true)                         // transitorio a partir de la definición del modelo

Grafos Transitorios

Creados dinámicamente durante la ejecución de la consulta. Sin configuración previa. Ideales para análisis ad-hoc, exploración y prototipado.

Plantilla: Grafo básico de dos entidades

// 1. Definir aristas
let edges = <TablaOrigen>
    | summarize <agregaciones> by ColOrigen, ColDestino;
// 2. Definir búsquedas de nodos
let source_nodes = edges
    | distinct ColOrigen
    | project nodeId = ColOrigen, label = ColOrigen, nodeType = "<TipoOrigen>";
let target_nodes = edges
    | distinct ColDestino
    | project nodeId = ColDestino, label = ColDestino, nodeType = "<TipoDestino>";
let all_nodes = union source_nodes, target_nodes;
// 3. Construir y consultar el grafo
edges
| make-graph ColOrigen --> ColDestino with all_nodes on nodeId
| graph-match (s)-[e]->(t)
    where <restricciones>
    project Origen = s.label, Destino = t.label, <propiedades de arista>

Plantilla: Grafo multi-relación

// Múltiples tipos de aristas -> unirlos con un esquema común
let auth_edges = EventosAutenticacion
    | project Origen = nombre_usuario, Destino = nombre_host, tipoArista = "autentica", ts = timestamp;
let net_edges = EventosRed
    | project Origen = src_ip, Destino = url, tipoArista = "conecta", ts = timestamp;
let all_edges = union auth_edges, net_edges;
// Búsquedas de nodos de todas las fuentes
let user_nodes = Empleados | project nodeId = nombre_usuario, label = nombre, nodeType = "Usuario";
let host_nodes = EventosAutenticacion | distinct nombre_host | project nodeId = nombre_host, label = nombre_host, nodeType = "Host";
let all_nodes = union user_nodes, host_nodes;
all_edges
| make-graph Origen --> Destino with all_nodes on nodeId

Grafos Persistentes

Para grafos reutilizables a gran escala. Almacenados en metadatos de la base de datos. Soportan instantáneas para comparación histórica.

Seguridad: Crear o alterar modelos de grafo e instantáneas modifica la base de datos. Siempre muestra el comando exacto y confirma con el usuario antes de ejecutar .create-or-alter graph_model o .make graph_snapshot.

Paso 1: Crear un modelo de grafo

.create-or-alter graph_model GrafoSeguridad
{
  "Schema": {
    "Nodes": {
      "Usuario": {"nombre": "string", "rol": "string"},
      "Host":   {"nombre_host": "string"},
      "IP":     {"ip": "string"}
    },
    "Edges": {
      "AutenticaEn": {"timestamp": "datetime", "resultado": "string"},
      "ConectaDesde":    {"timestamp": "datetime"}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "Empleados | project nombre, rol",
        "NodeIdColumn": "nombre",
        "Labels": ["Usuario"]
      },
      {
        "Kind": "AddNodes",
        "Query": "EventosAutenticacion | distinct nombre_host | project nombre_host",
        "NodeIdColumn": "nombre_host",
        "Labels": ["Host"]
      },
      {
        "Kind": "AddEdges",
        "Query": "EventosAutenticacion | project nombre_usuario, nombre_host, timestamp, resultado",
        "SourceColumn": "nombre_usuario",
        "TargetColumn": "nombre_host",
        "Labels": ["AutenticaEn"]
      }
    ]
  }
}

Paso 2: Crear una instantánea

.make graph_snapshot GrafoSeguridad Snapshot_2025_07

Paso 3: Consultar la instantánea

graph("GrafoSeguridad")
| graph-match (usuario)-[auth]->(host)
    where usuario.rol == "Admin" and auth.resultado == "Inicio de sesión fallido"
    project Usuario = usuario.nombre, Host = host.nombre_host, Hora = auth.timestamp

Comandos de administración

Seguridad: Todos los comandos de control a continuación modifican o eliminan objetos de la base de datos. Nunca ejecutes .drop, .create-or-alter graph_model, o .make graph_snapshot automáticamente. Siempre muestra el comando exacto, clúster, base de datos y objeto afectado, luego requiere confirmación explícita del usuario antes de la ejecución.

.show graph_models                        // listar todos los modelos
.show graph_model GrafoSeguridad           // mostrar detalles del modelo
.show graph_snapshots GrafoSeguridad       // listar instantáneas
.drop graph_snapshot GrafoSeguridad Snapshot_2025_07  // eliminar una instantánea (CONFIRMAR PRIMERO)
.drop graph_model GrafoSeguridad           // eliminar modelo y todas las instantáneas (CONFIRMAR PRIMERO)

Transitorio vs Persistente: Cuándo Usar Cada Uno

FactorTransitorio (make-graph)Persistente (graph())
ConfiguraciónNinguna -- en línea en la consultaCrear modelo + instantánea
DuraciónSolo durante la ejecución de la consultaAlmacenado en metadatos de la base de datos
Frescura de datosSiempre actualInstantánea en el momento de creación
EscalaLimitado por la memoria de la consultaA escala empresarial
ReutilizaciónReconstruido en cada consultaCompartido entre usuarios/consultas
Mejor paraInvestigaciones ad-hoc, prototipadoFlujos de trabajo de producción, paneles

Ejemplos de Seguridad y Caza de Amenazas

Grafo de autenticación: quién inició sesión en qué y desde dónde

let auth_edges = EventosAutenticacion
    | summarize
        inicios = count(),
        fallos = countif(resultado == "Inicio de sesión fallido")
      by src_ip, nombre_usuario, nombre_host;
let ip_nodes = auth_edges | distinct src_ip
    | project nodeId = src_ip, label = src_ip, nodeType = "IP";
let user_nodes = auth_edges | distinct nombre_usuario
    | project nodeId = nombre_usuario, label = nombre_usuario, nodeType = "Usuario";
let host_nodes = auth_edges | distinct nombre_host
    | project nodeId = nombre_host, label = nombre_host, nodeType = "Host";
let all_nodes = union ip_nodes, user_nodes, host_nodes;
// Aristas IP -> Usuario
let ip_user = auth_edges
    | project Origen = src_ip, Destino = nombre_usuario, inicios, fallos;
// Aristas Usuario -> Host
let user_host = auth_edges
    | project Origen = nombre_usuario, Destino = nombre_host, inicios, fallos;
union ip_user, user_host
| make-graph Origen --> Destino with all_nodes on nodeId
| graph-match (ip)-[e1]->(usuario)-[e2]->(host)
    where e2.fallos > 20
    project
        IP = ip.label,
        Usuario = usuario.label,
        Host = host.label,
        Fallos = e2.fallos
| order by Fallos desc

Detección de movimiento lateral: usuarios que comparten hosts comprometidos

// Patrón: (usuario1)-[auth1]->(host)<-[auth2]-(usuario2)
// Dos usuarios con fallos en el mismo host = posible ataque de credenciales
let edges = EventosAutenticacion
    | summarize fallos = countif(resultado == "Inicio de sesión fallido"), inicios = count()
      by nombre_usuario, nombre_host;
let nodes = union
    (edges | distinct nombre_usuario | project nodeId = nombre_usuario, nodeType = "Usuario"),
    (edges | distinct nombre_host | project nodeId = nombre_host, nodeType = "Host");
edges
| make-graph nombre_usuario --> nombre_host with nodes on nodeId
| graph-match (u1)-[e1]->(h)<-[e2]-(u2)
    where u1.nodeId != u2.nodeId and e1.fallos > 10 and e2.fallos > 10
    project
        Usuario1 = u1.nodeId, Usuario2 = u2.nodeId,
        HostCompartido = h.nodeId,
        FallosU1 = e1.fallos, FallosU2 = e2.fallos
| distinct Usuario1, HostCompartido, Usuario2, FallosU1, FallosU2
| order by FallosU1 + FallosU2 desc

Camino de ataque más corto

let edges = EventosSeguridad
    | project Origen = entidad_origen, Destino = entidad_destino, accion, timestamp;
let nodes = union
    (edges | distinct Origen | project nodeId = Origen),
    (edges | distinct Destino | project nodeId = Destino);
edges
| make-graph Origen --> Destino with nodes on nodeId
| graph-shortest-paths (inicio)-[e*1..10]->(fin)
    where inicio.nodeId == "IP_Externa_1.2.3.4" and fin.nodeId == "ServidorBaseDeDatos"
    project
        LongitudCamino = array_length(e),
        Acciones = e.accion,
        Saltos = e.Destino

Componentes conectados: encontrar clústeres aislados

let edges = FlujosRed
    | project Origen = src_ip, Destino = dst_ip;
let nodes = union
    (edges | distinct Origen | project nodeId = Origen),
    (edges | distinct Destino | project nodeId = Destino);
edges
| make-graph Origen --> Destino with nodes on nodeId
| graph-mark-components with_component_id = ComponentId
| graph-to-table nodes
| summarize Miembros = make_list(nodeId), Tamaño = count() by ComponentId
| order by Tamaño desc

Visualizar en Kusto Explorer

Termina una consulta en make-graph (sin canalizar a graph-match) para activar la ventana de visualización interactiva de grafos de Kusto Explorer:

edges
| make-graph Origen --> Destino with all_nodes on nodeId
// <- detente aquí. Kusto Explorer renderiza el grafo visualmente.

Para aplanar de nuevo a una tabla para paneles o exportación, canaliza a través de graph-match | project o graph-to-table.

Usando con IRQL

Cuando trabajes con datos de seguridad, considera usar selectores de IRQL (Get_*) de la habilidad azure-kusto-irql como fuente de datos. IRQL te proporciona un esquema unificado sin necesidad de memorizar nombres de tablas sin procesar o asignaciones de columnas. Para visualización enriquecida con iconos y plegado de nodos, el Lift_To_Graph de la habilidad azure-kusto-irql-graph es el camino más rápido.

EnfoqueMejor para
make-graph sin procesar (esta habilidad)Control total, modelos persistentes, caminos más cortos, componentes conectados, esquemas personalizados
Lift_To_Graph (azure-kusto-irql-graph)Visualización rápida con iconos en Kusto Explorer, plegado de nodos
IRQL Get_* -> make-graphEsquema unificado de IRQL como entrada, luego operadores de grafo sin procesar para análisis
IRQL Get_* -> Lift_To_Graph -> Graph_Render_ViewCamino más rápido de la pregunta al grafo visual

Nota: Lift_To_Graph, Graph_Render_View y Graph_Fold_By_Property son funciones almacenadas, no operadores integrados. Están preimplementadas en el clúster de ejemplo kc7001 pero pueden necesitar implementación en otros clústeres. Consulta azure-kusto-irql-graph/references/DEPLOY_IRQL_FUNCTIONS.md para definiciones de funciones e instrucciones de implementación.

Ejemplo: Selectores IRQL -> make-graph -> camino más corto

IRQL maneja la recuperación de datos; make-graph maneja la construcción del grafo y el análisis. Este ejemplo encuentra todos los caminos desde un punto de entrada externo a un servidor de base de datos usando datos de red de IRQL:

let Get_NetworkTraffic_All = ()
{
    // Selector IRQL que devuelve tráfico de red con esquema unificado
    cluster("tu_cluster").database("tu_bd").Get_NetworkTraffic_All()
};
let edges = Get_NetworkTraffic_All
    | project Origen = SrcIpAddr, Destino = DstIpAddr, BytesTotales = TotalBytes;
let nodes = union
    (edges | distinct Origen | project nodeId = Origen),
    (edges | distinct Destino | project nodeId = Destino);
edges
| make-graph Origen --> Destino with nodes on nodeId
| graph-shortest-paths (inicio)-[e*1..15]->(fin)
    where inicio.nodeId == "IP_Externa_1.2.3.4" and fin.nodeId == "10.0.0.5"
    project LongitudCamino = array_length(e), Bytes = e.BytesTotales

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.

Skills relacionados