Appearance
实战案例(一):智能运维助手
1. 本节产出
一个可演示的运维助手:接收告警 → 自动查指标/日志/变更记录 → 给出诊断结论与处置建议 → 高危操作进审批。核心是工具集设计和诊断逻辑的 prompt 工程。
2. 前置依赖
3. 为什么运维是 Agent 最好的落地场景
| 特点 | 为什么适合 |
|---|---|
| 信息分散在多个系统 | 人查要开 5 个页面,Agent 一次搞定 |
| 有标准排查流程 | 可编码为 prompt 工作流 |
| 只读操作为主 | 风险可控(查指标、查日志、查变更) |
| 故障有紧迫性 | 减少 MTTR 的价值容易量化 |
| 结果可验证 | 诊断对不对,很快能验证 |
关键:运维场景的「只读」特性让它成为最安全的 Agent 落地场景。 先做只读诊断,等信任建立后再逐步开放处置动作——这是一条稳妥的演进路径。
4. 核心原理
4.1 工具集设计
| 工具 | 风险 | 说明 |
|---|---|---|
queryMetrics(service, metric, range) | READ_ONLY | 查 CPU/内存/QPS/错误率 |
searchLogs(service, keyword, range) | READ_ONLY | 查日志(限流返回条数) |
listRecentChanges(service, range) | READ_ONLY | 查最近的发布/配置变更 |
queryTopology(service) | READ_ONLY | 查依赖拓扑 |
queryAlerts(service, range) | READ_ONLY | 查历史告警 |
restartService(service) | NEED_APPROVAL | 重启(高危,必须审批) |
scaleOut(service, replicas) | NEED_APPROVAL | 扩容 |
六个只读 + 两个需审批。这个配比是刻意设计的:让 Agent 90% 的工作是安全的,只在真正要处置时才触发审批。
4.2 诊断流程的 prompt 设计
系统提示(关键部分):
你是 SRE 助手,按以下流程诊断:
1. 确认影响面:查指标,确认是延迟、错误率还是资源问题
2. 定位变更:查最近 2 小时的发布与配置变更
└─ 有变更 → 高度怀疑是变更引起,优先建议回滚
3. 定位依赖:查拓扑,确认是否上游/下游引起
4. 查日志:用错误关键词检索,找具体错误
5. 给结论:按「现象 / 根因推测 / 置信度 / 建议动作」输出
规则:
- 每步都要调用工具获取证据,不要凭常识推断
- 置信度低于 0.6 时,明确说「需要人工介入」
- 涉及重启/扩容,必须走审批,不要直接建议执行「有变更 → 优先怀疑变更」这条经验规则是运维的核心知识,写进 prompt 能显著提升诊断准确率。这就是「把专家经验编码进 prompt」的实例。
4.3 置信度与人工介入
输出格式:
现象:订单服务 P99 从 200ms 涨到 3.2s,错误率 8%
根因推测:14:32 发布的 v2.3.1 引入了慢查询(置信度 0.85)
证据:[1] 变更记录 [2] 慢查询日志 [3] 数据库 CPU 曲线
建议:回滚 v2.3.1(需审批)必须输出置信度。低于阈值时明确说「需要人工介入」,而不是硬给一个低质量的结论。这是 Agent 产品化的重要细节:知道自己不知道。
4.4 与 RAG 的结合
运维知识库(RAG)提供:
- 历史故障案例(上次类似现象是怎么处理的)
- 服务文档(这个服务的架构、依赖、负责人)
- 应急预案(SOP)
Agent 流程中:
诊断完成后 → 检索历史相似案例 → 作为参考并入结论RAG + Agent 的组合:RAG 提供知识,Agent 提供行动。这是企业里最常见的组合形态。
5. 代码走查
5.1 工具实现
java
// ch03-agent/src/main/java/com/aitech/agent/caseops/OpsTools.java
@ToolComponent
public class OpsTools {
private final MetricsClient metrics;
private final LogClient logs;
private final ChangeClient changes;
@Tool(description = """
查询指定服务的时间序列指标。
指标名只能是:cpu、memory、qps、error_rate、p99_latency。
时间范围用相对表示,如 30m、2h、1d。
返回采样点摘要(均值、峰值、最新值),不返回全部原始点。
""")
@ToolMeta(name = "queryMetrics", risk = READ_ONLY,
tags = {"ops", "metrics"}, timeout = "10s")
public String queryMetrics(
@ToolParam(description = "服务名,如 order-service")
String service,
@ToolParam(description = "指标名:cpu/memory/qps/error_rate/p99_latency")
String metric,
@ToolParam(description = "时间范围,如 2h、30m、1d")
String range) {
Series s = metrics.query(service, metric, range);
return "服务 %s 的 %s(%s):均值 %.1f,峰值 %.1f,最新 %.1f"
.formatted(service, metric, range, s.avg(), s.max(), s.latest());
}
@Tool(description = """
检索服务日志中包含关键词的条目。
关键词应是具体的错误特征,如 NullPointerException、timeout。
最多返回 10 条,按时间倒序。没有匹配时返回 NOT_FOUND。
""")
@ToolMeta(name = "searchLogs", risk = READ_ONLY,
tags = {"ops", "logs"}, timeout = "15s")
public String searchLogs(
@ToolParam(description = "服务名") String service,
@ToolParam(description = "检索关键词,如具体的异常类名或错误码")
String keyword,
@ToolParam(description = "时间范围,如 30m、2h")
String range) {
List<LogEntry> hits = logs.search(service, keyword, range, 10);
if (hits.isEmpty()) return "NOT_FOUND:未找到包含「%s」的日志".formatted(keyword);
return hits.stream()
.map(e -> "[%s] %s".formatted(e.time(), abbreviate(e.message(), 200)))
.collect(Collectors.joining("\n"));
}
@Tool(description = """
重启指定服务。此操作会造成短暂中断,必须人工审批后执行。
执行前请确认:是否在低峰期、是否有其他处置方案。
""")
@ToolMeta(name = "restartService", risk = NEED_APPROVAL,
tags = {"ops", "action"}, timeout = "60s")
public String restartService(
@ToolParam(description = "服务名") String service) {
return opsApi.restart(service);
}
}5.2 运行配置
yaml
agent:
cases:
ops:
limits: { max-iterations: 12, budget-tokens: 120000, timeout: 240s }
tools: [queryMetrics, searchLogs, listRecentChanges,
queryTopology, queryAlerts, searchRunbook]
approval-required: [restartService, scaleOut]5.3 调用
java
// ch03-agent/src/main/java/com/aitech/agent/caseops/OpsAgentService.java
@Service
public class OpsAgentService {
private final AgentHarness harness;
public Diagnosis diagnose(Alert alert) {
AgentRequest req = AgentRequest.builder()
.goal("""
收到告警:服务 %s,指标 %s 当前值 %s,阈值 %s。
请诊断可能的原因并给出处置建议。
""".formatted(alert.service(), alert.metric(),
alert.value(), alert.threshold()))
.tenant(alert.tenantId())
.tools("ops") // 只挂载运维工具
.limits(props.limits("ops"))
.build();
AgentResult r = harness.run(req);
return Diagnosis.from(r);
}
}只挂载运维工具是 03-03 动态挂载的实践:12 个候选里选 6 个,选择准确率更高。
6. 跑起来
bash
git checkout ch03-14-ops-agent
docker compose up -d
mvn spring-boot:runbash
curl -X POST http://localhost:8080/api/ops/diagnose -d '{
"service":"order-service",
"metric":"p99_latency",
"value":"3200ms",
"threshold":"500ms"
}'期望输出(演示用 mock 数据):
轮次 1 | queryMetrics(order-service, p99_latency, 2h) → 均值 3100ms,峰值 3400ms
轮次 2 | listRecentChanges(order-service, 2h) → 14:32 发布 v2.3.1,改动:订单查询 SQL
轮次 3 | searchLogs(order-service, "slow query", 30m) → 找到 8 条慢查询日志
轮次 4 | searchRunbook("数据库慢查询") → 匹配到《慢查询应急 SOP》
轮次 5 | 给出结论
诊断结论:
现象:订单服务 P99 延迟从 200ms 升至 3.2s
根因推测:14:32 发布的 v2.3.1 引入慢查询(置信度 0.87)
证据:[1] 指标曲线 [2] 变更记录 [3] 慢查询日志 [4] 历史案例
建议:回滚 v2.3.1(需审批)→ 已生成审批单| 检查项 | 通过标准 |
|---|---|
| 多步诊断 | 至少 4 步,每步有工具证据 |
| 结论结构化 | 含现象/根因/置信度/建议 |
| 低置信度处理 | 证据不足时说「需要人工介入」 |
| 高危审批 | 建议重启时生成审批单而非执行 |
| 成本控制 | Token 在预算内 |
7. 生产避坑
- 运维 Agent 必须从只读起步。先做诊断,等准确率被验证、团队建立信任后,再逐步开放处置动作。上来就给写权限,一次误操作就会让整个项目被叫停。
- 必须输出置信度并设阈值。不给置信度的话,低质量结论和高质量结论看起来一样,用户无法判断是否该信。低于阈值明确说「需要人工介入」——这是产品可信度的关键。
- 「有变更就先怀疑变更」这类经验规则要显式写进 prompt。这是 SRE 的老经验,但模型不会自己总结出来。把领域专家的排查顺序编码进系统提示,准确率提升非常明显。
8. 延伸与锚点
- 思考题:运维是「诊断型」,如果是「生成型」任务(比如代码审查)呢?(答案在下一课时)
- 代码锚点:
git checkout ch03-14-ops-agent - 下一课时:03-15 实战案例(二):代码审查 Agent
- 对应课件:L03-14 运维助手