Skip to content

Commit

Permalink
[feature] : add SparkDesk Ai (#2185)
Browse files Browse the repository at this point in the history
Co-authored-by: Logic <zqr10159@dromara.org>
  • Loading branch information
Yanshuming1 and zqr10159 authored Jul 5, 2024
1 parent f3cecea commit a86fc85
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,34 @@ interface KimiAiConstants {


}

/**
* sparkDesk constants
*/
interface SparkDeskConstants {
/**
* SparkDesk Ai URL
*/
String SPARK_ULTRA_URL = "https://spark-api-open.xf-yun.com/v1/chat/completions";

/**
* request role param
*/
String REQUEST_ROLE = "user";

/**
* The model outputs the maximum tokens, with a maximum output of 8192 and a default value of 1024
*/
Integer MAX_TOKENS = 1024;

/**
* The sampling temperature, which controls the randomness of the output, must be positive
* The value ranges from 0.0 to 1.0, and cannot be equal to 0. The default value is 0.95. The larger the value,
* the more random and creative the output will be. The smaller the value, the more stable or certain the output will be
* You are advised to adjust top_p or temperature parameters based on application scenarios, but do not adjust the two parameters at the same time
*/
float TEMPERATURE = 0.95f;

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public enum AiTypeEnum {
*/
zhiPu,

/**
* sparkDesk
* 科大讯飞
*/
sparkDesk,

/**
* alibabaAi
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.manager.pojo.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* SparkDeskRequestParamDTO
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SparkDeskRequestParamDTO {

/**
* ai version
*/
private String model;

/**
* request message
*/
private List<AiMessage> messages;

/**
* The sampling temperature, which controls the randomness of the output, must be positive
* The value ranges from 0.0 to 1.0, and cannot be equal to 0. The default value is 0.95.
* The larger the value, the more random and creative the output will be. The smaller the value, the more stable or certain the output will be
* You are advised to adjust top_p or temperature parameters based on application scenarios, but do not adjust the two parameters at the same time
*/
private float temperature;

/**
* The model outputs the maximum tokens, with a maximum output of 8192 and a default value of 1024
*/
@JsonProperty("max_tokens")
private Integer maxTokens;

/**
* stream response
*/
private Boolean stream = Boolean.FALSE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.manager.pojo.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* SparkDeskResponse
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SparkDeskResponse {

/**
* Task order number generated by the AI open platform. Use this order number when invoking the request result interface
*/
private String id;

/**
* The request creation time is a Unix timestamp in seconds
*/
private Long created;

/**
* response message
*/
private List<Choice> choices;

/**
* Returns the number of tokens invoked by the model at the end.
*/
private Tokens usage;

/**
* Choice
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Choice {
private int index;
private AiMessage delta;
}

/**
* Tokens
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Tokens {

/**
* The number of tokens entered by users
*/
@JsonProperty("prompt_tokens")
private Integer promptTokens;

/**
* The number of tokens that the model outputs
*/
@JsonProperty("completion_tokens")
private Integer completionTokens;

/**
* Total number of tokens
*/
@JsonProperty("total_tokens")
private Integer totalTokens;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.manager.service.impl;

import com.alibaba.fastjson.JSON;
import java.util.List;
import java.util.Objects;
import javax.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.common.constants.AiConstants;
import org.apache.hertzbeat.common.constants.AiTypeEnum;
import org.apache.hertzbeat.manager.pojo.dto.AiMessage;
import org.apache.hertzbeat.manager.pojo.dto.SparkDeskRequestParamDTO;
import org.apache.hertzbeat.manager.pojo.dto.SparkDeskResponse;
import org.apache.hertzbeat.manager.service.AiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;


/**
* sparkDesk AI
*/
@Service("SparkDeskAiServiceImpl")
@Slf4j
public class SparkDeskAiServiceImpl implements AiService {

@Value("${aiConfig.model:generalv3.5}")
private String model;

@Value("${aiConfig.api-key}")
private String apiKey;
@Value("${aiConfig.api-secret}")
private String apiSecret;

private WebClient webClient;

@PostConstruct
private void init() {
StringBuilder sb = new StringBuilder();
String bearer = sb.append("Bearer ").append(apiKey).append(":").append(apiSecret).toString();
this.webClient = WebClient.builder()
.baseUrl(AiConstants.SparkDeskConstants.SPARK_ULTRA_URL)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.AUTHORIZATION, bearer)
.exchangeStrategies(ExchangeStrategies.builder()
.codecs(item -> item.defaultCodecs().maxInMemorySize(16 * 1024 * 1024))
.build())
.build();
}

@Override
public AiTypeEnum getType() {
return AiTypeEnum.sparkDesk;
}

@Override
public Flux<String> requestAi(String text) {

try {
checkParam(text, apiKey);
SparkDeskRequestParamDTO zhiPuRequestParamDTO = SparkDeskRequestParamDTO.builder()
.model(model)
//sse
.stream(Boolean.TRUE)
.maxTokens(AiConstants.SparkDeskConstants.MAX_TOKENS)
.temperature(AiConstants.SparkDeskConstants.TEMPERATURE)
.messages(List.of(new AiMessage(AiConstants.SparkDeskConstants.REQUEST_ROLE, text)))
.build();

return webClient.post()
.body(BodyInserters.fromValue(zhiPuRequestParamDTO))
.retrieve()
.bodyToFlux(String.class)
.filter(aiResponse -> !"[DONE]".equals(aiResponse))
.map(this::convertToResponse);
} catch (Exception e) {
log.info("SparkDeskAiServiceImpl.requestAi exception:{}", e.toString());
throw e;
}
}

private String convertToResponse(String aiRes) {
try {
SparkDeskResponse sparkDeskResponse = JSON.parseObject(aiRes, SparkDeskResponse.class);
if (Objects.nonNull(sparkDeskResponse)) {
SparkDeskResponse.Choice choice = sparkDeskResponse.getChoices().get(0);
return choice.getDelta().getContent();
}
} catch (Exception e) {
log.info("convertToResponse Exception:{}", e.toString());
}

return "";
}


private void checkParam(String param, String apiKey) {
Assert.notNull(param, "text is null");
Assert.notNull(apiKey, "aiConfig.api-key is null");
}
}
5 changes: 4 additions & 1 deletion manager/src/main/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,7 @@ aiConfig:
#Model name:glm-4
model: glm-4
#api key
api-key: xxx
api-key: xxx
#At present, only IFLYTEK large model needs to be filled in
#目前只有科大讯飞大模型需要填写
api-secret: xxx
11 changes: 7 additions & 4 deletions manager/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,12 @@ scheduler:
# AI config
# See the documentation for details : https://hertzbeat.apache.org/zh-cn/docs/help/aiConfig
aiConfig:
# AI Type:zhiPu、alibabaAi、kimiAi
# AI Type:zhiPu、alibabaAi、kimiAi、sparkDesk
type:
# Model name:glm-4、qwen-turbo、moonshot-v1-8k
model: glm-4
# Model name:glm-4、qwen-turboo、moonshot-v1-8k、generalv3.5
model:
# api key
api-key:
api-key:
#At present, only IFLYTEK large model needs to be filled in
#目前只有科大讯飞大模型需要填写
api-secret:

0 comments on commit a86fc85

Please sign in to comment.