## 主要改动
1. Prompt 配置化
- 从硬编码改为独立 Markdown 文件管理
- 新增 AiOpsPromptProperties 配置类,使用 @PostConstruct 加载
- 创建 prompts/{planner,executor,supervisor}-prompt.md
2. 集成 LookupKnowledgeTool
- 在 AiOpsService 中注入 LookupKnowledgeTool
- 添加到工具数组,只给 Executor Agent 使用
- 符合 3-Agent 协同分析模式
3. Executor Prompt 增强
- 添加工具选择指南(精确关键词 vs 模糊概念)
- 明确降级策略(lookup_knowledge 未找到时降级到 queryInternalDocs)
## 优势
- 易于维护:Prompt 修改不需重新编译
- 格式友好:Markdown 原生支持代码块和表格
- 性能优化:精确关键词查询 < 10ms(L0 匹配)
## 文件变更
- 新增:AiOpsPromptProperties.java
- 新增:prompts/planner-prompt.md
- 新增:prompts/executor-prompt.md
- 新增:prompts/supervisor-prompt.md
- 修改:AiOpsService.java(-136 行硬编码,+5 行配置引用)
160 lines
6.1 KiB
Java
160 lines
6.1 KiB
Java
package com.superbiz.agent.service;
|
|
|
|
import org.springframework.ai.chat.model.ChatModel;
|
|
import com.alibaba.cloud.ai.graph.OverAllState;
|
|
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
|
|
import com.alibaba.cloud.ai.graph.agent.flow.agent.SupervisorAgent;
|
|
import com.alibaba.cloud.ai.graph.exception.GraphRunnerException;
|
|
import com.superbiz.agent.agent.tool.DateTimeTools;
|
|
import com.superbiz.agent.agent.tool.InternalDocsTools;
|
|
import com.superbiz.agent.agent.tool.QueryLogsTools;
|
|
import com.superbiz.agent.agent.tool.QueryMetricsTools;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.ai.chat.messages.AssistantMessage;
|
|
import org.springframework.ai.tool.ToolCallback;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import com.superbiz.agent.config.AiOpsPromptProperties;
|
|
import com.superbiz.agent.tool.LookupKnowledgeTool;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* AI Ops 智能运维服务
|
|
* 负责多 Agent 协作的告警分析流程
|
|
*/
|
|
@Service
|
|
public class AiOpsService {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(AiOpsService.class);
|
|
|
|
@Autowired
|
|
private DateTimeTools dateTimeTools;
|
|
|
|
@Autowired
|
|
private InternalDocsTools internalDocsTools;
|
|
|
|
@Autowired
|
|
private QueryMetricsTools queryMetricsTools;
|
|
|
|
@Autowired(required = false) // Mock 模式下才注册
|
|
private QueryLogsTools queryLogsTools;
|
|
|
|
@Autowired
|
|
private LookupKnowledgeTool lookupKnowledgeTool;
|
|
|
|
@Autowired
|
|
private AiOpsPromptProperties promptProperties;
|
|
|
|
/**
|
|
* 执行 AI Ops 告警分析流程
|
|
*
|
|
* @param chatModel 大模型实例
|
|
* @param toolCallbacks 工具回调数组
|
|
* @return 分析结果状态
|
|
* @throws GraphRunnerException 如果 Agent 执行失败
|
|
*/
|
|
public Optional<OverAllState> executeAiOpsAnalysis(ChatModel chatModel, ToolCallback[] toolCallbacks) throws GraphRunnerException {
|
|
logger.info("开始执行 AI Ops 多 Agent 协作流程");
|
|
|
|
// 构建 Planner 和 Executor Agent
|
|
ReactAgent plannerAgent = buildPlannerAgent(chatModel, toolCallbacks);
|
|
ReactAgent executorAgent = buildExecutorAgent(chatModel, toolCallbacks);
|
|
|
|
// 构建 Supervisor Agent
|
|
SupervisorAgent supervisorAgent = SupervisorAgent.builder()
|
|
.name("ai_ops_supervisor")
|
|
.description("负责调度 Planner 与 Executor 的多 Agent 控制器")
|
|
.model(chatModel)
|
|
.systemPrompt(promptProperties.getSupervisor())
|
|
.subAgents(List.of(plannerAgent, executorAgent))
|
|
.build();
|
|
|
|
String taskPrompt = "你是企业级 SRE,接到了自动化告警排查任务。请结合工具调用,执行**规划→执行→再规划**的闭环,并最终按照固定模板输出《告警分析报告》。禁止编造虚假数据,如连续多次查询失败需诚实反馈无法完成的原因。";
|
|
|
|
logger.info("调用 Supervisor Agent 开始编排...");
|
|
|
|
Optional<OverAllState> stateOptional = supervisorAgent.invoke(taskPrompt);
|
|
|
|
// 添加调试代码
|
|
if (stateOptional.isPresent()) {
|
|
OverAllState state = stateOptional.get();
|
|
logger.debug("Final State Keys: {}", state.data().keySet()); // 打印所有 key
|
|
logger.debug("Planner Plan: {}", state.value("planner_plan"));
|
|
logger.debug("Executor Feedback: {}", state.value("executor_feedback"));
|
|
}
|
|
|
|
return stateOptional;
|
|
}
|
|
|
|
/**
|
|
* 从执行结果中提取最终报告文本
|
|
*
|
|
* @param state 执行状态
|
|
* @return 报告文本(如果存在)
|
|
*/
|
|
public Optional<String> extractFinalReport(OverAllState state) {
|
|
logger.info("开始提取最终报告...");
|
|
|
|
// 提取 Planner 最终输出(包含完整的告警分析报告)
|
|
Optional<AssistantMessage> plannerFinalOutput = state.value("planner_plan")
|
|
.filter(AssistantMessage.class::isInstance)
|
|
.map(AssistantMessage.class::cast);
|
|
|
|
if (plannerFinalOutput.isPresent()) {
|
|
String reportText = plannerFinalOutput.get().getText();
|
|
logger.info("成功提取到 Planner 最终报告,长度: {}", reportText.length());
|
|
return Optional.of(reportText);
|
|
} else {
|
|
logger.warn("未能提取到 Planner 最终报告");
|
|
return Optional.empty();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 构建 Planner Agent
|
|
*/
|
|
private ReactAgent buildPlannerAgent(ChatModel chatModel, ToolCallback[] toolCallbacks) {
|
|
return ReactAgent.builder()
|
|
.name("planner_agent")
|
|
.description("负责拆解告警、规划与再规划步骤")
|
|
.model(chatModel)
|
|
.systemPrompt(promptProperties.getPlanner())
|
|
.methodTools(buildMethodToolsArray())
|
|
.tools(toolCallbacks)
|
|
.outputKey("planner_plan")
|
|
.build();
|
|
}
|
|
|
|
/**
|
|
* 构建 Executor Agent
|
|
*/
|
|
private ReactAgent buildExecutorAgent(ChatModel chatModel, ToolCallback[] toolCallbacks) {
|
|
return ReactAgent.builder()
|
|
.name("executor_agent")
|
|
.description("负责执行 Planner 的首个步骤并及时反馈")
|
|
.model(chatModel)
|
|
.systemPrompt(promptProperties.getExecutor())
|
|
.methodTools(buildMethodToolsArray())
|
|
.tools(toolCallbacks)
|
|
.outputKey("executor_feedback")
|
|
.build();
|
|
}
|
|
|
|
/**
|
|
* 动态构建方法工具数组
|
|
* 根据 cls.mock-enabled 决定是否包含 QueryLogsTools
|
|
*/
|
|
private Object[] buildMethodToolsArray() {
|
|
if (queryLogsTools != null) {
|
|
// Mock 模式:包含 QueryLogsTools
|
|
return new Object[]{dateTimeTools, internalDocsTools, queryMetricsTools, queryLogsTools, lookupKnowledgeTool};
|
|
} else {
|
|
// 真实模式:不包含 QueryLogsTools(由 MCP 提供日志查询功能)
|
|
return new Object[]{dateTimeTools, internalDocsTools, queryMetricsTools, lookupKnowledgeTool};
|
|
}
|
|
}
|
|
}
|