src/main/java/cc/mrbird/febs/ai/controller/TestController.java
@@ -42,10 +42,7 @@ import com.alibaba.dashscope.exception.NoApiKeyException; import reactor.core.publisher.Flux; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.*; /** * @author Administrator @@ -155,18 +152,23 @@ if (StrUtil.isEmpty(dto.getQuestion())){ return Flux.just(new FebsResponse().fail().message("请输入问题")); } LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) .content(dto.getPrompt()) .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) .content(dto.getQuestion()) .build(); List<Message> messages = Arrays.asList(systemMsg, userMsg); llmStrategyDto.setMessages(messages); return llmStrategyFactory.getCalculationStrategyMap().get(LlmStrategyEnum.ALI.getName()).llmInvokeStreaming(llmStrategyDto); ArrayList<LlmStrategyDto> llmStrategyDtoList = new ArrayList<>(); if (dto.getPrompt() != null){ LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); llmStrategyDto.setRole(Role.SYSTEM.getValue()); llmStrategyDto.setContent(dto.getPrompt()); llmStrategyDtoList.add(llmStrategyDto); } if (dto.getQuestion() != null){ LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); llmStrategyDto.setRole(Role.USER.getValue()); llmStrategyDto.setContent(dto.getQuestion()); llmStrategyDtoList.add(llmStrategyDto); } String modelName = LlmStrategyEnum.getName(dto.getType()); return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreaming(llmStrategyDtoList); } @@ -180,18 +182,22 @@ if (StrUtil.isEmpty(dto.getQuestion())){ return new FebsResponse().fail().message("请输入问题"); } LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) .content(dto.getPrompt()) .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) .content(dto.getQuestion()) .build(); List<Message> messages = Arrays.asList(systemMsg, userMsg); llmStrategyDto.setMessages(messages); return llmStrategyFactory.getCalculationStrategyMap().get(LlmStrategyEnum.ALI.getName()).llmInvokeNonStreaming(llmStrategyDto); ArrayList<LlmStrategyDto> llmStrategyDtoList = new ArrayList<>(); if (dto.getPrompt() != null){ LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); llmStrategyDto.setRole(Role.SYSTEM.getValue()); llmStrategyDto.setContent(dto.getPrompt()); llmStrategyDtoList.add(llmStrategyDto); } if (dto.getQuestion() != null){ LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); llmStrategyDto.setRole(Role.USER.getValue()); llmStrategyDto.setContent(dto.getQuestion()); llmStrategyDtoList.add(llmStrategyDto); } String modelName = LlmStrategyEnum.getName(dto.getType()); return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeNonStreaming(llmStrategyDtoList); } src/main/java/cc/mrbird/febs/ai/req/talk/AiTalkAnswerStream.java
@@ -13,6 +13,9 @@ @ApiModel(value = "AiTalkAnsStream", description = "参数") public class AiTalkAnswerStream { @ApiModelProperty(value = "类型 1:火山 2:阿里", example = "10") private Integer type; @ApiModelProperty(value = "会话ID", example = "10") private String talkId; src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
@@ -4,10 +4,13 @@ import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.dashscope.aigc.generation.Generation; import com.alibaba.dashscope.aigc.generation.GenerationParam; import com.alibaba.dashscope.aigc.generation.GenerationResult; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; @@ -15,6 +18,8 @@ import reactor.core.publisher.Flux; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @Component("AliLlmStrategyService") public class AliLlmStrategyServiceImpl implements LlmStrategyService { @@ -32,10 +37,39 @@ .build(); } private List<Message> getMessages(List<LlmStrategyDto> dto) { List<Message> messages = new ArrayList<>(); for (LlmStrategyDto dtoItem : dto){ if (StrUtil.equals(dtoItem.getRole(),Role.SYSTEM.getValue())){ messages.add(Message.builder() .role(Role.SYSTEM.getValue()) .content(dtoItem.getContent()) .build()); } if (StrUtil.equals(dtoItem.getRole(),Role.USER.getValue())){ messages.add(Message.builder() .role(Role.USER.getValue()) .content(dtoItem.getContent()) .build()); } if (StrUtil.equals(dtoItem.getRole(),Role.ASSISTANT.getValue())){ messages.add(Message.builder() .role(Role.ASSISTANT.getValue()) .content(dtoItem.getContent()) .build()); } } return messages; } @Override public FebsResponse llmInvokeNonStreaming(LlmStrategyDto dto) { public FebsResponse llmInvokeNonStreaming(List<LlmStrategyDto> dto) { if (CollUtil.isEmpty(dto)){ throw new FebsException("百炼大模型初始化异常"); } List<Message> messages = getMessages(dto); Generation gen = new Generation(); generationParam.setMessages(dto.getMessages()); generationParam.setMessages(messages); FebsResponse febsResponse = new FebsResponse(); try { GenerationResult result = gen.call(generationParam); @@ -53,11 +87,15 @@ } @Override public Flux<FebsResponse> llmInvokeStreaming(LlmStrategyDto dto) { public Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto) { if (CollUtil.isEmpty(dto)){ throw new FebsException("百炼大模型初始化异常"); } List<Message> messages = getMessages(dto); long startTime = System.currentTimeMillis(); Generation gen = new Generation(); generationParam.setMessages(dto.getMessages()); generationParam.setMessages(messages); generationParam.setResultFormat(GenerationParam.ResultFormat.MESSAGE); generationParam.setIncrementalOutput(true); Flowable<GenerationResult> result; src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java
@@ -1,20 +1,167 @@ package cc.mrbird.febs.ai.strategy.Impl; import cc.mrbird.febs.ai.entity.AiTalkItem; import cc.mrbird.febs.ai.res.ai.Report; import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkStreamVo; import cc.mrbird.febs.ai.strategy.LlmStrategyService; import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.volcengine.ark.runtime.model.completion.chat.*; import com.volcengine.ark.runtime.service.ArkService; import okhttp3.ConnectionPool; import okhttp3.Dispatcher; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Component("HsLlmStrategyService") public class HsLlmStrategyServiceImpl implements LlmStrategyService { private ArkService service; private static final String LinkId = "ep-20250805124033-lhxbf"; @PostConstruct public void init() { // 增加连接池大小和存活时间 ConnectionPool connectionPool = new ConnectionPool(32, 60, TimeUnit.SECONDS); Dispatcher dispatcher = new Dispatcher(); // 增加并发请求数量 dispatcher.setMaxRequests(128); dispatcher.setMaxRequestsPerHost(32); this.service = ArkService.builder() .dispatcher(dispatcher) .connectionPool(connectionPool) .baseUrl("https://ark.cn-beijing.volces.com/api/v3") .ak("AKLTZTQxZjMyZTUxMWJmNDEyNDkzNWExOGQ3ODllNzhhNmQ") .sk("TmpFeE1qZ3haREExTW1JeE5HRTBZVGc1WlRRNVlqWXpORGd5TWpsak5HWQ") .build(); } @PreDestroy public void destroy() { if (service != null) { service.shutdownExecutor(); } } private List<ChatMessage> getMessages(List<LlmStrategyDto> dto) { List<ChatMessage> messages = new ArrayList<>(); for (LlmStrategyDto dtoItem : dto){ if (StrUtil.equals(dtoItem.getRole(), ChatMessageRole.SYSTEM.value())){ messages.add(ChatMessage.builder() .role(ChatMessageRole.SYSTEM) .content(dtoItem.getContent()) .build()); } if (StrUtil.equals(dtoItem.getRole(), ChatMessageRole.USER.value())){ messages.add(ChatMessage.builder() .role(ChatMessageRole.USER) .content(dtoItem.getContent()) .build()); } if (StrUtil.equals(dtoItem.getRole(), ChatMessageRole.ASSISTANT.value())){ messages.add(ChatMessage.builder() .role(ChatMessageRole.ASSISTANT) .content(dtoItem.getContent()) .build()); } } return messages; } @Override public FebsResponse llmInvokeNonStreaming(LlmStrategyDto dto) { return null; public FebsResponse llmInvokeNonStreaming(List<LlmStrategyDto> dto) { if (CollUtil.isEmpty(dto)){ throw new FebsException("火山大模型初始化异常"); } List<ChatMessage> messages = getMessages(dto); String result = ""; try { ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder() .model(LinkId) .messages(messages) .stream(false) .temperature(0.7) // 降低温度参数,提高确定性,可能提升速度 .topP(0.9) // 调整topP参数 .maxTokens(2048) // 减少最大token数 .frequencyPenalty(0.0) .build(); List<ChatCompletionChoice> choices = service.createChatCompletion(chatCompletionRequest).getChoices(); result = choices.stream() .map(choice -> choice.getMessage().getContent()) .filter(contentObj -> contentObj != null) .map(Object::toString) .collect(Collectors.joining()); } catch (Exception e) { throw new FebsException(StrUtil.format("火山大模型调用异常:{}", e.getMessage())); } return new FebsResponse().success().data(result); } @Override public Flux<FebsResponse> llmInvokeStreaming(LlmStrategyDto dto) { return null; public Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto) { if (CollUtil.isEmpty(dto)){ throw new FebsException("火山大模型初始化异常"); } List<ChatMessage> messages = getMessages(dto); ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder() .model(LinkId) .messages(messages) .stream(true) .thinking(new ChatCompletionRequest.ChatCompletionRequestThinking("enabled")) .temperature(0.7) .topP(0.9) .maxTokens(2048) .frequencyPenalty(0.0) .build(); return Flux.from(service.streamChatCompletion(chatCompletionRequest)) .map(response -> { if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) { return new FebsResponse().success().data("未响应,请重试"); } ChatCompletionChoice choice = response.getChoices().get(0); if (choice == null || choice.getMessage() == null) { return new FebsResponse().success().data("END"); } ChatMessage message = choice.getMessage(); ApiMemberTalkStreamVo apiMemberTalkStreamVo = new ApiMemberTalkStreamVo(); // 处理 reasoning content String reasoningContent = message.getReasoningContent(); if (StrUtil.isNotEmpty(reasoningContent)) { apiMemberTalkStreamVo.setReasoningContent(reasoningContent); } // 安全处理 content String content = ""; if (message.getContent() != null) { content = message.getContent().toString(); } apiMemberTalkStreamVo.setContent(content); return new FebsResponse().success().data(apiMemberTalkStreamVo); }) .onErrorResume(throwable -> { throw new FebsException(StrUtil.format("火山大模型流式调用AI服务失:{}",throwable)); }); } } src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyEnum.java
@@ -23,4 +23,13 @@ this.name = name; this.value = value; } public static String getName(int code) { for (LlmStrategyEnum c : LlmStrategyEnum.values()) { if (c.code == code) { return c.name; } } return null; } } src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
@@ -4,9 +4,11 @@ import cc.mrbird.febs.common.entity.FebsResponse; import reactor.core.publisher.Flux; import java.util.List; public interface LlmStrategyService { FebsResponse llmInvokeNonStreaming(LlmStrategyDto dto); FebsResponse llmInvokeNonStreaming(List<LlmStrategyDto> dto); Flux<FebsResponse> llmInvokeStreaming(LlmStrategyDto dto); Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto); } src/main/java/cc/mrbird/febs/ai/strategy/param/LlmStrategyDto.java
@@ -13,6 +13,8 @@ @ApiModel(value = "LlmStrategyDto", description = "参数") public class LlmStrategyDto { private List<Message> messages; private String role; private String content; }