Administrator
2025-09-02 ddf31ac4e871f442dfcc7ce1543f18159bc52077
refactor(ai): 重构 AI服务调用方法

- 修改 AiTalkServiceImpl 中的 llmInvokeStreaming 方法名为 llmInvokeStreamingWithThink
- 在 AliLlmStrategyServiceImpl 和 HsLlmStrategyServiceImpl 中实现新的 llmInvokeStreamingNoThink 方法
- 更新 LlmStrategyService 接口,添加新的 llmInvokeStreamingNoThink 方法
- 在 TestController 中更新方法调用,使用新的 llmInvokeStreamingWithThink 方法
5 files modified
117 ■■■■ changed files
src/main/java/cc/mrbird/febs/ai/controller/TestController.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java 3 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java 38 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java 70 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java 4 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/TestController.java
@@ -168,7 +168,7 @@
        }
        String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType());
        return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreaming(llmStrategyDtoList);
        return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingWithThink(llmStrategyDtoList);
    }
src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java
@@ -8,7 +8,6 @@
import cc.mrbird.febs.ai.req.talk.ApiTalkDto;
import cc.mrbird.febs.ai.req.talk.ApiTalkItemPageDto;
import cc.mrbird.febs.ai.req.talk.ApiTalkPageDto;
import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberProductWorkVo;
import cc.mrbird.febs.ai.res.talk.ApiTalkPageVo;
import cc.mrbird.febs.ai.res.talk.ApiTalkQuestionVo;
import cc.mrbird.febs.ai.res.talk.ApiTalkVo;
@@ -143,7 +142,7 @@
            llmStrategyDtoList.add(llmStrategyDto);
        }
        String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType());
        return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreaming(llmStrategyDtoList);
        return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingWithThink(llmStrategyDtoList);
    }
}
src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
@@ -92,7 +92,7 @@
    }
    @Override
    public Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto) {
    public Flux<FebsResponse> llmInvokeStreamingWithThink(List<LlmStrategyDto> dto) {
        if (CollUtil.isEmpty(dto)){
            throw new FebsException("百炼大模型初始化异常");
        }
@@ -130,4 +130,40 @@
                    throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error));
                });
    }
    @Override
    public Flux<FebsResponse> llmInvokeStreamingNoThink(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(messages);
        generationParam.setResultFormat(GenerationParam.ResultFormat.MESSAGE);
        generationParam.setIncrementalOutput(true);
        Flowable<GenerationResult> result;
        try {
            result = gen.streamCall(generationParam);
        } catch (NoApiKeyException | InputRequiredException e) {
            throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",e.getMessage()));
        }
        return Flux.from(result)
                .map(message -> {
                    HashMap<String, String> stringStringHashMap = new HashMap<>();
                    if (StrUtil.isNotEmpty(message.getOutput().getChoices().get(0).getMessage().getContent())){
                        stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getOutput().getChoices().get(0).getMessage().getContent());
                    }
                    return new FebsResponse().success().data(stringStringHashMap);
                })
                .doOnComplete(() -> {
                    long endTime = System.currentTimeMillis();
                    System.out.println("百炼大模型输出:" + (endTime - startTime) + "毫秒");
                })
                .doOnError(error -> {
                    throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error));
                });
    }
}
src/main/java/cc/mrbird/febs/ai/strategy/Impl/HsLlmStrategyServiceImpl.java
@@ -1,29 +1,24 @@
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.enumerates.LlmStrategyContextEnum;
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.ObjectUtil;
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.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -122,7 +117,7 @@
    }
    @Override
    public Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto) {
    public Flux<FebsResponse> llmInvokeStreamingWithThink(List<LlmStrategyDto> dto) {
        if (CollUtil.isEmpty(dto)){
            throw new FebsException("火山大模型初始化异常");
        }
@@ -151,21 +146,56 @@
                    }
                    ChatMessage message = choice.getMessage();
                    ApiMemberTalkStreamVo apiMemberTalkStreamVo = new ApiMemberTalkStreamVo();
                    // 处理 reasoning content
                    String reasoningContent = message.getReasoningContent();
                    if (StrUtil.isNotEmpty(reasoningContent)) {
                        apiMemberTalkStreamVo.setReasoningContent(reasoningContent);
                    HashMap<String, String> stringStringHashMap = new HashMap<>();
                    if (ObjectUtil.isNotEmpty(message.getReasoningContent())) {
                        stringStringHashMap.put(LlmStrategyContextEnum.THINK.name(),message.getReasoningContent().toString());
                    }
                    if (ObjectUtil.isNotEmpty(message.getContent())) {
                        stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getContent().toString());
                    }
                    return new FebsResponse().success().data(stringStringHashMap);
                })
                .onErrorResume(throwable -> {
                    throw new FebsException(StrUtil.format("火山大模型流式调用AI服务失:{}",throwable));
                });
    }
    @Override
    public Flux<FebsResponse> llmInvokeStreamingNoThink(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)
                .temperature(temperature) // 降低温度参数,提高确定性,可能提升速度
                .topP(topP)        // 调整topP参数
                .maxTokens(maxTokens)  // 减少最大token数
                .frequencyPenalty(frequencyPenalty)
                .build();
        return Flux.from(service.streamChatCompletion(chatCompletionRequest))
                .map(response -> {
                    if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) {
                        return new FebsResponse().success().data("未响应,请重试");
                    }
                    // 安全处理 content
                    String content = "";
                    if (message.getContent() != null) {
                        content = message.getContent().toString();
                    ChatCompletionChoice choice = response.getChoices().get(0);
                    if (choice == null || choice.getMessage() == null) {
                        return new FebsResponse().success().data("END");
                    }
                    apiMemberTalkStreamVo.setContent(content);
                    return new FebsResponse().success().data(apiMemberTalkStreamVo);
                    ChatMessage message = choice.getMessage();
                    HashMap<String, String> stringStringHashMap = new HashMap<>();
                    if (ObjectUtil.isNotEmpty(message.getContent())) {
                        stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getContent().toString());
                    }
                    return new FebsResponse().success().data(stringStringHashMap);
                })
                .onErrorResume(throwable -> {
                    throw new FebsException(StrUtil.format("火山大模型流式调用AI服务失:{}",throwable));
src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
@@ -10,5 +10,7 @@
    FebsResponse llmInvokeNonStreaming(List<LlmStrategyDto> dto);
    Flux<FebsResponse> llmInvokeStreaming(List<LlmStrategyDto> dto);
    Flux<FebsResponse> llmInvokeStreamingWithThink(List<LlmStrategyDto> dto);
    Flux<FebsResponse> llmInvokeStreamingNoThink(List<LlmStrategyDto> dto);
}