Files
aiops/backend/pkg/agentcli/agentcli.go
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

110 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package agentcli 是 Agent CLI 引擎的顶层入口。 // Logan.Li
// 组装 llm 客户端 + 工具注册中心(含 ssh_execute)+ 安全控制器 + Evolver + ReAct 核心,
// 对外暴露 Engine,由 controller 通过依赖注入(EventCallback / ConfirmFn / SSH 凭据)驱动。
//
// 设计原则(参考 opsxcli,适配为 aiops 后端库):
// - 零业务依赖:不 import model/controller,所有持久化与 WS 由 controller 层负责。
// - 复用 aiops 既有能力:LLM 走 OpenAI 兼容(model.LLMConfig),SSH 走 pkg/remoteexec。
// - 安全:危险命令黑名单硬拒,高危命令经 ConfirmFn 由前端确认。
// - 自进化:Evolver 异步学习经验并注入下次 Prompt,失败优雅降级。
package agentcli
import (
"context"
"ezops/pkg/agentcli/core"
"ezops/pkg/agentcli/evolver"
"ezops/pkg/agentcli/llm"
"ezops/pkg/agentcli/safety"
"ezops/pkg/agentcli/tools"
"ezops/pkg/remoteexec"
)
// EngineConfig 引擎配置(由 controller 从 model.LLMConfig + model.Server 构建后注入) // Logan.Li
type EngineConfig struct {
LLM llm.Config // LLM 客户端配置(endpoint 已解析)
SSH remoteexec.SSHConfig // 目标主机 SSH 配置(含凭据)
SafetyMode safety.Mode // 安全模式(默认 balanced)
Core *core.Config // ReAct 配置(nil 用默认)
MemoryDir string // Evolver 记忆目录(空则 data/agentcli)
}
// Engine Agent CLI 引擎实例(每个 WebSocket 连接 / 任务一个) // Logan.Li
type Engine struct {
agent *core.Agent
safety *safety.Controller
tools *tools.Registry
evolver *evolver.EvolverEngine
}
// NewEngine 组装引擎并注册默认工具集 // Logan.Li
func NewEngine(cfg EngineConfig) (*Engine, error) {
coreCfg := cfg.Core
if coreCfg == nil {
coreCfg = core.DefaultConfig()
}
if cfg.MemoryDir != "" {
coreCfg.MemoryDir = cfg.MemoryDir
}
mode := cfg.SafetyMode
if mode == "" {
mode = safety.ModeBalanced
}
// LLM 客户端
client := llm.NewClient(cfg.LLM)
// 工具注册中心:ssh_execute(注入目标主机凭据)+ analyze_output
registry := tools.NewRegistry()
registry.Register(tools.NewSSHExecuteTool(cfg.SSH, coreCfg.ToolTimeout))
registry.Register(tools.NewAnalyzeOutputTool())
// 安全控制器
sc := safety.NewController(mode)
// Evolver(LLM 可用时启用学习;失败降级)
ev, err := evolver.NewEvolverEngine(coreCfg.MemoryDir, client)
if err != nil {
ev = nil // 降级:无自学习,不影响主流程
}
agent := core.NewAgent(client, registry, coreCfg, sc, ev)
return &Engine{agent: agent, safety: sc, tools: registry, evolver: ev}, nil
}
// SetCallback 注入事件回调(驱动前端渲染 + DB 持久化) // Logan.Li
func (e *Engine) SetCallback(cb core.EventCallback) { e.agent.SetCallback(cb) }
// SetConfirmFn 注入高危确认回调(controller 推 WS confirm 事件并阻塞等前端回传) // Logan.Li
func (e *Engine) SetConfirmFn(fn safety.ConfirmFn) { e.safety.SetConfirmFn(fn) }
// SetAutoApprove 测试用:自动批准(生产禁用) // Logan.Li
func (e *Engine) SetAutoApprove(b bool) { e.safety.SetAutoApprove(b) }
// Run 执行任务(ReAct 循环),serverInfo 为目标主机摘要(注入 system prompt) // Logan.Li
func (e *Engine) Run(ctx context.Context, query, serverInfo string) (string, error) {
res, err := e.agent.Run(ctx, query, serverInfo)
if err != nil {
return "", err
}
if res != nil {
return res.Output, nil
}
return "", nil
}
// EvolveStats 进化统计(供审计展示) // Logan.Li
func (e *Engine) EvolveStats() map[string]interface{} {
if e.evolver == nil {
return map[string]interface{}{"enabled": false}
}
return e.evolver.GetStats()
}
// Close 释放资源 // Logan.Li
func (e *Engine) Close() {
if e.agent != nil {
e.agent.Close()
}
}