技能(tools)
一个技能是 LLM 可以调用的一个自包含能力。技能框架从单一 metadata 结构 体自动派生 LLM 工具注册、HTTP API、UI 表单、权限门、审计日志 —— 加一个新 技能等于写一个文件并在 init() 里调 Register。
技能跑在 edge agent 上时属于 L2(设备直达),跑在 manager 上时属于 L3 (智能)。两者都是一等公民。
解剖
每个技能发:
// 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
}加一个 Executor:
type Executor interface {
Metadata() Metadata
Execute(ctx context.Context, params json.RawMessage) (json.RawMessage, error)
}框架按 Scope 派发:
ScopeHost—— manager 把调用包成 tunnel RPC (Caller.Call(ctx, edgeID, "execute_skill", body)),edge agent 那唯一 一个execute_skillhandler 按 key 派发。LLM tool 包装在 schema 里注入 必填的edge_id整型属性。ScopeManager—— 进程内跑。无edge_id;适合走公网的调用 (web_search)、外部 API、子进程技能包。
权限分类
内置在 metadata 里,所以门在每次调用时都跑,不是事后栓上去:
| 类 | 例子 | 谁能调 |
|---|---|---|
safe | probe_*、read_file、tail_file、query_promql | LLM、任何角色 |
mutating | restart_service、kill_process | 需要 human-in-the-loop 批准(暂缓,但门存在) |
dangerous | rm、reboot、drop_table | 需要 RSA 签名 SOP + 双批准(暂缓) |
默认类是 safe —— 但作者忘了写字段时,框架会在注册时打 warning,所以这事 不会悄悄漏掉。见 types.go:205。
aiops tools registry 里的 skill_bridge.go 目前只把 ClassSafe 技能露给 LLM —— 见 skill_bridge.go。 mutating 和 dangerous 类等 PR-G4 审批流。
三种技能群体
Go 内置(edge)
| Key | 是什么 |
|---|---|
probe_http、probe_dns、probe_tcp | 只读网络连通性 |
tail_file、read_journal | 日志面 |
host_netns_inspect | 网络命名空间 inventory |
web_search | manager 侧;默认 SearXNG,可配置 |
restart_service | mutating;带门 |
每个都是一个 Go 文件,init() 里调 skill.Register。edge 二进制把所有内置 打进来 —— 不装插件,不留远程代码执行面。
子进程技能包
要不重建 edge agent 也能塞进去的能力,发一个目录,带 skill.json manifest 和一个可执行文件。 internal/skill/subprocess.go 的加载器读 manifest,注册技能,把 Execute 派给二进制并通过 stdin 传参数。
用在:网络研发工具(ovs-vsctl、nft、bpftool、ethtool、ip netns)、 Kubernetes inspect helper —— 任何"二进制已经存在,shell 出去比用 Go 重写 快"的场景。
manager 侧 BaseTool
最大那一群。住在 internal/manager/biz/aiops/tools/ 下的 *_basetool.go 文件里。每个带自己手写的 JSON Schema(声明式 ParamSchema 表达不了的形状需要:数组、嵌套对象、oneOf)。
精选 BaseTool:
| Tool | 做什么 |
|---|---|
bash | 在目标 edge 上跑 shell(带门;录像) |
query_promql、query_logql、query_traceql | 三大可观测后端 |
query_incidents、get_incident_detail、query_alert_rules | 告警面 |
query_edges、query_change_events | inventory + 审计 |
correlate_incident | 对 prom + log + trace 的复合扇出 |
expand_topology、find_topology_node、get_topology | 图 |
query_knowledge | RAG |
find_outlier_edges、rank_edges | 多主机比较 |
host_load、host_processes、host_files | 主机状态批量工具 |
get_edge_summary | 一次性 edge 健康快照 |
restart_service | manager 侧 edge restart skill 的封装 |
send_message | coordinator → specialist agent 通信 |
task_stop、agent_tool | worker 生命周期 |
总共大约 30+。完整列表是 cmd/ongrid/main.go 里 BuildBaseTools 注册的 那些。
inventory bridge
桥出现前并行两套 registry:
- 技能 registry ——
ScopeHost的 Go 内置 + 子进程包。露在 SPA 的/skills页,带审计 + class 门。 - BaseTool 工具包 —— 手写的 manager 侧工具。露给 LLM 但不露在
/skills。
运维不读源码就看不到 agent 实际持有什么云端能力。 inventory_bridge.go 走 BaseTool 工具包,把每个 tool 注册成 Scope=ScopeManager 的技能。可选的 RawSchemaProvider 接口用来逐字保留每个 BaseTool 手写的 JSON Schema。
按 2026-05-08 备忘录,18 个 BaseTool 经这条路桥接出来 —— /skills 页现在 列出每一项云端能力,并带一个 edge vs manager 的 scope chip。
反向桥也接好了: skill_bridge.go 把每个 safe 技能注册成 LLM 面的 Tool,所以 LLM 把技能当成函数调用工具, ScopeHost 的会被自动前缀一个 edge_id 参数。
审计
每次 tool 调用写一行 chat_tool_calls:
session_id—— 调用方 chatruntime 会话。tool_name、args_json、result_json、error。device_id—— 工具对准某台具体主机时(ExecuteResult上的EdgeID字段)。started_at、finished_at、duration_ms。caller_user_id+caller_role—— LLM 发起的调用框架用UserID=0/Role="system"。
HLD-010 审计日志搭在同一张表上;admin 的 /admin/audit 页用 timeline + 按 tool 过滤的方式渲染。
另见
- WebShell ——
bash技能的交互终端版(不是一次性 tool 调用)。 同样的审计底座。 - 知识库 ——
query_knowledge深度。 - 拓扑 ——
expand_topology/find_topology_node。 - Skill manifest —— 子进程技能包的 wire format。