package com.vincent.rsf.server.ai.service; import com.vincent.rsf.server.ai.config.AiProperties; import com.vincent.rsf.server.ai.constant.AiSceneCode; import com.vincent.rsf.server.ai.model.AiDiagnosticToolResult; import com.vincent.rsf.server.ai.model.AiPromptContext; import com.vincent.rsf.server.ai.service.diagnosis.AiDiagnosticToolService; import com.vincent.rsf.server.system.entity.AiPromptTemplate; import com.vincent.rsf.server.system.service.AiPromptTemplateService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @Service public class AiPromptRuntimeService { @Resource private AiProperties aiProperties; @Resource private AiPromptContextService aiPromptContextService; @Resource private AiPromptTemplateService aiPromptTemplateService; @Resource private AiDiagnosticToolService aiDiagnosticToolService; /** * 构造指定场景的系统 Prompt。 * 当未显式传入诊断工具结果时,诊断场景会在内部主动收集一次工具摘要。 */ public String buildSystemPrompt(String sceneCode, String fallbackBasePrompt, AiPromptContext context) { return buildSystemPrompt(sceneCode, fallbackBasePrompt, context, null); } /** * 构造最终系统 Prompt,按“已发布模板/默认模板 + 上下文 + 工具摘要”的顺序拼装。 */ public String buildSystemPrompt(String sceneCode, String fallbackBasePrompt, AiPromptContext context, List diagnosticResults) { String basePrompt = resolveBasePrompt(sceneCode, fallbackBasePrompt, context.getTenantId()); List results = diagnosticResults; if (results == null && AiSceneCode.SYSTEM_DIAGNOSE.equals(sceneCode)) { results = aiDiagnosticToolService.collect(context); } if (results != null && !results.isEmpty()) { List parts = new ArrayList<>(); String contextPrompt = aiPromptContextService.buildSystemPrompt(basePrompt, context); if (contextPrompt != null && !contextPrompt.trim().isEmpty()) { parts.add(contextPrompt.trim()); } String diagnosticPrompt = aiDiagnosticToolService.buildPrompt(context.getTenantId(), sceneCode, results); if (!diagnosticPrompt.trim().isEmpty()) { parts.add(diagnosticPrompt); } return String.join("\n\n", parts); } return aiPromptContextService.buildSystemPrompt(basePrompt, context); } /** * 解析当前场景的基础 Prompt。 * 优先使用已发布的 Prompt 模板;若模板不存在或为空,则回退到配置文件中的默认提示词。 */ private String resolveBasePrompt(String sceneCode, String fallbackBasePrompt, Long tenantId) { AiPromptTemplate publishedTemplate = aiPromptTemplateService.getPublishedTemplate(tenantId, sceneCode); if (publishedTemplate == null) { return aiProperties.buildScenePrompt(sceneCode, fallbackBasePrompt); } List parts = new ArrayList<>(); if (publishedTemplate.getBasePrompt() != null && !publishedTemplate.getBasePrompt().trim().isEmpty()) { parts.add(publishedTemplate.getBasePrompt().trim()); } if (publishedTemplate.getToolPrompt() != null && !publishedTemplate.getToolPrompt().trim().isEmpty()) { parts.add(publishedTemplate.getToolPrompt().trim()); } if (publishedTemplate.getOutputPrompt() != null && !publishedTemplate.getOutputPrompt().trim().isEmpty()) { parts.add(publishedTemplate.getOutputPrompt().trim()); } if (parts.isEmpty()) { return aiProperties.buildScenePrompt(sceneCode, fallbackBasePrompt); } return String.join("\n\n", parts); } }