运维 Subagent
让 AI 帮你巡检系统、写运维笔记、复盘问题 -- 24/7 不休息的运维助手
你将学到
- 理解运维 Subagent 的概念和价值
- 编写 Agent 配置文件定义运维职责
- 创建巡检脚本自动检查服务状态
- 配置 macOS LaunchAgent 定时执行
- 利用 Agent 自动记录运维笔记和复盘
前置条件:已完成 Claude Code 配置,了解基础 shell 脚本
预计时间:45 分钟
一、什么是运维 Subagent
问题场景
你部署了多个 AI 服务 -- MLX 推理引擎、OpenClaw 网关、监控面板、Telegram Bot......
每天你需要:
- 检查每个服务是否正常运行
- 翻看日志找异常
- 发现问题后排查修复
- 记录发生了什么、怎么修的
服务少的时候手动搞没问题。但当你有 5 个、10 个服务时,这些重复工作就变成了负担。
解决方案
运维 Subagent = 专门负责系统巡检和维护的 AI Agent。
Claude Code 支持 Agent 模式,可以自主执行复杂任务链 -- 读文件、跑命令、分析结果、做决策、写报告。你可以把它训练成一个"首席运维官":
你(老板)
|
v
运维 Subagent(7x24 在线的运维工程师)
|
+-- 定时巡检所有服务
+-- 分析日志发现异常
+-- 写运维笔记
+-- 复盘历史问题
+-- 提出优化建议
类比:你雇了一个 24 小时在线的运维工程师。他不会累、不会忘、不会漏检。你只需要定义好他该做什么、怎么做。
二、Agent 配置文件
文件位置
Claude Code 的 Agent 定义文件放在 ~/.claude/agents/ 目录:
mkdir -p ~/.claude/agents配置框架
创建 ~/.claude/agents/ops-agent.md,这是你的运维 Agent 的"岗位说明书":
# ops-agent.md
## 身份
你是系统运维助手,负责监控和维护本机所有 AI 服务。
你的工作目标是:确保所有服务健康运行,发现问题及时报告。
## 服务清单
| 服务 | 端口 | 检查方式 | 重要性 |
|------|------|----------|--------|
| MLX 推理引擎 | 8000 | curl /v1/models | 核心 |
| OpenClaw 网关 | 18789 | curl /api/health | 核心 |
| 监控面板 API | 3940 | curl /api/v1/status | 重要 |
| 监控面板前端 | 3939 | curl / | 重要 |
| Open WebUI | 3000 | curl / | 普通 |
## 巡检流程
### Phase 1: 服务存活
对服务清单中的每个端口执行 HTTP 检查,超时 3 秒。
标记状态:正常 / 不可达 / 响应异常
### Phase 2: 资源检查
- 内存使用率(vm_stat 解析)
- 磁盘使用率(df -h)
- MLX 模型内存占用
### Phase 3: 日志分析
检查以下日志文件最近 1 小时的 ERROR / FATAL:
- ~/logs/mlx-server.log
- ~/logs/openclaw.log
### Phase 4: 汇总报告
按以下格式输出:
#### 巡检报告 YYYY-MM-DD HH:mm
- 故障数:X
- 警告数:X
- 服务状态:[列表]
- 发现的问题:[详情]
- 建议操作:[列表]
## 安全规则
- 绝不自行重启任何服务
- 发现需要重启的情况,报告给用户,由用户手动执行
- 不修改任何配置文件,只读取和分析关键设计原则
- 服务清单要完整 -- 遗漏一个服务就等于巡检盲区
- 巡检流程要明确 -- 每个 Phase 的输入、检查项、输出都要写清楚
- 安全边界要严格 -- Agent 只读不写,只报告不操作
- 输出格式要规范 -- 统一格式方便后续自动化处理
调用 Agent
# 在 Claude Code 中调用自定义 Agent
claude --agent ops-agent
# 或者用 /agent 命令
# 进入 Claude Code 后输入:
# /agent ops-agent三、巡检脚本
Agent 配置文件定义了"做什么",巡检脚本则提供了"怎么做"的基础工具。
基础巡检脚本
创建 ~/scripts/patrol.sh:
#!/bin/bash
# patrol.sh - 服务巡检脚本
# 用法: bash ~/scripts/patrol.sh
set -euo pipefail
# ===== 配置 =====
TIMEOUT=3 # curl 超时秒数
REPORT=""
FAILURES=0
WARNINGS=0
# 服务列表:名称|端口|路径
SERVICES=(
"MLX推理引擎|8000|/v1/models"
"OpenClaw网关|18789|/api/health"
"监控面板API|3940|/api/v1/status"
"监控面板前端|3939|/"
"OpenWebUI|3000|/"
)
# ===== 函数 =====
check_service() {
local name="$1"
local port="$2"
local path="$3"
local http_code
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
--connect-timeout "$TIMEOUT" \
"http://localhost:${port}${path}" 2>/dev/null || echo "000")
if [ "$http_code" = "200" ]; then
echo " [OK] $name (:$port)"
elif [ "$http_code" = "000" ]; then
echo " [FAIL] $name (:$port) - 不可达"
FAILURES=$((FAILURES + 1))
else
echo " [WARN] $name (:$port) - HTTP $http_code"
WARNINGS=$((WARNINGS + 1))
fi
}
check_memory() {
local mem_pressure
mem_pressure=$(memory_pressure 2>/dev/null | head -1 || echo "unknown")
echo " 内存压力: $mem_pressure"
# 磁盘使用
local disk_usage
disk_usage=$(df -h / | tail -1 | awk '{print $5}')
echo " 磁盘使用: $disk_usage"
}
check_launchagents() {
echo " LaunchAgent 状态:"
for plist in ~/Library/LaunchAgents/ai.*.plist; do
[ -f "$plist" ] || continue
local label
label=$(basename "$plist" .plist)
local status
status=$(launchctl list | grep "$label" || echo "未加载")
if echo "$status" | grep -q "$label"; then
echo " [OK] $label"
else
echo " [--] $label (未运行)"
fi
done
}
check_logs() {
local log_dir="${1:-$HOME/logs}"
local hours="${2:-1}"
local cutoff
cutoff=$(date -v-${hours}H +%Y-%m-%d\ %H:%M 2>/dev/null || date +%Y-%m-%d\ %H:%M)
echo " 最近 ${hours}h 错误日志:"
for logfile in "$log_dir"/*.log; do
[ -f "$logfile" ] || continue
local errors
errors=$(grep -ci "error\|fatal\|panic" "$logfile" 2>/dev/null || echo "0")
if [ "$errors" -gt 0 ]; then
echo " [!] $(basename "$logfile"): $errors 条错误"
WARNINGS=$((WARNINGS + 1))
fi
done
}
# ===== 执行 =====
echo "=============================="
echo " 巡检报告 $(date '+%Y-%m-%d %H:%M')"
echo "=============================="
echo ""
echo "[Phase 1] 服务存活检查"
for svc in "${SERVICES[@]}"; do
IFS='|' read -r name port path <<< "$svc"
check_service "$name" "$port" "$path"
done
echo ""
echo "[Phase 2] 系统资源"
check_memory
echo ""
echo "[Phase 3] LaunchAgent"
check_launchagents
echo ""
echo "[Phase 4] 日志分析"
check_logs "$HOME/logs" 1
echo ""
echo "=============================="
echo " 故障: $FAILURES | 警告: $WARNINGS"
echo "=============================="使用
# 赋予执行权限
chmod +x ~/scripts/patrol.sh
# 运行巡检
bash ~/scripts/patrol.sh输出示例:
==============================
巡检报告 2026-03-07 14:30
==============================
[Phase 1] 服务存活检查
[OK] MLX推理引擎 (:8000)
[OK] OpenClaw网关 (:18789)
[OK] 监控面板API (:3940)
[OK] 监控面板前端 (:3939)
[OK] OpenWebUI (:3000)
[Phase 2] 系统资源
内存压力: The system is under no memory pressure.
磁盘使用: 1%
[Phase 3] LaunchAgent
LaunchAgent 状态:
[OK] ai.mlx-lm-server
[OK] ai.openclaw.gateway
[OK] ai.neowatch-backend
[Phase 4] 日志分析
最近 1h 错误日志:
==============================
故障: 0 | 警告: 0
==============================
脚本设计要点
- 超时必须设置 -- 服务卡死时 curl 不会一直等
- 错误处理要完善 --
set -euo pipefail加|| echo兜底 - 输出格式要规范 -- 方便 Agent 解析,也方便人类阅读
- 服务列表要可扩展 -- 数组结构,增删服务只改一行
四、定时执行
巡检不能全靠手动。macOS 的 LaunchAgent 可以让脚本定时自动运行。
创建 LaunchAgent
创建 ~/Library/LaunchAgents/ai.patrol.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.patrol</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/你的用户名/scripts/patrol.sh</string>
</array>
<!-- 每 2 小时执行一次(偶数小时的第 10 分钟) -->
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Minute</key>
<integer>10</integer>
<key>Hour</key>
<integer>0</integer>
</dict>
<dict>
<key>Minute</key>
<integer>10</integer>
<key>Hour</key>
<integer>2</integer>
</dict>
<dict>
<key>Minute</key>
<integer>10</integer>
<key>Hour</key>
<integer>4</integer>
</dict>
<!-- 继续添加 6, 8, 10, 12, 14, 16, 18, 20, 22 -->
</array>
<key>StandardOutPath</key>
<string>/Users/你的用户名/logs/patrol.out.log</string>
<key>StandardErrorPath</key>
<string>/Users/你的用户名/logs/patrol.err.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin</string>
</dict>
</dict>
</plist>加载与管理
# 加载(开机自启)
launchctl load ~/Library/LaunchAgents/ai.patrol.plist
# 手动触发一次(测试用)
launchctl start ai.patrol
# 查看状态
launchctl list | grep ai.patrol
# 卸载(停止定时执行)
launchctl unload ~/Library/LaunchAgents/ai.patrol.plistLaunchAgent vs Cron
| 特性 | LaunchAgent | Cron |
|---|---|---|
| macOS 原生 | 是 | 是 |
| 错过执行后补偿 | 支持 | 不支持 |
| 日志管理 | 内置 | 需自行配置 |
| 环境变量 | 可在 plist 中定义 | 继承用户环境 |
| 推荐度 | 推荐 | 简单任务可用 |
LaunchAgent 的优势在于:如果定时触发时电脑处于睡眠状态,唤醒后会自动补执行。Cron 错过就错过了。
注意事项
PATH 环境变量
LaunchAgent 的 PATH 和你终端里的不同。如果脚本里用了
brew安装的工具(如jq), 必须在 plist 的EnvironmentVariables中显式设置 PATH,包含/usr/local/bin。 同理,sysctl等系统命令在/usr/sbin,也要包含。
五、笔记与复盘
自动运维笔记
运维 Agent 最有价值的能力之一是自动记录。每次巡检、每次故障排查,Agent 都可以写笔记。
在 Agent 配置中添加笔记规则:
## 笔记规则
每次巡检后,在 ~/Desktop/笔记/ 目录创建运维笔记:
### 文件名格式
运维-YYYY-MM-DD.md
### 笔记结构
# 运维: [日期]
> 巡检时间: HH:mm | 故障: X | 警告: X
## 服务状态
[表格]
## 发现的问题
### 问题 1: [标题]
- 症状: ...
- 原因: ...
- 修复: ...
- 教训: ...
## 系统快照
| 指标 | 值 |
|------|-----|
## 运维建议
### 短期
- [ ] ...
### 长期
- [ ] ...复盘流程
Agent 不仅记录当次巡检,还可以复盘历史问题:
## 复盘流程
当用户说"复盘"或"recap"时:
1. 读取最近 7 天的运维笔记
2. 统计:
- 故障总数和分类
- 重复出现的问题
- 平均修复时间
3. 分析趋势:
- 哪些服务最不稳定
- 哪些问题反复出现
- 资源使用趋势
4. 输出复盘报告,包含:
- 本周运维总结
- Top 3 问题及根因
- 改进建议
- 更新到记忆文件知识库积累
运维笔记长期积累后,就成了你的运维知识库:
~/Desktop/笔记/
运维-2026-03-01.md # NEO运维升级复盘
运维-2026-03-02.md # 六宝事件驱动刷新
运维-2026-03-03.md # 日常巡检
...
Agent 每次巡检时都会参考历史笔记,避免重复犯错。比如上次某个服务挂了是因为内存不足,Agent 会记住这个模式,下次看到内存接近阈值时提前预警。
六、实际案例:NEO运维的实践
从 5 个服务到 10 个服务
AINEOS 的运维 Agent 从最初的 5 个服务起步,经历了一次完整的扩展过程:
初始阶段(5 个服务):
MLX 推理引擎 (:8000)
OpenClaw 二宝 (:18789)
NeoWatch 后端 (:3940)
NeoWatch 前端 (:3939)
Open WebUI (:3000)
扩展后(10 个端口):
MLX 推理引擎 (:8000) # 核心 - 模型推理
OpenClaw 二宝 (:18789) # 管家 - 日报、心跳
OpenClaw 三宝 (:18790) # 交易员 - 加密货币分析
四宝引擎 (:3721) # 量化 - 宝藏发现
四宝大脑 (:18796) # 量化 - 决策中心
六宝引擎 (:6789) # 预测市场 - 交易执行
六宝大脑 (:18795) # 预测市场 - 策略分析
NeoWatch 后端 (:3940) # 监控 - API
NeoWatch 前端 (:3939) # 监控 - 仪表盘
Open WebUI (:3000) # 聊天界面
扩展过程中的教训
这次扩展涉及 9 个文件变更,包括 Agent 配置、巡检脚本、服务管理脚本等。以下是几个关键教训:
1. 服务清单必须同步更新
新增服务后,所有相关的配置都要更新 -- Agent 定义、巡检脚本、监控采集器、文档。遗漏任何一个都会产生巡检盲区。
2. 日志路径要覆盖所有实例
初始版本只检查 3 个日志文件,扩展后需要覆盖 8 个。4 个 OpenClaw 实例各有独立的日志目录。
3. 定时巡检的误报处理
有些服务是周期性运行的(比如 cron 触发的分析任务),巡检时可能正好处于空闲状态。脚本需要维护一个"周期性服务白名单",避免误报。
4. Agent 安全边界要严格
运维 Agent 绝不自行重启服务。特别是 MLX 推理引擎,重启极易导致 GPU 卡死。Agent 只负责发现问题和报告,由人类决定是否重启。
巡检效果
定时巡检部署后(每 2 小时一次,每天 12 次):
- 首次巡检发现 1 个配置缺失问题(auth 文件未复制)
- 日志分析发现 3 个非紧急但需关注的模式
- 系统状态快照为后续排障提供了基线数据
总结
核心要点
- Agent 配置文件 -- 定义运维职责、服务清单、巡检流程
- 巡检脚本 -- 自动化的健康检查工具
- 定时执行 -- LaunchAgent 保证 7x24 覆盖
- 笔记与复盘 -- 积累运维知识库,避免重复犯错
推荐的起步路径
第 1 天: 写 Agent 配置 + 基础巡检脚本
第 2 天: 配置 LaunchAgent 定时执行
第 3 天: 添加笔记规则,开始积累知识库
第 7 天: 第一次复盘,优化巡检流程
从 3-5 个服务开始,随着基础设施增长逐步扩展。不要一开始就追求完美 -- 先跑起来,再持续改进。
下一步 OpenClaw 进阶 -->