AI接口支持流式调用

This commit is contained in:
2025-10-30 15:59:48 +08:00
parent 9ddc6887ff
commit 093d07ab76
2 changed files with 596 additions and 153 deletions
@@ -13,6 +13,8 @@ import com.emotion.service.ConversationService;
import com.emotion.service.CozeApiCallService;
import com.emotion.service.EmotionRecordService;
import com.emotion.service.EmotionAnalysisService;
import com.emotion.service.AiConfigService;
import com.emotion.entity.AiConfig;
import com.emotion.dto.request.*;
import com.emotion.dto.response.*;
import com.emotion.util.SnowflakeIdGenerator;
@@ -41,6 +43,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* AI聊天服务实现类
@@ -73,37 +76,15 @@ public class AiChatServiceImpl implements AiChatService {
@Autowired
private SnowflakeIdGenerator snowflakeIdGenerator;
@Value("${emotion.coze.api.token:}")
private String cozeApiToken;
@Value("${emotion.coze.api.base-url:https://api.coze.cn}")
private String cozeBaseUrl;
@Value("${emotion.coze.api.chat.path:/v3/chat}")
private String chatPath;
@Value("${emotion.coze.api.chat.talk.bot-id:}")
private String chatBotId;
@Value("${emotion.coze.api.chat.talk.workflow-id:}")
private String chatWorkflowId;
@Value("${emotion.coze.api.chat.summary.bot-id:}")
private String summaryBotId;
@Value("${emotion.coze.api.chat.summary.workflow-id:}")
private String summaryWorkflowId;
@Value("${emotion.coze.api.timeout:30000}")
private int timeout;
@Value("${emotion.coze.api.retry-count:3}")
private int retryCount;
@Value("${emotion.coze.api.retry-delay:1000}")
private int retryDelay;
@Autowired
private AiConfigService aiConfigService;
private static final String DEFAULT_USER_ID = "emotion-museum-user";
// 使用场景常量
private static final String USAGE_SCENARIO_CHAT = "chat";
private static final String USAGE_SCENARIO_SUMMARY = "summary";
private static final String DEFAULT_ENVIRONMENT = "production";
// API 相关常量
private static final String CONTENT_KEY = "content";
@@ -494,13 +475,20 @@ public class AiChatServiceImpl implements AiChatService {
@Override
public boolean healthCheck() {
try {
// 简化健康检查 - 检查必要配置是否存在
boolean configValid = cozeApiToken != null && !cozeApiToken.trim().isEmpty() &&
chatBotId != null && !chatBotId.trim().isEmpty() &&
cozeBaseUrl != null && !cozeBaseUrl.trim().isEmpty();
// 检查聊天场景的AI配置是否存在
AiConfig chatConfig = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
if (chatConfig == null) {
log.warn("未找到聊天场景的AI配置");
return false;
}
// 检查必要配置是否完整
boolean configValid = chatConfig.getApiToken() != null && !chatConfig.getApiToken().trim().isEmpty() &&
chatConfig.getBotId() != null && !chatConfig.getBotId().trim().isEmpty() &&
chatConfig.getApiBaseUrl() != null && !chatConfig.getApiBaseUrl().trim().isEmpty();
if (!configValid) {
log.warn("Coze API 配置不完整");
log.warn("AI配置不完整: configId={}", chatConfig.getId());
return false;
}
@@ -587,65 +575,89 @@ public class AiChatServiceImpl implements AiChatService {
CozeApiCall apiCall = createSummaryApiCallRecord(conversationId, null, userMessage, userId, "summary");
try {
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + cozeApiToken);
headers.set("Content-Type", "application/json");
// 构建请求体 - 使用总结专用的bot和workflow
Map<String, Object> requestBody = buildSummaryRequest(conversationId, userMessage, userId);
// 更新API调用记录的请求信息
updateApiCallRequest(apiCall, cozeBaseUrl + chatPath, requestBody, headers);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
// 构建完整的API URL
String cozeApiUrl = cozeBaseUrl + chatPath;
log.info("发送Coze总结请求到: {}, 请求体: {}", cozeApiUrl, requestBody);
// 发送请求
ResponseEntity<String> response = restTemplate.exchange(
cozeApiUrl,
HttpMethod.POST,
request,
String.class);
log.info("收到Coze总结初始响应: {}", response.getBody());
// 更新API调用记录的响应信息
updateApiCallResponse(apiCall, response);
// 解析响应获取chat_id和conversation_id
JSONObject responseJson = JSON.parseObject(response.getBody());
String chatId = extractChatIdFromResponse(responseJson);
String cozeConversationId = extractConversationIdFromResponse(responseJson);
if (chatId != null && cozeConversationId != null) {
// 更新API调用记录的Coze ID信息
updateApiCallCozeIds(apiCall, chatId, cozeConversationId);
// 轮询聊天状态直到完成并获取回复内容
String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
log.info("Coze AI总结响应成功: reply={}", aiReply);
// 更新API调用记录的最终结果
updateApiCallSuccess(apiCall, aiReply);
return aiReply;
} else {
log.error("无法从Coze总结响应中获取chat_id或conversation_id");
updateApiCallError(apiCall, "INVALID_RESPONSE", "无法从Coze总结响应中获取chat_id或conversation_id");
return "抱歉,AI总结服务响应异常,请稍后再试。";
}
return executeSummaryCozeApiCall(apiCall, conversationId, userMessage, userId);
} catch (Exception e) {
log.error("发送总结消息到Coze AI失败", e);
updateApiCallError(apiCall, "REQUEST_FAILED", e.getMessage());
log.error("发送总结消息失败", e);
updateApiCallFailure(apiCall, e.getMessage());
return "抱歉,AI总结服务暂时不可用,请稍后再试。";
}
}
/**
* 执行总结Coze API调用的逻辑
*/
private String executeSummaryCozeApiCall(CozeApiCall apiCall, String conversationId, String userMessage, String userId) {
// 获取总结场景的AI配置
AiConfig config = getSummaryAiConfig();
// 构建请求体 - 使用总结专用的bot和workflow
Map<String, Object> requestBody = buildSummaryRequest(conversationId, userMessage, userId);
// 检查是否使用流式输出
boolean useStream = (Boolean) requestBody.get("stream");
if (useStream) {
return executeStreamCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
} else {
return executeSummaryNormalCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
}
}
/**
* 执行普通(非流式)总结Coze API调用
*/
private String executeSummaryNormalCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody,
String conversationId, String userMessage, String userId) {
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + config.getApiToken());
headers.set("Content-Type", "application/json");
// 构建完整的API URL
String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
// 更新API调用记录的请求信息
updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
log.info("发送Coze总结请求到: {}, 请求体: {}", cozeApiUrl, requestBody);
// 发送请求
ResponseEntity<String> response = restTemplate.exchange(
cozeApiUrl,
HttpMethod.POST,
request,
String.class);
log.info("收到Coze总结初始响应: {}", response.getBody());
// 更新API调用记录的响应信息
updateApiCallResponse(apiCall, response);
// 解析响应获取chat_id和conversation_id
JSONObject responseJson = JSON.parseObject(response.getBody());
String chatId = extractChatIdFromResponse(responseJson);
String cozeConversationId = extractConversationIdFromResponse(responseJson);
if (chatId != null && cozeConversationId != null) {
// 更新API调用记录的Coze ID信息
updateApiCallCozeIds(apiCall, chatId, cozeConversationId);
// 轮询聊天状态直到完成并获取回复内容
String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
log.info("Coze AI总结响应成功: reply={}", aiReply);
// 更新API调用记录的最终结果
updateApiCallSuccess(apiCall, aiReply);
return aiReply;
} else {
log.error("无法从Coze总结响应中获取chat_id或conversation_id");
updateApiCallError(apiCall, "INVALID_RESPONSE", "无法从Coze总结响应中获取chat_id或conversation_id");
return "抱歉,AI总结服务响应异常,请稍后再试。";
}
}
@Override
public EmotionSummaryGenerateResponse generateEmotionSummaryWithResponse(String userId) {
log.info("生成用户情绪记录总结: userId={}", userId);
@@ -719,9 +731,11 @@ public class AiChatServiceImpl implements AiChatService {
public boolean isServiceAvailable() {
try {
// 简单的健康检查
return cozeApiToken != null && !cozeApiToken.isEmpty() &&
chatBotId != null && !chatBotId.isEmpty();
// 检查聊天场景的AI配置是否可用
AiConfig chatConfig = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
return chatConfig != null &&
chatConfig.getApiToken() != null && !chatConfig.getApiToken().isEmpty() &&
chatConfig.getBotId() != null && !chatConfig.getBotId().isEmpty();
} catch (Exception e) {
log.error("检查AI服务可用性失败", e);
return false;
@@ -751,22 +765,40 @@ public class AiChatServiceImpl implements AiChatService {
* 执行Coze API调用的公共逻辑
*/
private String executeCozeApiCall(CozeApiCall apiCall, String conversationId, String userMessage, String userId) {
// 获取聊天场景的AI配置
AiConfig config = getChatAiConfig();
// 构建请求体 - 使用正确的Coze API格式
Map<String, Object> requestBody = buildCozeRequestWithConfig(conversationId, userMessage, userId, config);
// 检查是否使用流式输出
boolean useStream = (Boolean) requestBody.get("stream");
if (useStream) {
return executeStreamCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
} else {
return executeNormalCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
}
}
/**
* 执行普通(非流式)Coze API调用
*/
private String executeNormalCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody,
String conversationId, String userMessage, String userId) {
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + cozeApiToken);
headers.set("Authorization", "Bearer " + config.getApiToken());
headers.set("Content-Type", "application/json");
// 构建请求体 - 使用正确的Coze API格式
Map<String, Object> requestBody = buildCozeRequest(conversationId, userMessage, userId);
// 构建完整的API URL
String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
// 更新API调用记录的请求信息
updateApiCallRequest(apiCall, cozeBaseUrl + chatPath, requestBody, headers);
updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
// 构建完整的API URL
String cozeApiUrl = cozeBaseUrl + chatPath;
log.info("发送Coze请求到: {}, 请求体: {}", cozeApiUrl, requestBody);
log.info("发送Coze普通请求到: {}, 请求体: {}", cozeApiUrl, requestBody);
// 发送请求
ResponseEntity<String> response = restTemplate.exchange(
@@ -791,7 +823,7 @@ public class AiChatServiceImpl implements AiChatService {
// 轮询聊天状态直到完成并获取回复内容
String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
log.info("Coze AI响应成功: reply={}", aiReply);
log.info("Coze AI普通响应成功: reply={}", aiReply);
// 更新API调用记录的最终结果
updateApiCallSuccess(apiCall, aiReply);
@@ -804,6 +836,165 @@ public class AiChatServiceImpl implements AiChatService {
}
}
/**
* 执行流式Coze API调用
*/
private String executeStreamCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody,
String conversationId, String userMessage, String userId) {
try {
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + config.getApiToken());
headers.set("Content-Type", "application/json");
headers.set("Accept", "text/event-stream");
// 构建完整的API URL
String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
// 更新API调用记录的请求信息
updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);
log.info("发送Coze流式请求到: {}, 请求体: {}", cozeApiUrl, requestBody);
// 使用RestTemplate处理流式响应
String streamResponse = handleStreamResponse(cozeApiUrl, headers, requestBody, apiCall);
log.info("Coze AI流式响应完成: length={}", streamResponse != null ? streamResponse.length() : 0);
// 更新API调用记录的最终结果
updateApiCallSuccess(apiCall, streamResponse);
return streamResponse;
} catch (Exception e) {
log.error("流式API调用失败", e);
updateApiCallError(apiCall, "STREAM_ERROR", e.getMessage());
return "抱歉,AI流式服务暂时不可用,请稍后再试。";
}
}
/**
* 处理流式响应
*/
private String handleStreamResponse(String url, HttpHeaders headers, Map<String, Object> requestBody, CozeApiCall apiCall) {
try {
// 创建HTTP客户端
java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
.connectTimeout(java.time.Duration.ofSeconds(30))
.build();
// 构建请求
java.net.http.HttpRequest.Builder requestBuilder = java.net.http.HttpRequest.newBuilder()
.uri(java.net.URI.create(url))
.timeout(java.time.Duration.ofMinutes(5))
.POST(java.net.http.HttpRequest.BodyPublishers.ofString(JSON.toJSONString(requestBody)));
// 添加请求头
headers.forEach((key, values) -> {
if (values != null && !values.isEmpty()) {
requestBuilder.header(key, values.get(0));
}
});
java.net.http.HttpRequest request = requestBuilder.build();
// 发送请求并处理流式响应
StringBuilder responseBuilder = new StringBuilder();
StringBuilder fullStreamData = new StringBuilder();
java.net.http.HttpResponse<java.util.stream.Stream<String>> response = client.send(request,
java.net.http.HttpResponse.BodyHandlers.ofLines());
log.info("流式响应状态码: {}", response.statusCode());
if (response.statusCode() != 200) {
String errorBody = response.body().collect(java.util.stream.Collectors.joining("\n"));
log.error("流式请求失败,状态码: {}, 响应: {}", response.statusCode(), errorBody);
return "流式请求失败,状态码: " + response.statusCode();
}
// 处理流式数据
response.body().forEach(line -> {
fullStreamData.append(line).append("\n");
if (line.startsWith("data: ")) {
String data = line.substring(6).trim();
if ("[DONE]".equals(data)) {
log.info("流式响应完成");
return;
}
try {
JSONObject jsonData = JSON.parseObject(data);
// 提取消息内容
if (jsonData.containsKey("choices")) {
com.alibaba.fastjson2.JSONArray choices = jsonData.getJSONArray("choices");
if (choices != null && !choices.isEmpty()) {
JSONObject choice = choices.getJSONObject(0);
if (choice != null && choice.containsKey("delta")) {
JSONObject delta = choice.getJSONObject("delta");
if (delta != null && delta.containsKey("content")) {
String content = delta.getString("content");
if (content != null) {
responseBuilder.append(content);
}
}
}
}
}
// Coze特定格式处理
if (jsonData.containsKey("event")) {
String event = jsonData.getString("event");
if ("conversation.message.delta".equals(event) && jsonData.containsKey("data")) {
JSONObject eventData = jsonData.getJSONObject("data");
if (eventData != null && eventData.containsKey("content")) {
String content = eventData.getString("content");
if (content != null) {
responseBuilder.append(content);
}
}
}
}
} catch (Exception e) {
log.warn("解析流式数据失败: {}, 数据: {}", e.getMessage(), data);
}
}
});
// 记录完整的流式数据用于调试
updateApiCallStreamData(apiCall, fullStreamData.toString());
String finalResponse = responseBuilder.toString();
if (finalResponse.isEmpty()) {
log.warn("流式响应为空,返回默认消息");
return "收到了流式响应,但内容为空。";
}
return finalResponse;
} catch (Exception e) {
log.error("处理流式响应失败", e);
throw new RuntimeException("处理流式响应失败: " + e.getMessage(), e);
}
}
/**
* 更新API调用记录的流式数据
*/
private void updateApiCallStreamData(CozeApiCall apiCall, String streamData) {
try {
// 可以将流式数据存储到响应体字段中,用于调试和分析
apiCall.setResponseBody(streamData);
cozeApiCallService.updateById(apiCall);
} catch (Exception e) {
log.error("更新API调用记录流式数据失败: {}", e.getMessage(), e);
}
}
public Map<String, Object> guestChat(String message, String clientIp) {
log.info("访客聊天: message={}, clientIp={}", message, clientIp);
@@ -883,16 +1074,28 @@ public class AiChatServiceImpl implements AiChatService {
* 构建Coze API请求 - 根据官方文档修正格式
*/
private Map<String, Object> buildCozeRequest(String conversationId, String userMessage, String userId) {
// 获取聊天场景的AI配置
AiConfig config = getChatAiConfig();
return buildCozeRequestWithConfig(conversationId, userMessage, userId, config);
}
/**
* 使用指定配置构建Coze API请求
*/
private Map<String, Object> buildCozeRequestWithConfig(String conversationId, String userMessage, String userId, AiConfig config) {
Map<String, Object> cozeRequest = new HashMap<>();
cozeRequest.put("bot_id", chatBotId);
cozeRequest.put("bot_id", config.getBotId());
// 如果有workflow_id,则添加
if (chatWorkflowId != null && !chatWorkflowId.trim().isEmpty()) {
cozeRequest.put("workflow_id", chatWorkflowId);
if (config.getWorkflowId() != null && !config.getWorkflowId().trim().isEmpty()) {
cozeRequest.put("workflow_id", config.getWorkflowId());
}
cozeRequest.put("user_id", userId != null ? userId : DEFAULT_USER_ID);
cozeRequest.put("stream", false);
// 根据配置决定是否使用流式输出
boolean useStream = config.getSupportStream() != null && config.getSupportStream() == 1;
cozeRequest.put("stream", useStream);
// 构建消息列表 - 按照 Coze API 标准格式
java.util.List<Map<String, Object>> messages = new java.util.ArrayList<>();
@@ -944,6 +1147,9 @@ public class AiChatServiceImpl implements AiChatService {
*/
private String waitForChatCompletion(String chatId, String conversationId) {
try {
// 获取聊天场景的AI配置
AiConfig config = getChatAiConfig();
// 最多等待30秒,每2秒轮询一次
int maxAttempts = 15;
int attempt = 0;
@@ -952,12 +1158,12 @@ public class AiChatServiceImpl implements AiChatService {
log.info("轮询聊天状态,第{}次尝试: chatId={}, conversationId={}", attempt + 1, chatId, conversationId);
// 构建状态查询URL
String statusUrl = cozeBaseUrl + "/v3/chat/retrieve?chat_id=" + chatId + "&conversation_id="
String statusUrl = config.getApiBaseUrl() + "/v3/chat/retrieve?chat_id=" + chatId + "&conversation_id="
+ conversationId;
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + cozeApiToken);
headers.set("Authorization", "Bearer " + config.getApiToken());
headers.set("Content-Type", "application/json");
HttpEntity<String> request = new HttpEntity<>(headers);
@@ -1009,15 +1215,18 @@ public class AiChatServiceImpl implements AiChatService {
*/
private String getChatMessages(String chatId, String conversationId) {
try {
// 获取聊天场景的AI配置
AiConfig config = getChatAiConfig();
log.info("获取聊天消息: chatId={}, conversationId={}", chatId, conversationId);
// 构建消息查询URL
String messagesUrl = cozeBaseUrl + "/v3/chat/message/list?chat_id=" + chatId + "&conversation_id="
String messagesUrl = config.getApiBaseUrl() + "/v3/chat/message/list?chat_id=" + chatId + "&conversation_id="
+ conversationId;
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + cozeApiToken);
headers.set("Authorization", "Bearer " + config.getApiToken());
headers.set("Content-Type", "application/json");
HttpEntity<String> request = new HttpEntity<>(headers);
@@ -1067,16 +1276,22 @@ public class AiChatServiceImpl implements AiChatService {
* 构建总结请求 - 使用专门的总结bot和workflow
*/
private Map<String, Object> buildSummaryRequest(String conversationId, String userMessage, String userId) {
// 获取总结场景的AI配置
AiConfig config = getSummaryAiConfig();
Map<String, Object> cozeRequest = new HashMap<>();
cozeRequest.put("bot_id", summaryBotId != null && !summaryBotId.trim().isEmpty() ? summaryBotId : chatBotId);
cozeRequest.put("bot_id", config.getBotId());
// 如果有总结workflow_id,则添加
if (summaryWorkflowId != null && !summaryWorkflowId.trim().isEmpty()) {
cozeRequest.put("workflow_id", summaryWorkflowId);
// 如果有workflow_id,则添加
if (config.getWorkflowId() != null && !config.getWorkflowId().trim().isEmpty()) {
cozeRequest.put("workflow_id", config.getWorkflowId());
}
cozeRequest.put("user_id", userId != null ? userId : DEFAULT_USER_ID);
cozeRequest.put("stream", false);
// 根据配置决定是否使用流式输出
boolean useStream = config.getSupportStream() != null && config.getSupportStream() == 1;
cozeRequest.put("stream", useStream);
cozeRequest.put("auto_save_history", true);
// 如果有会话ID,则添加
@@ -1118,6 +1333,9 @@ public class AiChatServiceImpl implements AiChatService {
*/
private CozeApiCall createApiCallRecord(String conversationId, String messageId, String userMessage, String userId,
String requestType) {
// 获取聊天场景的AI配置
AiConfig config = getChatAiConfig();
CozeApiCall apiCall = CozeApiCall.builder()
.conversationId(conversationId)
.messageId(messageId) // 设置messageId
@@ -1125,8 +1343,8 @@ public class AiChatServiceImpl implements AiChatService {
.requestType(requestType)
.userMessage(userMessage)
.userMessageType("text")
.botId(chatBotId)
.workflowId(chatWorkflowId)
.botId(config.getBotId())
.workflowId(config.getWorkflowId())
.status("pending")
.startTime(LocalDateTime.now())
.traceId(UUID.randomUUID().toString())
@@ -1158,6 +1376,9 @@ public class AiChatServiceImpl implements AiChatService {
*/
private CozeApiCall createSummaryApiCallRecord(String conversationId, String messageId, String userMessage,
String userId, String requestType) {
// 获取总结场景的AI配置
AiConfig config = getSummaryAiConfig();
CozeApiCall apiCall = CozeApiCall.builder()
.conversationId(conversationId)
.messageId(messageId) // 设置messageId
@@ -1165,8 +1386,8 @@ public class AiChatServiceImpl implements AiChatService {
.requestType(requestType)
.userMessage(userMessage)
.userMessageType("text")
.botId(summaryBotId)
.workflowId(summaryWorkflowId)
.botId(config.getBotId())
.workflowId(config.getWorkflowId())
.status("pending")
.startTime(LocalDateTime.now())
.traceId(UUID.randomUUID().toString())
@@ -1505,4 +1726,36 @@ public class AiChatServiceImpl implements AiChatService {
return record;
}
/**
* 获取聊天场景的AI配置
*/
private AiConfig getChatAiConfig() {
AiConfig config = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
if (config == null) {
log.error("未找到聊天场景的AI配置");
throw new RuntimeException("未找到聊天场景的AI配置,请先在管理后台配置");
}
return config;
}
/**
* 获取总结场景的AI配置
*/
private AiConfig getSummaryAiConfig() {
AiConfig config = aiConfigService.getBestConfig(USAGE_SCENARIO_SUMMARY, DEFAULT_ENVIRONMENT);
if (config == null) {
log.warn("未找到总结场景的AI配置,使用聊天配置");
return getChatAiConfig();
}
return config;
}
/**
* 获取配置的API路径
*/
private String getApiPath(AiConfig config) {
// 默认使用 /v3/chat 路径
return "/v3/chat";
}
}