Files
aiops/docs/agent/04-插件架构设计.md
T
attackerandClaude 92a2247390 feat: 新增 Agent CLI — Web 版 AI 运维 Agent(参考 opsxcli 移植)
后端引擎 backend/pkg/agentcli/(纯引擎库,零业务依赖,剥离 CLI/TUI 外壳):
- llm: OpenAI 兼容客户端,复用 model.LLMConfig
- tools: ssh_execute(复用 pkg/remoteexec)+ analyze_output + 风险评估黑名单
- safety: 三级安全模式 + 五级风险 + WebSocket 异步确认
- prompt: 五层 System Prompt
- core: ReAct 16 轮循环 + 自适应检查点 + 循环检测
- evolver: 四层记忆 + 进化循环,data/agentcli/ 文件存储

集成层:
- controller/agent_cli.go: WebSocket 控制器(事件流推流 + 高危确认 + 会话持久化)
- model/agent_cli.go: agent_cli_sessions/messages 表 + AutoMigrate
- 路由 /ws/agent-cli + /api/v1/aiops/agent-cli/sessions
- seed 权限 aiops:agent-cli / aiops:llm-config

前端:
- AgentCLI.tsx: 对话流 + 工具块 + 高危确认 + 四模块 tips 面板
- LLMConfig.tsx: 大模型设置独立页
- api/agentCli.ts + Sidebar/App 菜单路由

文档:
- docs/agent/ 11 篇(opsxcli 同名文档适配改写 + 00-README 映射总览)

其他:
- CLAUDE.md 补充 agent-cli 模块说明
- 修正 .gitignore 根级二进制规则(前导 /,避免误伤 frontend/src/components/aiops/)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-27 09:55:17 +08:00

7.4 KiB
Raw Blame History

04 - 插件架构设计

本文由 opsxcli 同名设计文档适配改写,结合 aiops Agent CLI 的 Web 实现(backend/pkg/agentcli/)。 opsxcli 的「plugins/」CLI 插件层(mysql/ssh/ping 等 46+ 命令)在 aiops 中不适用 —— Web 版聚焦远程运维,工具精简为 2 个并改由 tools.Tool 接口承载。

工具(Tool)= aiops 版的「插件」

opsxcli 有完整的 CLI 插件生态(46+ 命令插件);aiops Agent CLI 把「插件」概念收敛为更纯粹的 Tool 接口:

  • 不再有 CLI 命令、参数解析、帮助文本
  • 工具的唯一职责是:被 LLM 调用 → 在目标主机做事 → 返回结构化结果
  • LLM 通过 function calling 协议感知工具的存在与用法

这是合理的精简:Web Agent 的能力边界由「Tool 接口 + LLM 推理」共同决定,不再需要 CLI 命令那一层。

Tool 接口(5 方法)

// backend/pkg/agentcli/tools/registry.go

type Tool interface {
    Name() string                       // 工具名(LLM 调用时用)
    Description() string                // 给 LLM 看的描述
    Parameters() map[string]interface{} // JSON Schema 参数定义
    RiskLevel() RiskLevel               // 静态风险等级
    Execute(ctx context.Context, args map[string]interface{}) (*Result, error)
}

设计哲学:接口最小化 —— 5 个方法覆盖工具的完整生命周期。

DynamicRiskTool 扩展接口

type DynamicRiskTool interface {
    Tool
    RiskLevelForArgs(args map[string]interface{}) RiskLevel
}

部分工具的「静态风险」无法反映真实风险(如 ssh_execute 静态是 High,但 df -h 是 Safe、rm -rf / 是 Critical)。这些工具额外实现 DynamicRiskTool,安全控制器 Check 时优先调用动态评估。

Result 结构

type Result struct {
    Success bool   `json:"success"`
    Output  string `json:"output"`
    Error   string `json:"error,omitempty"`
}

Registry 注册中心

type Registry struct {
    tools map[string]Tool
    mu    sync.RWMutex  // 读写锁,支持并发注册和查询
}

核心方法:

方法 说明
NewRegistry() 创建空注册中心
Register(tool) 注册工具(线程安全)
Get(name) 按名获取工具(LLM 调用时按名查找)
List() 列出所有工具(构建 Prompt Layer 3 工具描述)
ToLLMTools() 转换为 OpenAI function calling 格式(自动注入到 LLM tools 参数)

ToLLMTools() 是 Registry 与 LLM 协议的桥梁:注册的工具自动出现在 LLM 的 function 列表中,无需手动维护。

已注册工具一览

与 opsxcli 的关键差异:opsxcli 有 6 个工具(local_bash / ssh_execute / scp_transfer / file_read / file_search / analyze_output),aiops 精简为 2 个。

