Files
SuperBizAgent-java/docs/learning/01-AI-Ops-核心设计-Essence报告.md
T
2026-05-31 21:45:14 +08:00

310 lines
16 KiB
Markdown
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.
# /api/ai_ops 核心设计 - Essence 报告
> 生成日期:2026-05-30
> 分析透镜:Mechanical(如何工作)
> 设计模式:3-Agent Collaborative Analysis Pattern
---
## 💎 核心洞察
`/api/ai_ops` 的精华在于 **3-Agent 协同分析模式**:
1. **Planner** 负责"想"(制定计划 & 重新规划)
2. **Executor** 负责"做"(执行工具调用)
3. **Supervisor** 负责"协调"(循环调度直到完成)
这个模式解决了单 Agent 无法"边执行边调整"的痛点。
---
## 🎯 设计分析
### 问题(Problem)
传统的单 Agent 系统在处理复杂的运维场景时存在以下痛点:
1. **规划与执行混杂**:一个 Agent 既要制定计划,又要执行工具调用,导致逻辑混乱
2. **无法自适应调整**:执行失败后无法重新规划,只能从头开始
3. **调试困难**:无法清晰追踪"哪个环节失败了"
4. **输出格式不稳定**: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 行)
```java
// 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 中提取最终报告?
---
> 💡 **延伸阅读**:
> - [outputKey 深度解析](./02-outputKey-深度解析.md)
> - [3个核心疑问解答](./03-核心疑问解答.md)