1. 立项背景与目标
背景:传统运维工具(Zabbix、Nagios等)架构重、门槛高,难以覆盖边缘节点;故障排查依赖人工经验,效率低;变更操作缺乏AI辅助和细粒度审批审计。ops-agent将系统巡检、AI问诊、安全审批和可视化看板整合为统一单机程序,填补市场空白。
目标:交付v0.1.0版本,提供TUI/Daemon/Dashboard三种运行模式;以LLM实现自然语言驱动的智能运维;建立本地审查+LLM评估+人工审批三层安全机制;发行包一键部署,开箱即用。
2. 软件功能与核心模块
智能对话引擎:集成LLM,支持自然语言交互,内置ReAct和Plan-and-Execute双策略自动适配任务复杂度,自主调用系统工具,实现“对话即运维”。
安全管控中心:本地规则硬拦截+LLM辅助风险评估+人工风险队列审批三层防线,五级风险分级(只读到关键变更),全程审计可追溯。
自动化巡检与调度:后台守护进程支持Cron定时采集CPU/内存/磁盘/网络等指标,扩展至K8s/容器/Prometheus巡检,阈值告警推送钉钉/企微,告警归并为Incident故障事件。
用户交互层:TUI终端界面(ratatui,六Tab页,键盘导航)+ Web Dashboard(React,可视化看板)。
3. 核心业务流程
故障诊断修复流程:SSH登录→TUI对话页输入自然语言(如“nginx起不来”)→Agent经LLM意图分析,调用check_service/journalctl等诊断工具(安全审查保障只读)→流式呈现诊断结果→修复操作识别为高风险→进入风险队列待人工审批(a键批准/x键拒绝)→执行并反馈结果。
无人值守巡检与干预流程:Daemon systemd开机自启→按Cron定时执行巡检(指标每分钟,深度每30分钟)→数据写入SQLite→超阈值生成告警并推送钉钉/企微→运维人员通过Dashboard/TUI介入查看→查阅Incident时间线和处置计划→高风险操作仍经人工审批后执行。
4. 项目范围与约束
包含:v0.1.0全部功能开发(24个功能点)、测试、文档、发行包及安装脚本。
不包含:第三方监控系统迁移工具、SaaS云服务、移动端APP、高可用集群部署。
技术约束:Rust 2024 + tokio;前端React+TypeScript+Bun;SQLite。
环境约束:兼容麒麟/Linux(x86_64/aarch64),依赖systemd和Python 3.8+,可选kubectl/Docker。
1. 整体架构与设计思路
ops-agent采用单进程多模式架构,一个二进制文件通过命令行参数切换TUI/Daemon/Dashboard三种运行模式。架构分为五层:数据持久层(SQLite)、基础设施层(配置管理/MCP工具注册/LLM客户端)、安全管控层(本地审查+LLM评估+风险审批)、业务逻辑层(Agent对话引擎+Daemon调度引擎)、表现层(TUI+Web)。
三个核心理念:AI原生——LLM作为运维交互核心入口;安全优先——高风险操作必经“评估-审批-执行”完整链路;轻量敏捷——单机部署、嵌入式数据库、静态编译。
技术栈:Rust + tokio(核心),ratatui(TUI),axum + React(Dashboard),SQLite(数据库),MCP协议(工具接入)。
2. “我”负责的模块与成果
安全管控模块:设计五级风险分级体系、工具调用强制校验、多Reviewer决策汇总(8种汇总模式)、参数自动脱敏。
Daemon调度模块:构建定时任务调度框架,实现MCP工具巡检、系统指标采集、Managed Target自动展开巡检、single-flight防重入、systemd watchdog。
配置管理模块:实现TOML配置加载链路(三级覆盖)、路径展开、注释保留写入、explain子命令。
量化成果:累计8000行Rust代码(safety/daemon/config三个模块15个源文件),5篇技术文档超2万字。安全模块支撑8项功能、8类风险100%拦截;Daemon模块支撑5项功能、26个MCP工具调度,CPU占用<2%;支持最多5个安全模型并行评估。
3. 遇到的难点与解决方案
Python子进程残留:MCP工具超时后子进程堆积。解决:设置独立进程组,超时时终止整个进程组。
TOML注释丢失:配置热加载后注释消失。解决:toml_edit增量修改AST节点,仅写回变更段。
LLM调用循环:多步推理时反复调用同一工具。解决:max_tool_rounds上限(默认5轮),策略综合决策,轮次从4轮降至2轮。
SQLite锁冲突:并发读写频繁报错。解决:启用WAL模式,独立连接+busy_timeout,批量插入,查询用read_only。
Release panic定位难:无法定位错误位置。解决:保留调试符号,anyhow::Result加上下文,关键路径增加日志。