src/main/java/cc/mrbird/febs/ai/controller/agent/ApiAgentController.java
@@ -1,8 +1,6 @@ package cc.mrbird.febs.ai.controller.agent; import cc.mrbird.febs.ai.req.agent.AiAgentInitDto; import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto; import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto; import cc.mrbird.febs.ai.req.agent.*; import cc.mrbird.febs.ai.req.productCategory.ApiProductCategoryAllDto; import cc.mrbird.febs.ai.res.agent.AiAgentInitVo; import cc.mrbird.febs.ai.res.agent.ApiAgentCategoryVo; @@ -10,6 +8,7 @@ import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo; import cc.mrbird.febs.ai.service.AiAgentService; import cc.mrbird.febs.common.entity.FebsResponse; import cn.hutool.core.util.StrUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; @@ -18,6 +17,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import javax.servlet.http.HttpServletRequest; @@ -55,7 +55,7 @@ return service.agentList(dto); } @ApiOperation(value = "初始化智能体", notes = "初始化智能体") @ApiOperation(value = "详情", notes = "详情") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = AiAgentInitVo.class) }) @@ -65,6 +65,35 @@ return service.initAgent(dto); } @ApiOperation(value = "初始化对话", notes = "初始化对话") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = AgentSendInitVo.class) }) @PostMapping(value = "/initSend", produces = "application/json") public FebsResponse initSend(@RequestBody @Validated AgentInitDto dto) { return service.initSend(dto); } @ApiOperation(value = "保存对话消息", notes = "保存对话消息") @PostMapping(value = "/saveContext") public FebsResponse saveContext(@RequestBody @Validated AgentSaveContextDto dto) { return service.saveContext(dto); } @ApiOperation("AI回答(流式)") @ApiResponses({ @ApiResponse(code = 200, message = "流式响应", response = AitalkItemStreamVo.class), }) @PostMapping("/aiAnswer") public Flux<FebsResponse> aiAnswer(@RequestBody @Validated AitalkItemStreamDto dto) { if (StrUtil.isEmpty(dto.getTalkId()) || StrUtil.isEmpty(dto.getReqContext())|| StrUtil.isEmpty(dto.getReqContext())){ return Flux.just(new FebsResponse().fail().message("参数异常")); } return service.aiAnswer(dto); } } src/main/java/cc/mrbird/febs/ai/entity/AiAgentKnowledge.java
New file @@ -0,0 +1,29 @@ package cc.mrbird.febs.ai.entity; import cc.mrbird.febs.common.entity.AiBaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; @Data @TableName("ai_agent_knowledge") public class AiAgentKnowledge extends AiBaseEntity { /** 公司ID */ private String companyId; /** 名称 */ private String name; /** 知识创建时间 */ private Date knowledgeCreateTime; /** 智能体ID */ private String agentId; /** 知识库ID */ private String knowledgeId; } src/main/java/cc/mrbird/febs/ai/entity/AiKnowledgeFile.java
New file @@ -0,0 +1,37 @@ package cc.mrbird.febs.ai.entity; import cc.mrbird.febs.common.entity.AiBaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data @TableName("ai_knowledge_file") public class AiKnowledgeFile extends AiBaseEntity { /** * 状态:0-上传服务器,1-应用数据,2-知识库 3-成功 */ private Integer state; /** * 文件ID */ private String jobId; /** * 文件ID */ private String fileId; /** * 文件存储路径 */ private String savePath; /** * 文件名称 */ private String name; /** * 公司ID */ private String companyId; } src/main/java/cc/mrbird/febs/ai/entity/AiTalk.java
@@ -27,4 +27,7 @@ * 用户ID (UUID) */ private String memberId; /** 智能体ID */ private String agentId; } src/main/java/cc/mrbird/febs/ai/entity/AiTalkItem.java
@@ -30,7 +30,7 @@ /** * 类型 1-用户提问 2-AI回答 */ private Integer type; private String type; /** * 内容 src/main/java/cc/mrbird/febs/ai/mapper/AiAgentKnowledgeMapper.java
New file @@ -0,0 +1,8 @@ package cc.mrbird.febs.ai.mapper; import cc.mrbird.febs.ai.entity.AiAgent; import cc.mrbird.febs.ai.entity.AiAgentKnowledge; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface AiAgentKnowledgeMapper extends BaseMapper<AiAgentKnowledge> { } src/main/java/cc/mrbird/febs/ai/mapper/AiKnowledgeFileMapper.java
New file @@ -0,0 +1,8 @@ package cc.mrbird.febs.ai.mapper; import cc.mrbird.febs.ai.entity.AiAgentKnowledge; import cc.mrbird.febs.ai.entity.AiKnowledgeFile; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface AiKnowledgeFileMapper extends BaseMapper<AiKnowledgeFile> { } src/main/java/cc/mrbird/febs/ai/req/agent/AgentInitDto.java
New file @@ -0,0 +1,17 @@ package cc.mrbird.febs.ai.req.agent; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "AgentInitDto", description = "参数") public class AgentInitDto { @NotBlank(message = "智能体不能为空") @ApiModelProperty(value = "智能体ID", example = "you_ke_*****") private String id; } src/main/java/cc/mrbird/febs/ai/req/agent/AgentSaveContextDto.java
New file @@ -0,0 +1,26 @@ package cc.mrbird.febs.ai.req.agent; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "AgentSaveContextDto", description = "参数") public class AgentSaveContextDto { /** * 用户对话ID (UUID) */ @NotBlank(message = "会话ID不能为空") @ApiModelProperty(value = "会话ID", example = "10") private String talkId; @NotBlank(message = "类型不能为空") @ApiModelProperty(value = "类型 ai:assistant ,用户:user", example = "assistant") private String type; @NotBlank(message = "内容不能为空") @ApiModelProperty(value = "内容", example = "10") private String content; } src/main/java/cc/mrbird/febs/ai/req/agent/AgentSendInitVo.java
New file @@ -0,0 +1,15 @@ package cc.mrbird.febs.ai.req.agent; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "AgentSendInitVo", description = "参数") public class AgentSendInitVo { @ApiModelProperty(value = "会话ID", example = "1") private String talkId; } src/main/java/cc/mrbird/febs/ai/req/agent/AiRequestDto.java
New file @@ -0,0 +1,25 @@ package cc.mrbird.febs.ai.req.agent; import com.alibaba.dashscope.common.Message; import lombok.Data; import java.util.List; @Data public class AiRequestDto { private List<Message> messages; private List<String> knowledgeIds ; private List<String> fileIds; private String prompt; private String rolePrompt; private String talkId; private String companyId; } src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamDto.java
New file @@ -0,0 +1,20 @@ package cc.mrbird.febs.ai.req.agent; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "AitalkItemStreamDto", description = "参数") public class AitalkItemStreamDto { @NotBlank(message = "会话不能为空") @ApiModelProperty(value = "会话ID", example = "10") private String talkId; @NotBlank(message = "内容不能为空") @ApiModelProperty(value = "内容", example = "10") private String reqContext; } src/main/java/cc/mrbird/febs/ai/req/agent/AitalkItemStreamVo.java
New file @@ -0,0 +1,16 @@ package cc.mrbird.febs.ai.req.agent; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "AitalkItemStreamVo", description = "参数") public class AitalkItemStreamVo { @ApiModelProperty(value = "消息") private String content; @ApiModelProperty(value = "思考") private String reasoningContent; } src/main/java/cc/mrbird/febs/ai/req/talk/ApiTalkDto.java
@@ -23,7 +23,7 @@ @NotNull(message = "类型不能为空") @ApiModelProperty(value = "类型 1-用户提问 2-AI回答", example = "10") private Integer type; private String type; @ApiModelProperty(value = "会话ID", example = "10") private String talkId; src/main/java/cc/mrbird/febs/ai/service/AiAgentService.java
@@ -1,11 +1,10 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiAgent; import cc.mrbird.febs.ai.req.agent.AiAgentInitDto; import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto; import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto; import cc.mrbird.febs.ai.req.agent.*; import cc.mrbird.febs.common.entity.FebsResponse; import com.baomidou.mybatisplus.extension.service.IService; import reactor.core.publisher.Flux; public interface AiAgentService extends IService<AiAgent> { @@ -14,4 +13,10 @@ FebsResponse agentList(ApiAgentPageDto dto); FebsResponse initAgent(AiAgentInitDto dto); FebsResponse initSend(AgentInitDto dto); FebsResponse saveContext(AgentSaveContextDto dto); Flux<FebsResponse> aiAnswer(AitalkItemStreamDto dto); } src/main/java/cc/mrbird/febs/ai/service/AiTalkItemService.java
@@ -10,7 +10,7 @@ public interface AiTalkItemService extends IService<AiTalkItem> { void add(String id,String companyId, int code, String context, String memberUuid, DateTime date); void add(String id,String companyId, String code, String context, String memberUuid, DateTime date); FebsResponse historyPage(ApiTalkItemPageDto dto); src/main/java/cc/mrbird/febs/ai/service/impl/AiAgentServiceImpl.java
@@ -3,23 +3,25 @@ import cc.mrbird.febs.ai.entity.*; import cc.mrbird.febs.ai.enumerates.AiCommonEnum; import cc.mrbird.febs.ai.enumerates.ProductCategoryLevelEnum; import cc.mrbird.febs.ai.mapper.AiAgentCategoryMapper; import cc.mrbird.febs.ai.mapper.AiAgentMapper; import cc.mrbird.febs.ai.mapper.AiAgentStartQuestionMapper; import cc.mrbird.febs.ai.req.agent.AiAgentInitDto; import cc.mrbird.febs.ai.req.agent.ApiAgentCategoryAllDto; import cc.mrbird.febs.ai.req.agent.ApiAgentPageDto; import cc.mrbird.febs.ai.mapper.*; import cc.mrbird.febs.ai.req.agent.*; import cc.mrbird.febs.ai.res.agent.AiAgentInitVo; import cc.mrbird.febs.ai.res.agent.ApiAgentCategoryVo; import cc.mrbird.febs.ai.res.agent.ApiAgentVo; import cc.mrbird.febs.ai.res.product.ApiProductVo; import cc.mrbird.febs.ai.res.productCategory.ApiProductCategoryVo; import cc.mrbird.febs.ai.service.AiAgentService; import cc.mrbird.febs.ai.strategy.LlmStrategyFactory; import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum; import cc.mrbird.febs.ai.utils.UUID; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.LoginUserUtil; import cn.hutool.core.bean.BeanUtil; 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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -27,8 +29,10 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import java.util.ArrayList; import java.util.Date; import java.util.List; @Slf4j @@ -39,6 +43,12 @@ private final AiAgentMapper aiAgentMapper; private final AiAgentCategoryMapper aiAgentCategoryMapper; private final AiAgentStartQuestionMapper aiAgentStartQuestionMapper; private final AiTalkMapper aiTalkMapper; private final AiTalkItemMapper aiTalkItemMapper; private final AiCompanyMapper aiCompanyMapper; private final AiAgentKnowledgeMapper aiAgentKnowledgeMapper; private final AiKnowledgeFileMapper aiKnowledgeFileMapper; private final LlmStrategyFactory llmStrategyFactory; @Override public FebsResponse allCategoryList(ApiAgentCategoryAllDto dto) { @@ -98,4 +108,167 @@ return new FebsResponse().success().data(vo); } @Override public FebsResponse initSend(AgentInitDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); AgentSendInitVo vo = new AgentSendInitVo(); String agentId = dto.getId(); //获取智能体信息 AiAgent aiAgent = aiAgentMapper.selectById(agentId); if (aiAgent == null) { throw new FebsException("智能体不存在"); } if (aiAgent.getState() != 1){ throw new FebsException("智能体未启用"); } String companyId = aiAgent.getCompanyId(); /** * 新增一个会话记录 */ AiTalk entity = new AiTalk(); entity.setId(UUID.getSimpleUUIDString()); entity.setCompanyId(companyId); entity.setMemberId(memberUuid); entity.setAgentId(agentId); entity.setCreatedTime(new Date()); aiTalkMapper.insert(entity); vo.setTalkId(entity.getId()); return new FebsResponse().success().data(vo); } @Override public FebsResponse saveContext(AgentSaveContextDto dto) { String talkId = dto.getTalkId(); String type = dto.getType(); String content = dto.getContent(); AiTalk aiTalk = aiTalkMapper.selectById(talkId); if (aiTalk == null) { throw new FebsException("会话不存在"); } //保存会话记录 AiTalkItem aiTalkItem = new AiTalkItem(); aiTalkItem.setId(UUID.getSimpleUUIDString()); aiTalkItem.setCompanyId(aiTalk.getCompanyId()); aiTalkItem.setTalkId(aiTalk.getId()); aiTalkItem.setType(type); aiTalkItem.setContext(content); aiTalkItem.setCreatedTime(new Date()); aiTalkItemMapper.insert(aiTalkItem); return new FebsResponse().success(); } @Override public Flux<FebsResponse> aiAnswer(AitalkItemStreamDto dto) { String talkId = dto.getTalkId(); String reqContext = dto.getReqContext(); AiTalk aiTalk = aiTalkMapper.selectById(talkId); if (aiTalk == null) { throw new FebsException("会话不存在"); } String agentId = aiTalk.getAgentId(); AiAgent aiAgent = aiAgentMapper.selectById(agentId); //判断字符是否足够 String companyId = aiTalk.getCompanyId(); AiCompany aiCompany = aiCompanyMapper.selectById(companyId); if (aiCompany == null) { throw new FebsException("知识库异常"); } //获取智能体绑定的知识库 List<String> knowledgeIds = new ArrayList<>(); String knowledgeId = aiCompany.getKnowledgeId(); knowledgeIds.add(knowledgeId); //获取智能体绑定的查询文件 List<String> fileIds = new ArrayList<>(); List<AiAgentKnowledge> aiAgentKnowledges = aiAgentKnowledgeMapper.selectList( Wrappers.lambdaQuery(AiAgentKnowledge.class) .select(AiAgentKnowledge::getKnowledgeId) .eq(AiAgentKnowledge::getAgentId, agentId) .eq(AiAgentKnowledge::getCompanyId, companyId) ); if (CollUtil.isNotEmpty(aiAgentKnowledges)){ List<String> aiKnowledgeIds = new ArrayList<>(); for (AiAgentKnowledge aiAgentKnowledge : aiAgentKnowledges){ aiKnowledgeIds.add(aiAgentKnowledge.getKnowledgeId()); } if (CollUtil.isNotEmpty(aiKnowledgeIds)){ List<AiKnowledgeFile> aiKnowledges = aiKnowledgeFileMapper.selectList( Wrappers.lambdaQuery(AiKnowledgeFile.class) .select(AiKnowledgeFile::getFileId) .in(AiKnowledgeFile::getId, aiKnowledgeIds) ); if (CollUtil.isNotEmpty(aiKnowledges)){ for (AiKnowledgeFile aiKnowledge : aiKnowledges){ fileIds.add(aiKnowledge.getFileId()); } } } } AiRequestDto aiRequestDto = new AiRequestDto(); aiRequestDto.setTalkId(talkId); String prompt = aiAgent.getPrompt(); aiRequestDto.setRolePrompt(prompt); // List<Message> messages = new ArrayList<>(); // messages.add(Message.builder().role(Role.SYSTEM.getValue()).content(prompt).build()); //获取对话记录 List<Message> messages = new ArrayList<>(); List<AiTalkItem> aiTalkItemList = aiTalkItemMapper.selectList( Wrappers.lambdaQuery(AiTalkItem.class) .eq(AiTalkItem::getTalkId, talkId) .orderByAsc(AiTalkItem::getCreatedTime) ); if (CollUtil.isNotEmpty(aiTalkItemList)){ messages = getMessages(messages,aiTalkItemList); } for ( Message message : messages ){ log.info("上下文内容:{},{}", message.getRole(),message.getContent()); } aiRequestDto.setMessages(messages); aiRequestDto.setKnowledgeIds(knowledgeIds); aiRequestDto.setFileIds(fileIds); aiRequestDto.setPrompt(reqContext); aiRequestDto.setCompanyId(companyId); //日志输出详细的请求参数的每一个属性 log.info("请求参数:{}", aiRequestDto.getPrompt()); log.info("请求参数:{}", aiRequestDto); String modelName = LlmStrategyEnum.getName(2); return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(aiRequestDto); } private List<Message> getMessages(List<Message> messages, List<AiTalkItem> aiTalkItemList) { for (AiTalkItem item : aiTalkItemList){ if (StrUtil.equals(item.getType(), Role.USER.getValue())){ messages.add(Message.builder() .role(Role.USER.getValue()) .content(item.getContext()) .build()); } if (StrUtil.equals(item.getType(),Role.ASSISTANT.getValue())){ messages.add(Message.builder() .role(Role.ASSISTANT.getValue()) .content(item.getContext()) .build()); } } return messages; } } src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkItemServiceImpl.java
@@ -26,7 +26,7 @@ private final AiTalkItemMapper aiTalkItemMapper; @Override public void add(String id,String companyId, int code, String context, String memberUuid, DateTime date) { public void add(String id,String companyId, String code, String context, String memberUuid, DateTime date) { AiTalkItem aiTalkItem = new AiTalkItem(); aiTalkItem.setId(UUID.getSimpleUUIDString()); aiTalkItem.setCompanyId(companyId); src/main/java/cc/mrbird/febs/ai/service/impl/AiTalkServiceImpl.java
@@ -92,7 +92,7 @@ public FebsResponse talkOpen(ApiTalkDto dto) { String talkId = dto.getTalkId(); String context = dto.getContext(); Integer type = dto.getType(); String type = dto.getType(); String reasoningContent = dto.getReasoningContent(); String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); String companyId = LoginUserUtil.getLoginUser().getCompanyId(); src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliApplicationLlmStrategyServiceImpl.java
@@ -1,6 +1,7 @@ package cc.mrbird.febs.ai.strategy.Impl; import cc.mrbird.febs.ai.enumerates.AiTypeEnum; import cc.mrbird.febs.ai.req.agent.AiRequestDto; import cc.mrbird.febs.ai.strategy.LlmStrategyService; import cc.mrbird.febs.ai.strategy.enumerates.LlmApplicationAppIdEnum; import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum; @@ -255,4 +256,9 @@ throw new FebsException(StrUtil.format("百炼工作流输出失败:{}",error)); }); } @Override public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto) { return null; } } src/main/java/cc/mrbird/febs/ai/strategy/Impl/AliLlmStrategyServiceImpl.java
@@ -1,21 +1,26 @@ package cc.mrbird.febs.ai.strategy.Impl; import cc.mrbird.febs.ai.req.agent.AiRequestDto; 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 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.stereotype.Component; import reactor.core.publisher.Flux; @@ -24,14 +29,21 @@ import java.util.HashMap; import java.util.List; @Slf4j @Component("AliLlmStrategyService") public class AliLlmStrategyServiceImpl implements LlmStrategyService { private GenerationParam generationParam; private static final String apiKey = "sk-babdcf8799144134915cee2683794b2f"; private static final String apiKey = "sk-a2323eba1e584066b3a536aefa804970"; private static final String model = "qwen-plus"; // private static final String model = "qwen3-14b-ft-202509031002-7446"; private ApplicationParam applicationParam; private ApplicationParam applicationParamSummary; private static final String appId = "a5d38240f6b94da6b7f1f7fbe563f50c"; private static final String SummaryAppId = "19da84392c534db5b2e3f10e698758ab"; @PostConstruct public void init() { @@ -41,6 +53,18 @@ // 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models .model(model) .resultFormat(GenerationParam.ResultFormat.MESSAGE) .build(); this.applicationParam = ApplicationParam.builder() // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。 .apiKey(apiKey) .appId(appId) .build(); this.applicationParamSummary = ApplicationParam.builder() // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。 .apiKey(apiKey) .appId(SummaryAppId) .build(); } @@ -175,4 +199,91 @@ throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",error)); }); } @Override public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto dto) { long startTime = System.currentTimeMillis(); if (ObjectUtil.isEmpty(dto)){ throw new FebsException("参数异常"); } String talkId = dto.getTalkId(); String rolePrompt = dto.getRolePrompt(); List<Message> messages = dto.getMessages(); HashMap<String, Object> userPromptParams = new HashMap<>(); userPromptParams.put("role_prompt", rolePrompt); if(CollUtil.isNotEmpty( messages)){ userPromptParams.put("message_list", messages); } HashMap<String, Object> bizParams = new HashMap<>(); bizParams.put("user_prompt_params", userPromptParams); List<String> knowledgeIds = dto.getKnowledgeIds(); List<String> 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<ApplicationResult> result; try { result = application.streamCall(applicationParam); } catch (NoApiKeyException | InputRequiredException e) { throw new FebsException(StrUtil.format("百炼大模型输出失败:{}",e.getMessage())); } return Flux.from(result) .map(message -> { HashMap<String, Object> 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<ApplicationUsage.ModelUsage> 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); stringStringHashMap.put("inputTokens:",inputTokens); stringStringHashMap.put("outputTokens:",outputTokens); stringStringHashMap.put(LlmStrategyContextEnum.CONTENT.name(),message.getOutput().getText()); } 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,5 +1,6 @@ package cc.mrbird.febs.ai.strategy.Impl; import cc.mrbird.febs.ai.req.agent.AiRequestDto; import cc.mrbird.febs.ai.strategy.LlmStrategyService; import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyContextEnum; import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; @@ -201,4 +202,9 @@ throw new FebsException(StrUtil.format("火山大模型流式调用AI服务失:{}",throwable)); }); } @Override public Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto) { return null; } } src/main/java/cc/mrbird/febs/ai/strategy/LlmStrategyService.java
@@ -1,5 +1,6 @@ package cc.mrbird.febs.ai.strategy; import cc.mrbird.febs.ai.req.agent.AiRequestDto; import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; import cc.mrbird.febs.common.entity.FebsResponse; import reactor.core.publisher.Flux; @@ -13,4 +14,6 @@ Flux<FebsResponse> llmInvokeStreamingWithThink(List<LlmStrategyDto> dto); Flux<FebsResponse> llmInvokeStreamingNoThink(List<LlmStrategyDto> dto); Flux<FebsResponse> llmInvokeStreamingNoThink(AiRequestDto aiRequestDto); }