package cc.mrbird.febs.ai.strategy.Impl; 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 cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.yinhe.req.AiRequestDto; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; 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.app.*; 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 com.alibaba.dashscope.utils.JsonUtils; import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; @Slf4j @Component("AliLlmStrategyService") public class AliLlmStrategyServiceImpl implements LlmStrategyService { @Override public FebsResponse llmInvokeNonStreaming(List dto) { return new FebsResponse().success(); } @Override public Flux llmInvokeStreamingWithThink(List dto) { return null; } @Override public Flux llmInvokeStreamingNoThink(List dto) { return null; } private ApplicationParam applicationParam; @Autowired private RedisUtils redisUtils; @PostConstruct public void init() { this.applicationParam = ApplicationParam.builder() // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。 .apiKey(YHapiKey) .appId(YHappId) .build(); } private static final String YHapiKey = "sk-4b97b556ba7c4350a41f2856f75b9377"; // private static final String appId = "71022536aca048528b61ac43c77f0e94"; private static final String YHappId = "04beff88c50d4ccaaf1814231b02d2bb"; @Override public Flux llmInvokeStreamingNoThink(AiRequestDto dto) { long startTime = System.currentTimeMillis(); if (ObjectUtil.isEmpty(dto)){ throw new FebsException("参数异常"); } String talkId = dto.getTalkId(); String rolePrompt = dto.getRolePrompt(); List messages = dto.getMessages(); HashMap userPromptParams = new HashMap<>(); userPromptParams.put("role_prompt", rolePrompt); if(CollUtil.isNotEmpty( messages)){ userPromptParams.put("message_list", messages); } HashMap bizParams = new HashMap<>(); bizParams.put("user_prompt_params", userPromptParams); List knowledgeIds = dto.getKnowledgeIds(); List fileIds = dto.getFileIds(); String prompt = dto.getPrompt(); Application application = new Application(); applicationParam.setPrompt(prompt); applicationParam.setBizParams(JsonUtils.toJsonObject( bizParams)); // 获取当前的系统时间 applicationParam.setEnableSystemTime( true); // 增量输出 applicationParam.setIncrementalOutput( true); // 思考过程 applicationParam.setEnableThinking( false); // 多轮对话 // applicationParam.setMessages(messages); // 上下文seesionId // String sessionId = (String) redisCache.getCacheObject(talkId); // if (ObjectUtil.isNotEmpty(sessionId)){ // applicationParam.setSessionId(talkId); // } RagOptions ragOptions = null; if (CollUtil.isEmpty(fileIds)){ ragOptions = RagOptions.builder() .pipelineIds(knowledgeIds) .build(); }else{ ragOptions = RagOptions.builder() .pipelineIds(knowledgeIds) .fileIds(fileIds) .build(); } applicationParam.setRagOptions(ragOptions); Flowable result; try { result = application.streamCall(applicationParam); } catch (NoApiKeyException | InputRequiredException e) { throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",e.getMessage())); } return Flux.from(result) .map(message -> { HashMap stringStringHashMap = new HashMap<>(); if (!message.getOutput().getFinishReason().equals("stop")){ stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getOutput().getText()); } if (message.getOutput().getFinishReason().equals("stop")){ log.info("百炼大模型输出:{}",message.getOutput().getSessionId()); List models = message.getUsage().getModels(); long outputTokens = models.stream().mapToLong(ApplicationUsage.ModelUsage::getOutputTokens).sum(); log.info("百炼大模型输出:{}",outputTokens); long inputTokens = models.stream().mapToLong(ApplicationUsage.ModelUsage::getInputTokens).sum(); log.info("百炼大模型输出:{}",inputTokens); redisUtils.set(talkId, message.getOutput().getSessionId(), 5*60); stringStringHashMap.put("inputTokens:",inputTokens); stringStringHashMap.put("outputTokens:",outputTokens); } return new FebsResponse().success().data(stringStringHashMap); }) .doOnComplete(() -> { long endTime = System.currentTimeMillis(); System.out.println("百炼大模型输出:" + (endTime - startTime) + "毫秒"); }) .doOnError(error -> { throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error)); }); } }