Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
public record PromptConfigDTO(String id, // 配置ID(更新时需要)
String name, // 配置名称
String promptType, // 提示词类型
String systemPrompt, // 用户自定义的系统提示词内容
String optimizationPrompt, // 用户添加的优化提示词内容
Boolean enabled, // 是否启用该配置
String description, // 配置描述
String creator // 创建者
) {
public PromptConfigDTO(String promptType, String systemPrompt) {
this(null, null, promptType, systemPrompt, true, null, null);
public PromptConfigDTO(String promptType, String optimizationPrompt) {
this(null, null, promptType, optimizationPrompt, true, null, null);
}

@Override
Expand Down Expand Up @@ -61,8 +61,8 @@ public String promptType() {
}

@Override
public String systemPrompt() {
return systemPrompt;
public String optimizationPrompt() {
return optimizationPrompt;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.time.LocalDateTime;

/**
* 用户自定义提示词配置实体类
* 用户提示词优化配置实体类
*
* @author Makoto
*/
Expand All @@ -46,7 +46,7 @@ public class UserPromptConfig {
private String promptType;

/**
* 用户自定义的系统提示词内容
* 用户添加的优化提示词内容(附加到原始模板)
*/
@TableField("system_prompt")
private String systemPrompt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.alibaba.cloud.ai.node;

import com.alibaba.cloud.ai.entity.UserPromptConfig;
import com.alibaba.cloud.ai.enums.StreamResponseType;
import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.action.NodeAction;
Expand Down Expand Up @@ -136,14 +137,15 @@ private Flux<ChatResponse> generateReport(String userInput, Plan plan, HashMap<S
// Build analysis steps and data results description
String analysisStepsAndData = buildAnalysisStepsAndData(plan, executionResults);

// Get custom prompt content if available
String customPrompt = promptConfigService.getCustomPromptContent("report-generator");
// Get optimization configs if available
List<UserPromptConfig> optimizationConfigs = promptConfigService.getOptimizationConfigs("report-generator");

// Use PromptHelper to build report generation prompt with custom prompt support
String reportPrompt = PromptHelper.buildReportGeneratorPromptWithCustom(userRequirementsAndPlan,
analysisStepsAndData, summaryAndRecommendations, customPrompt);
// Use PromptHelper to build report generation prompt with optimization support
String reportPrompt = PromptHelper.buildReportGeneratorPromptWithOptimization(userRequirementsAndPlan,
analysisStepsAndData, summaryAndRecommendations, optimizationConfigs);

logger.info("Using {} prompt for report generation", customPrompt != null ? "custom" : "default");
logger.info("Using {} prompt for report generation",
!optimizationConfigs.isEmpty() ? "optimized (" + optimizationConfigs.size() + " configs)" : "default");

return chatClient.prompt().user(reportPrompt).stream().chatResponse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,28 +228,28 @@ public static String buildSemanticConsistenPrompt(String nlReq, String sql) {
}

/**
* 构建带自定义提示词的报告生成提示词
* 构建带优化提示词的报告生成提示词
* @param userRequirementsAndPlan 用户需求和计划
* @param analysisStepsAndData 分析步骤和数据
* @param summaryAndRecommendations 总结和建议
* @param customPrompt 用户自定义的提示词内容,如果为null则使用默认提示词
* @param optimizationConfigs 用户配置的优化提示词列表
* @return 构建的提示词
*/
public static String buildReportGeneratorPromptWithCustom(String userRequirementsAndPlan,
String analysisStepsAndData, String summaryAndRecommendations, String customPrompt) {
public static String buildReportGeneratorPromptWithOptimization(String userRequirementsAndPlan,
String analysisStepsAndData, String summaryAndRecommendations,
List<com.alibaba.cloud.ai.entity.UserPromptConfig> optimizationConfigs) {

Map<String, Object> params = new HashMap<>();
params.put("user_requirements_and_plan", userRequirementsAndPlan);
params.put("analysis_steps_and_data", analysisStepsAndData);
params.put("summary_and_recommendations", summaryAndRecommendations);

if (customPrompt != null && !customPrompt.trim().isEmpty()) {
// 使用自定义提示词
return new org.springframework.ai.chat.prompt.PromptTemplate(customPrompt).render(params);
}
else {
// 使用默认提示词
return PromptConstant.getReportGeneratorPromptTemplate().render(params);
}
// 构建优化部分内容
String optimizationSection = buildOptimizationSection(optimizationConfigs, params);
params.put("optimization_section", optimizationSection);

// 渲染完整模板
return PromptConstant.getReportGeneratorPromptTemplate().render(params);
}

public static String buildSqlErrorFixerPrompt(String question, DbConfig dbConfig, SchemaDTO schemaDTO,
Expand Down Expand Up @@ -285,4 +285,49 @@ public static String buildSemanticModelPrompt(List<SemanticModelDTO> semanticMod
return PromptConstant.getSemanticModelPromptTemplate().render(params);
}

/**
* 构建优化提示词部分内容
* @param optimizationConfigs 优化配置列表
* @param params 模板参数
* @return 优化部分的内容
*/
private static String buildOptimizationSection(
List<com.alibaba.cloud.ai.entity.UserPromptConfig> optimizationConfigs, Map<String, Object> params) {

if (optimizationConfigs == null || optimizationConfigs.isEmpty()) {
return "";
}

StringBuilder result = new StringBuilder();
result.append("## 优化要求\n");

for (com.alibaba.cloud.ai.entity.UserPromptConfig config : optimizationConfigs) {
String optimizationContent = renderOptimizationPrompt(config.getOptimizationPrompt(), params);
if (!optimizationContent.trim().isEmpty()) {
result.append("- ").append(optimizationContent).append("\n");
}
}

return result.toString().trim();
}

/**
* 渲染优化提示词模板
* @param optimizationPrompt 优化提示词模板
* @param params 参数
* @return 渲染后的内容
*/
private static String renderOptimizationPrompt(String optimizationPrompt, Map<String, Object> params) {
if (optimizationPrompt == null || optimizationPrompt.trim().isEmpty()) {
return "";
}
try {
return new org.springframework.ai.chat.prompt.PromptTemplate(optimizationPrompt).render(params);
}
catch (Exception e) {
// 如果模板渲染失败,直接返回原始内容
return optimizationPrompt;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* 用户提示词配置管理服务 提供提示词配置的增删改查功能,支持运行时配置更新
* 用户提示词优化配置管理服务 提供提示词优化配置的增删改查功能,支持多个优化配置同时生效
*
* @author Makoto
*/
Expand All @@ -41,12 +43,22 @@ public class UserPromptConfigService {
private UserPromptConfigMapper userPromptConfigMapper;

/**
* 创建或更新提示词配置
* 内存存储,用于缓存配置(可选的性能优化)
*/
private final Map<String, UserPromptConfig> configStorage = new ConcurrentHashMap<>();

/**
* 根据提示词类型存储启用的配置ID列表(支持多个配置同时启用)
*/
private final Map<String, List<String>> promptTypeToConfigIds = new ConcurrentHashMap<>();

/**
* 创建或更新提示词优化配置
* @param configDTO 配置数据传输对象
* @return 保存后的配置对象
*/
public UserPromptConfig saveOrUpdateConfig(PromptConfigDTO configDTO) {
logger.info("保存或更新提示词配置:{}", configDTO);
logger.info("保存或更新提示词优化配置:{}", configDTO);

UserPromptConfig config;
if (configDTO.id() != null) {
Expand Down Expand Up @@ -84,6 +96,12 @@ public UserPromptConfig saveOrUpdateConfig(PromptConfigDTO configDTO) {
userPromptConfigMapper.insert(config);
}

// 更新缓存
configStorage.put(config.getId(), config);

// 更新类型映射(支持多个配置)
updatePromptTypeMapping(config);

// 如果配置启用,禁用同类型的其他配置
if (Boolean.TRUE.equals(config.getEnabled())) {
userPromptConfigMapper.disableAllByPromptType(config.getPromptType());
Expand All @@ -104,12 +122,39 @@ public UserPromptConfig getConfigById(String id) {
}

/**
* 根据提示词类型获取启用的配置
* 根据提示词类型获取所有启用的配置
* @param promptType 提示词类型
* @return 配置列表
*/
public List<UserPromptConfig> getActiveConfigsByType(String promptType) {
List<String> configIds = promptTypeToConfigIds.get(promptType);
if (configIds == null || configIds.isEmpty()) {
return new ArrayList<>();
}

return configIds.stream()
.map(configStorage::get)
.filter(Objects::nonNull)
.filter(config -> Boolean.TRUE.equals(config.getEnabled()))
.sorted(Comparator.comparing(UserPromptConfig::getUpdateTime).reversed())
.toList();
}

/**
* 根据提示词类型获取启用的配置(兼容旧接口)
* @param promptType 提示词类型
* @return 配置对象,不存在时返回null
*/
public UserPromptConfig getActiveConfigByType(String promptType) {
return userPromptConfigMapper.selectActiveByPromptType(promptType);
// 优先从数据库获取
UserPromptConfig dbConfig = userPromptConfigMapper.selectActiveByPromptType(promptType);
if (dbConfig != null) {
return dbConfig;
}

// 备用:从内存缓存获取
List<UserPromptConfig> configs = getActiveConfigsByType(promptType);
return configs.isEmpty() ? null : configs.get(0);
}

/**
Expand Down Expand Up @@ -138,8 +183,12 @@ public List<UserPromptConfig> getConfigsByType(String promptType) {
public boolean deleteConfig(String id) {
UserPromptConfig config = userPromptConfigMapper.selectById(id);
if (config != null) {
// 从数据库删除
int deleted = userPromptConfigMapper.deleteById(id);
if (deleted > 0) {
// 从内存缓存和类型映射中移除该配置
configStorage.remove(id);
removeFromPromptTypeMapping(config);
logger.info("已删除配置:{}", id);
return true;
}
Expand All @@ -161,6 +210,10 @@ public boolean enableConfig(String id) {
// 启用当前配置
int updated = userPromptConfigMapper.enableById(id);
if (updated > 0) {
// 更新内存缓存
config.setEnabled(true);
configStorage.put(id, config);
updatePromptTypeMapping(config);
logger.info("已启用配置:{}", id);
return true;
}
Expand All @@ -176,30 +229,71 @@ public boolean enableConfig(String id) {
public boolean disableConfig(String id) {
int updated = userPromptConfigMapper.disableById(id);
if (updated > 0) {
// 更新内存缓存
UserPromptConfig config = configStorage.get(id);
if (config != null) {
config.setEnabled(false);
removeFromPromptTypeMapping(config);
}
logger.info("已禁用配置:{}", id);
return true;
}
return false;
}

/**
* 禁用指定类型的所有配置
* 更新提示词类型映射
* @param config 配置对象
*/
private void updatePromptTypeMapping(UserPromptConfig config) {
if (Boolean.TRUE.equals(config.getEnabled())) {
promptTypeToConfigIds.computeIfAbsent(config.getPromptType(), k -> new ArrayList<>());
List<String> configIds = promptTypeToConfigIds.get(config.getPromptType());
if (!configIds.contains(config.getId())) {
configIds.add(config.getId());
logger.info("已将配置 {} 添加到提示词类型 [{}] 的映射中", config.getId(), config.getPromptType());
}
}
else {
removeFromPromptTypeMapping(config);
}
}

/**
* 从提示词类型映射中移除配置
* @param config 配置对象
*/
private void removeFromPromptTypeMapping(UserPromptConfig config) {
List<String> configIds = promptTypeToConfigIds.get(config.getPromptType());
if (configIds != null) {
configIds.remove(config.getId());
if (configIds.isEmpty()) {
promptTypeToConfigIds.remove(config.getPromptType());
}
logger.info("已从提示词类型 [{}] 的映射中移除配置 {}", config.getPromptType(), config.getId());
}
}

/**
* 获取优化提示词内容列表
* @param promptType 提示词类型
* @return 优化提示词内容列表
*/
public void disableConfigsByType(String promptType) {
userPromptConfigMapper.disableAllByPromptType(promptType);
public List<UserPromptConfig> getOptimizationConfigs(String promptType) {
return getActiveConfigsByType(promptType);
}

/**
* 获取自定义提示词内容,如果没有自定义配置则返回null
* 获取自定义提示词内容,如果没有自定义配置则返回null(兼容旧接口)
* @param promptType 提示词类型
* @return 自定义提示词内容
*/
public String getCustomPromptContent(String promptType) {
// TODO 需要优化,提示词不能完全替代现有的,仅用作补充使用
List<UserPromptConfig> configs = getActiveConfigsByType(promptType);
if (!configs.isEmpty()) {
return configs.get(0).getSystemPrompt();
}
return null;
// UserPromptConfig config = getActiveConfigByType(promptType);
// return config != null ? config.getSystemPrompt() : null;
}

/**
Expand All @@ -208,7 +302,7 @@ public String getCustomPromptContent(String promptType) {
* @return 是否有自定义配置
*/
public boolean hasCustomConfig(String promptType) {
return getActiveConfigByType(promptType) != null;
return !getActiveConfigsByType(promptType).isEmpty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@
## 总结建议要求
{summary_and_recommendations}

{optimization_section}

请根据以上信息生成一份专业、全面的数据分析报告。
Loading
Loading