package com.vincent.rsf.server.ai.service.provider; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.vincent.rsf.server.ai.model.AiDiagnosticToolResult; import com.vincent.rsf.server.ai.model.AiPromptContext; import com.vincent.rsf.server.system.entity.AiCallLog; import com.vincent.rsf.server.system.service.AiCallLogService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Service public class AiApiFailureSummaryService implements AiDiagnosticDataProvider { private static final String TOOL_CODE = "ai_call_failure"; private static final String TOOL_NAME = "AI调用失败"; @Resource private AiCallLogService aiCallLogService; @Resource private com.vincent.rsf.server.ai.config.AiProperties aiProperties; /** * 返回 AI 调用失败工具默认顺序。 */ @Override public int getOrder() { return 50; } /** * 返回 AI 调用失败工具编码。 */ @Override public String getToolCode() { return TOOL_CODE; } /** * 返回 AI 调用失败工具展示名。 */ @Override public String getToolName() { return TOOL_NAME; } /** * 返回 AI 调用失败工具默认说明。 */ @Override public String getDefaultToolPrompt() { return "重点识别最近 AI 调用失败的模型、错误类型和时间窗口。"; } /** * 汇总最近一段时间内的 AI 调用失败记录。 */ @Override public AiDiagnosticToolResult buildDiagnosticData(AiPromptContext context) { Date start = new Date(System.currentTimeMillis() - aiProperties.getApiFailureWindowHours() * 3600_000L); List records = aiCallLogService.list(new LambdaQueryWrapper() .eq(AiCallLog::getTenantId, context.getTenantId()) .eq(AiCallLog::getResult, 0) .ge(AiCallLog::getCreateTime, start) .orderByDesc(AiCallLog::getCreateTime) .last("limit 10")); Map meta = new LinkedHashMap<>(); meta.put("count", records.size()); if (records.isEmpty()) { return new AiDiagnosticToolResult() .setToolCode(getToolCode()) .setToolName(getToolName()) .setSeverity("INFO") .setSummaryText("最近 " + aiProperties.getApiFailureWindowHours() + " 小时未发现 AI 调用失败记录。") .setRawMeta(meta); } List parts = new ArrayList<>(); for (AiCallLog item : records) { parts.add((item.getModelCode() == null ? "未知模型" : item.getModelCode()) + "(" + (item.getErr() == null ? "无异常描述" : item.getErr()) + ")"); } meta.put("latestErrors", parts); return new AiDiagnosticToolResult() .setToolCode(getToolCode()) .setToolName(getToolName()) .setSeverity("WARN") .setSummaryText("最近 " + aiProperties.getApiFailureWindowHours() + " 小时发现 " + records.size() + " 条 AI 调用失败记录,最近失败包括:" + String.join(";", parts)) .setRawMeta(meta); } }