Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] : add SparkDesk Ai #2185

Merged
merged 13 commits into from
Jul 5, 2024
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:
Loading