Skills (tools)
Uma skill é uma capacidade auto-contida que o LLM pode invocar. O framework de skill auto-deriva o registro da tool no LLM, a API HTTP, o form da UI, o gate de permissão, e o audit log a partir de uma única struct de metadados — adicionar uma nova skill significa escrever um arquivo e chamar Register em init().
Skills são L2 (device-direct) quando rodam num edge agent, L3 (inteligência) quando rodam no manager. Ambas são first-class.
Anatomia
Toda skill distribui:
// internal/skill/types.go:99
type Metadata struct {
Key string // lower_snake — id in dedupe keys, audit logs, LLM tool names
Name string // human label
Description string // shown to humans AND to the LLM
Class Class // safe | mutating | dangerous
Scope Scope // host (default) | manager
Category string // free-form group label
Params ParamSchema
ResultPreview string
}Mais um Executor:
type Executor interface {
Metadata() Metadata
Execute(ctx context.Context, params json.RawMessage) (json.RawMessage, error)
}O framework despacha com base em Scope:
ScopeHost— o manager envolve a chamada em um RPC de tunnel (Caller.Call(ctx, edgeID, "execute_skill", body)), o único handlerexecute_skilldo edge agent despacha por chave. O wrapper de tool do LLM injeta uma propriedade integer obrigatóriaedge_idno schema.ScopeManager— roda in-process. Semedge_id; útil para chamadas à internet pública (web_search), APIs externas, skill packs subprocess.
Classes de permissão
Embutidas nos metadados de modo que o gate roda em toda invocação, não como um bolt-on:
| Class | Exemplos | Quem pode invocar |
|---|---|---|
safe | probe_*, read_file, tail_file, query_promql | LLM, qualquer role |
mutating | restart_service, kill_process | Exige aprovação human-in-the-loop (parqueado, mas o gate existe) |
dangerous | rm, reboot, drop_table | Exige SOP assinado RSA + aprovação dual (parqueado) |
A classe padrão é safe — mas o framework loga warning no registro quando o autor esquece de setar o campo, então isso não passa silenciosamente. Veja types.go:205.
O skill_bridge.go no registry de tools do aiops atualmente só expõe skills ClassSafe ao LLM — veja skill_bridge.go. Classes mutating e dangerous esperam pelo workflow de aprovação PR-G4.
As três populações de skill
Go builtins (edge)
Escritos à mão em internal/skill/builtin/:
| Key | O que |
|---|---|
probe_http, probe_dns, probe_tcp | Read-only de alcançabilidade de rede |
tail_file, read_journal | Superfície de log |
host_netns_inspect | Inventário de network namespace |
web_search | Lado do manager; SearXNG por padrão, configurável |
restart_service | Mutating; gateado |
Cada um é um arquivo Go com init() chamando skill.Register. O binário do edge distribui cada builtin embutido — sem instalação de plugin, sem superfície de execução de código remoto.
Skill packs subprocess
Para capacidades que você quer largar sem rebuildar o edge agent, distribua um diretório com um manifesto skill.json e um executável. O loader em internal/skill/subprocess.go lê o manifesto, registra a skill, despacha Execute ao binário com params no stdin.
Usado para: ferramentas de pesquisa de rede (ovs-vsctl, nft, bpftool, ethtool, ip netns), helpers de inspeção de Kubernetes — qualquer coisa onde o binário já existe e shellar ganha de reescrever em Go.
BaseTools do manager
A maior população. Vivem sob internal/manager/biz/aiops/tools/ como arquivos *_basetool.go. Cada um carrega seu próprio JSON Schema escrito à mão (necessário para shapes que o ParamSchema declarativo não consegue expressar: arrays, objetos aninhados, oneOf).
BaseTools selecionados:
| Tool | O que faz |
|---|---|
bash | Shell num edge alvo (gateado; gravado) |
query_promql, query_logql, query_traceql | Os três backends de observabilidade |
query_incidents, get_incident_detail, query_alert_rules | Superfície de alerta |
query_edges, query_change_events | Inventário + auditoria |
correlate_incident | Fan-out composto a prom + log + trace |
expand_topology, find_topology_node, get_topology | Grafo |
query_knowledge | RAG |
find_outlier_edges, rank_edges | Comparação multi-host |
host_load, host_processes, host_files | Tools de batch de estado de host |
get_edge_summary | Snapshot one-shot de saúde do edge |
restart_service | Wrapper do lado manager sobre a skill de restart do edge |
send_message | Comms coordinator → specialist |
task_stop, agent_tool | Ciclo de vida do worker |
Cerca de 30+ no total. A lista completa é o que estiver registrado em BuildBaseTools em cmd/ongrid/main.go.
A inventory bridge
Dois registries paralelos existiam antes da bridge:
- O registry de skill —
ScopeHostGo builtins + subprocess packs. Exposto na página/skillsdo SPA com audit + gate de class. - A BaseTool bag — tools do manager escritas à mão. Exposta ao LLM mas NÃO ao
/skills.
Operadores não conseguiam ver quais capacidades do lado cloud o agent realmente tinha sem ler o source. O inventory_bridge.go percorre a BaseTool bag e registra cada tool como uma skill com Scope=ScopeManager. A interface opt-in RawSchemaProvider é usada para preservar o JSON Schema escrito à mão de cada BaseTool verbatim.
Conforme o memo de 2026-05-08, 18 BaseTools são bridged por esse caminho — a página /skills agora lista cada capacidade do lado cloud com um chip de scope indicando edge vs manager.
A bridge reversa também está conectada: skill_bridge.go pega cada skill segura e a registra como uma Tool voltada ao LLM, então o LLM vê skills como tools de function-calling com um parâmetro edge_id auto-prefixado para as ScopeHost.
Auditoria
Toda invocação de tool escreve uma linha em chat_tool_calls:
session_id— a sessão do chatruntime que chamou.tool_name,args_json,result_json,error.device_id— quando a tool mirou um host específico (o campoEdgeIDemExecuteResult).started_at,finished_at,duration_ms.caller_user_id+caller_role— para chamadas originadas pelo LLM, o framework usaUserID=0/Role="system".
O audit log do HLD-010 pega carona na mesma tabela; a página admin /admin/audit o renderiza com timeline + filtros por tool.
Veja também
- WebShell — skill
bashexpressa como um terminal interativo em vez de uma única chamada de tool. - Conhecimento — deep dive em
query_knowledge. - Topologia —
expand_topology/find_topology_node. - Manifesto de skill — formato wire para skill packs subprocess.