工具 风险等级 功能 来源
ssh_execute High(静态)/ Safe~Critical(动态) 在目标主机远程执行 shell 命令 aiops 既有 pkg/remoteexec
analyze_output Safe 对冗长输出做摘要/错误提取 内置 Go 实现

为什么精简?

opsxcli 工具 aiops 处理 原因
local_bash 剥离 Web 后端不应在服务器本地执行命令(安全风险 + 多用户隔离)
scp_transfer 剥离 文件传输走 aiops 既有的「文件管理」模块,不混入 Agent
file_read 剥离 远程读文件用 ssh_execute cat,无需独立工具
file_search 剥离 远程搜文件用 ssh_execute grep/find
ssh_execute 保留 核心远程运维能力
analyze_output 保留 防止长输出 token 爆炸,辅助 LLM 聚焦关键信息

工具越少,LLM 的决策空间越收敛(呼应 Ashby 定律),首次做对的概率越高。

工具分类标准(aiops 版)

放入内置工具集的条件(需同时满足)

  1. 属于运维 Agent 高频需要的能力
  2. 无法用现有工具简单组合完成(如 analyze_output 不能用 ssh_execute 替代 —— 它操作的是已有文本而非远程命令)
  3. 实现简洁(单文件 < 300 行)

通过 ssh_execute 间接覆盖的能力

opsxcli 用独立插件实现的能力,在 aiops 中全部由 ssh_execute 执行远程命令覆盖:

opsxcli 插件能力 aiops 等效
mysql -e "..." ssh_execute "mysql -e \"...\""
redis-cli ... ssh_execute "redis-cli ..."
ping / traceroute ssh_execute "ping ..."
cat / grep / find ssh_execute "cat ..."
systemctl status nginx ssh_execute "systemctl status nginx"

LLM 会根据任务自主决定执行什么命令,无需为每类命令提供独立工具。

混合架构的好处

  1. 职责单一:每个工具只做一件事,ssh_execute 执行、analyze_output 分析
  2. 协议简单:LLM 只需理解 2 个 function,决策快、错误少
  3. 风险可控:所有远程操作统一走 ssh_execute 的风险评估(AssessBashRisk),不会因为工具增多而出现安全盲区
  4. 扩展灵活:未来若需要新工具(如 kubectl_apply),实现 Tool 接口注册即可

扩展指南

添加新工具

  1. 实现 Tool 接口(必要时实现 DynamicRiskTool):
// pkg/agentcli/tools/kubectl_get.go
type KubectlGetTool struct{ cfg remoteexec.SSHConfig }

func (t *KubectlGetTool) Name() string { return "kubectl_get" }
func (t *KubectlGetTool) Description() string {
    return "在目标主机执行 kubectl get 并返回结果"
}
func (t *KubectlGetTool) Parameters() map[string]interface{} {
    return map[string]interface{}{
        "type": "object",
        "properties": map[string]interface{}{
            "resource": map[string]interface{}{"type": "string", "description": "如 pods/deployments"},
        },
        "required": []string{"resource"},
    }
}
func (t *KubectlGetTool) RiskLevel() tools.RiskLevel { return tools.RiskSafe }
func (t *KubectlGetTool) Execute(ctx context.Context, args map[string]interface{}) (*tools.Result, error) {
    // 复用 remoteexec 执行 kubectl get
}
  1. 在 agentcli.NewEngine 中注册:
registry.Register(tools.NewSSHExecuteTool(cfg.SSH, coreCfg.ToolTimeout))
registry.Register(tools.NewAnalyzeOutputTool())
registry.Register(tools.NewKubectlGetTool(cfg.SSH))  // 新增
  1. 工具自动出现在 LLM 的 function 列表与 Prompt Layer 3 工具描述中。无需改 Prompt、controller、前端。

常见陷阱

陷阱 解决方案
忘记设置 RiskLevel 导致误判 默认按接口返回值,高危工具必须显式声明
高危工具未实现 DynamicRiskTool 静态等级无法反映参数差异(如 ssh_execute 看 df 还是 rm -rf),必须实现动态评估
工具 Execute 无超时 Config.ToolTimeout=120s 兜底(context.WithTimeout)
工具输出过长导致 token 爆炸 OutputMaxLength=10000 截断 + 引导 LLM 调用 analyze_output

总结

aiops Agent CLI 的「插件架构」是 opsxcli 的精简版:从「46+ CLI 插件」收敛为「2 个 Tool 接口实现」。这不是能力的退化,而是收敛决策空间、聚焦远程运维、降低 LLM 误判概率的有意设计。详细工具实现见 05 - Builtin 内置工具。

作者:Logan.Li