16 KiB
16 KiB
/api/ai_ops 核心设计 - Essence 报告
生成日期:2026-05-30
分析透镜:Mechanical(如何工作)
设计模式:3-Agent Collaborative Analysis Pattern
💎 核心洞察
/api/ai_ops 的精华在于 3-Agent 协同分析模式:
- Planner 负责"想"(制定计划 & 重新规划)
- Executor 负责"做"(执行工具调用)
- Supervisor 负责"协调"(循环调度直到完成)
这个模式解决了单 Agent 无法"边执行边调整"的痛点。
🎯 设计分析
问题(Problem)
传统的单 Agent 系统在处理复杂的运维场景时存在以下痛点:
- 规划与执行混杂:一个 Agent 既要制定计划,又要执行工具调用,导致逻辑混乱
- 无法自适应调整:执行失败后无法重新规划,只能从头开始
- 调试困难:无法清晰追踪"哪个环节失败了"
- 输出格式不稳定:Agent 可能在规划阶段就输出最终结果,导致流程短路
具体场景:
AI Ops 告警分析需要:
1. 先查 Prometheus 告警
2. 根据告警查对应的日志
3. 如果日志查询失败 → 重新规划(换个主题或时间范围)
4. 汇总所有数据 → 生成报告
单 Agent 无法处理"步骤 3"的重新规划
代码证据:
AiOpsService.java:144-235- Planner Prompt 明确定义了 Replanner 角色AiOpsService.java:241-257- Executor Prompt 明确只执行"第一步"
模式(Pattern)
核心思想:将复杂任务拆分为 3 个专职 Agent,通过 Supervisor 编排协同工作。
角色分工
| Agent | 职责 | 输入 | 输出 | 关键行为 |
|---|---|---|---|---|
| Planner | 制定计划 & 重新规划 | {input} + {executor_feedback} |
decision (PLAN/EXECUTE/FINISH) + step 描述 |
分析告警 → 制定下一步 |
| Executor | 执行工具调用 | {planner_plan} |
executor_feedback (JSON) |
只执行第一步 → 返回证据 |
| Supervisor | 调度与编排 | taskPrompt |
OverAllState |
Loop 调度 Planner & Executor 直到 FINISH |
协同流程图
┌─────────────────────────────────────────────────────────┐
│ Supervisor │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Loop: │ │
│ │ │ │
│ │ ┌─────────────────┐ │ │
│ │ │ Planner Agent │ │ │
│ │ │ │ │ │
│ │ │ Input: │ │ │
│ │ │ - task │ │ │
│ │ │ - feedback │◄────────┐ │ │
│ │ │ │ │ │ │
│ │ │ Output: │ │ │ │
│ │ │ decision │ │ │ │
│ │ │ step │ │ │ │
│ │ └─────────────────┘ │ │ │
│ │ │ │ │ │
│ │ ├── PLAN ──────────► (记录) │ │
│ │ │ │ │ │
│ │ ├── EXECUTE ───┐ │ │ │
│ │ │ │ │ │ │
│ │ │ ▼ │ │ │
│ │ │ ┌─────────────────┐ │ │
│ │ │ │ Executor Agent │ │ │
│ │ │ │ │ │ │
│ │ │ │ Input: │ │ │
│ │ │ │ - planner_plan │ │ │
│ │ │ │ │ │ │
│ │ │ │ Output: │ │ │
│ │ │ │ - feedback │───────────────┘ │
│ │ │ │ - evidence │ │
│ │ │ └─────────────────┘ │
│ │ │ │ │
│ │ │ ▼ │
│ │ │ 调用 Tools: │
│ │ │ - QueryMetricsTools │
│ │ │ - QueryLogsTools │
│ │ │ - InternalDocsTools │
│ │ │ │
│ │ └── FINISH ───► 输出 Markdown 报告 │
│ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
🔗 完整调用链
HTTP → Service → Agents → Tools → SSE
用户点击 "AI Ops" 按钮
↓
HTTP POST /api/ai_ops (ChatController.java:280)
↓
ChatController.aiOps()
- 创建 SseEmitter (10 分钟超时)
- 异步执行任务
↓
AiOpsService.executeAiOpsAnalysis(chatModel, toolCallbacks) (Line 51)
↓
┌────────────────────────────────────────────────────────────┐
│ Step 1: 构建 3 个 Agent │
│ │
│ ① plannerAgent = buildPlannerAgent() (Line 100-109) │
│ - name: "planner_agent" │
│ - description: "负责拆解告警、规划与再规划步骤" │
│ - systemPrompt: buildPlannerPrompt() (Line 144-235) │
│ - outputKey: "planner_plan" │
│ │
│ ② executorAgent = buildExecutorAgent() (Line 115-124) │
│ - name: "executor_agent" │
│ - description: "负责执行 Planner 的首个步骤并反馈" │
│ - systemPrompt: buildExecutorPrompt() (Line 241-257) │
│ - outputKey: "executor_feedback" │
│ │
│ ③ supervisorAgent = SupervisorAgent.builder() (Line 59-65)│
│ - name: "ai_ops_supervisor" │
│ - systemPrompt: buildSupervisorSystemPrompt() │
│ - subAgents: [plannerAgent, executorAgent] │
└────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────┐
│ Step 2: Supervisor 编排执行 (Line 70) │
│ │
│ supervisorAgent.invoke(taskPrompt) │
│ │
│ 编排逻辑(内置于 SupervisorAgent): │
│ ┌──────────────────────────────────────────┐ │
│ │ Loop until decision == FINISH: │ │
│ │ │ │
│ │ 1. 调用 planner_agent │ │
│ │ → 输出 decision: PLAN/EXECUTE/FINISH │ │
│ │ │ │
│ │ 2. if decision == EXECUTE: │ │
│ │ 调用 executor_agent │ │
│ │ → 执行第一步工具调用 │ │
│ │ → 返回 executor_feedback │ │
│ │ │ │
│ │ 3. 将 executor_feedback 传回 planner │ │
│ │ → planner 重新规划 (Replanner 角色) │ │
│ │ │ │
│ │ 4. if decision == FINISH: │ │
│ │ planner 输出最终 Markdown 报告 │ │
│ │ → break │ │
│ └──────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────┐
│ Step 3: 工具调用(在 Executor 阶段) │
│ │
│ Executor Agent 根据 Planner 的计划调用工具: │
│ │
│ ① QueryMetricsTools.queryPrometheusAlerts() │
│ → 查询 Prometheus 活跃告警 │
│ → Mock 模式返回模拟数据(HighCPUUsage, etc.) │
│ │
│ ② QueryLogsTools.queryLogs(告警名称, 日志主题) │
│ → 查询腾讯云 CLS 日志 │
│ → Mock 模式返回与告警关联的模拟日志 │
│ │
│ ③ InternalDocsTools.queryInternalDocs(关键字) │
│ → RAG 知识库检索 │
│ → 从 Milvus 检索相关文档 │
│ │
│ ④ DateTimeTools.getCurrentDateTime() │
│ → 获取当前时间(用于计算告警持续时间) │
└────────────────────────────────────────────────────────────┘
↓
AiOpsService.extractFinalReport(state) (Line 79-94)
- 从 state.value("planner_plan") 提取 Planner 最终输出
- 返回 Markdown 格式的告警分析报告
↓
ChatController 通过 SSE 流式返回前端 (Line 312-314)
- event: message
- data: {"type":"content","data":"# 告警分析报告\n..."}
↓
前端渲染 Markdown
📊 替代方案对比
| 方案 | 优点 | 缺点 | 为什么不选 |
|---|---|---|---|
| 单 Agent | 简单,易维护 | 无法重新规划,调试困难 | 无法处理"执行失败后重新规划"的场景 |
| 2-Agent (Planner + Executor) | 角色清晰 | 需要外部循环逻辑,状态管理复杂 | 缺少 Supervisor 统一调度,状态传递困难 |
| 静态工作流(DAG) | 确定性强 | 无法动态调整 | 告警场景不确定,无法提前定义 DAG |
| ReAct Loop (单 Agent 循环) | 通用性强 | 规划与执行混杂,输出格式不稳定 | 无法保证"先规划后执行"的顺序 |
⚖️ 权衡分析
为什么选择 3-Agent 协同?
| 维度 | 收益 | 代价 |
|---|---|---|
| 职责清晰 | ✅ 每个 Agent 只做一件事,易于调试 | ❌ 多一个 Supervisor,代码量增加 |
| 自适应能力 | ✅ Executor 失败后,Planner 可以重新规划 | ❌ 需要设计 feedback 传递机制 |
| 输出稳定性 | ✅ Supervisor 保证"只有 FINISH 才输出报告" | ❌ 需要在 Prompt 中明确约束 |
| 可扩展性 | ✅ 可以轻松添加新的 Agent(如 Reviewer) | ❌ Supervisor 逻辑会变复杂 |
📦 迁移示例(≤20 行)
// 1. 定义 3 个 Agent
ReactAgent planner = ReactAgent.builder()
.name("planner")
.systemPrompt("制定计划,输出 decision: PLAN/EXECUTE/FINISH")
.outputKey("plan")
.build();
ReactAgent executor = ReactAgent.builder()
.name("executor")
.systemPrompt("执行计划的第一步,返回 feedback")
.outputKey("feedback")
.tools(yourTools) // 注入工具
.build();
SupervisorAgent supervisor = SupervisorAgent.builder()
.name("supervisor")
.systemPrompt("循环调度 planner 和 executor 直到 FINISH")
.subAgents(List.of(planner, executor))
.build();
// 2. 启动编排
OverAllState result = supervisor.invoke("分析这个问题...");
⚠️ 关键陷阱
| 陷阱 | 后果 | 避免方法 |
|---|---|---|
| Prompt 未明确"只执行第一步" | Executor 会执行所有步骤,Planner 无法插手 | 在 Executor Prompt 中强调"只执行其中的第一步" |
| 未设置 outputKey | 状态无法传递,Planner 无法读取 feedback | 每个 Agent 必须设置 outputKey |
| Planner 在 EXECUTE 阶段输出最终报告 | 流程短路,Supervisor 无法控制 | Prompt 中明确"FINISH 时才输出 Markdown" |
| Supervisor Prompt 缺失循环逻辑 | 只执行一轮就结束 | Supervisor Prompt 必须说明"直到 decision=FINISH" |
| 工具调用失败未反馈给 Planner | Planner 无法重新规划,陷入死循环 | Executor 必须在 feedback 中记录失败原因 |
代码证据:
AiOpsService.java:228-233- 防止 Planner 提前输出报告的约束AiOpsService.java:245-246- Executor 对工具失败的处理机制
📁 核心文件索引
| 文件 | 关键行 | 作用 |
|---|---|---|
ChatController.java |
280-314 | HTTP 入口 + SSE 流式返回 |
AiOpsService.java |
51-70 | 3-Agent 构建与编排 |
AiOpsService.java |
100-109 | Planner Agent 构建 |
AiOpsService.java |
115-124 | Executor Agent 构建 |
AiOpsService.java |
144-235 | Planner Prompt(含 Replanner 逻辑) |
AiOpsService.java |
241-257 | Executor Prompt(只执行第一步) |
AiOpsService.java |
263-277 | Supervisor Prompt(循环调度) |
AiOpsService.java |
79-94 | 最终报告提取逻辑 |
🎓 学习检查点
完成本报告后,你应该能回答:
- 为什么用 3 个 Agent 而不是 1 个?
- Planner 的 Replanner 角色是什么意思?
- Executor 为什么只执行"第一步"?
- Supervisor 如何知道该调用哪个 Agent?
- 如果 Executor 执行失败会发生什么?
- outputKey 的作用是什么?
- 如何从 state 中提取最终报告?
💡 延伸阅读: