Commit 63c5f90596bcdd66e735a6559721c1f5a670388c

Authored by cherishsince
1 parent 2ef64a0a

【优化】兼容阿里云千问开源模型,和付费模型

yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java
@@ -4,13 +4,14 @@ import cn.iocoder.yudao.framework.ai.chat.*; @@ -4,13 +4,14 @@ import cn.iocoder.yudao.framework.ai.chat.*;
4 import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; 4 import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions;
5 import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; 5 import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt;
6 import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi; 6 import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi;
7 -import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenChatCompletionRequest;  
8 import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException; 7 import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException;
9 import com.alibaba.dashscope.aigc.generation.GenerationResult; 8 import com.alibaba.dashscope.aigc.generation.GenerationResult;
10 import com.alibaba.dashscope.aigc.generation.models.QwenParam; 9 import com.alibaba.dashscope.aigc.generation.models.QwenParam;
11 import com.alibaba.dashscope.common.Message; 10 import com.alibaba.dashscope.common.Message;
  11 +import com.google.common.collect.Lists;
12 import io.reactivex.Flowable; 12 import io.reactivex.Flowable;
13 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
  14 +import org.jetbrains.annotations.NotNull;
14 import org.springframework.http.ResponseEntity; 15 import org.springframework.http.ResponseEntity;
15 import org.springframework.retry.RetryCallback; 16 import org.springframework.retry.RetryCallback;
16 import org.springframework.retry.RetryContext; 17 import org.springframework.retry.RetryContext;
@@ -71,7 +72,7 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { @@ -71,7 +72,7 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient {
71 return this.retryTemplate.execute(ctx -> { 72 return this.retryTemplate.execute(ctx -> {
72 // ctx 会有重试的信息 73 // ctx 会有重试的信息
73 // 创建 request 请求,stream模式需要供应商支持 74 // 创建 request 请求,stream模式需要供应商支持
74 - QianWenChatCompletionRequest request = this.createRequest(prompt, false); 75 + QwenParam request = this.createRequest(prompt, false);
75 // 调用 callWithFunctionSupport 发送请求 76 // 调用 callWithFunctionSupport 发送请求
76 ResponseEntity<GenerationResult> responseEntity = qianWenApi.chatCompletionEntity(request); 77 ResponseEntity<GenerationResult> responseEntity = qianWenApi.chatCompletionEntity(request);
77 // 获取结果封装 chatCompletion 78 // 获取结果封装 chatCompletion
@@ -81,11 +82,41 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { @@ -81,11 +82,41 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient {
81 // response.getRequestId(), response.getCode(), response.getMessage())))); 82 // response.getRequestId(), response.getCode(), response.getMessage()))));
82 // } 83 // }
83 // 转换为 Generation 返回 84 // 转换为 Generation 返回
84 - return new ChatResponse(List.of(new Generation(response.getOutput().getText()))); 85 + return new ChatResponse(response.getOutput().getChoices().stream()
  86 + .map(choices -> new Generation(choices.getMessage().getContent()))
  87 + .collect(Collectors.toList()));
85 }); 88 });
86 } 89 }
87 90
88 - private QianWenChatCompletionRequest createRequest(Prompt prompt, boolean stream) { 91 + private QwenParam createRequest(Prompt prompt, boolean stream) {
  92 + // 获取 ChatOptions
  93 + QianWenOptions chatOptions = getChatOptions(prompt);
  94 + //
  95 + List<Message> messageList = Lists.newArrayList();
  96 + prompt.getInstructions().stream().forEach(instruction -> {
  97 + Message message = new Message();
  98 + message.setRole(instruction.getMessageType().getValue());
  99 + message.setContent(instruction.getContent());
  100 + messageList.add(message);
  101 + });
  102 + return QwenParam.builder()
  103 + .model(qianWenApi.getQianWenChatModal().getValue())
  104 + .prompt(prompt.getContents())
  105 + .messages(messageList)
  106 + .maxTokens(chatOptions.getMaxTokens())
  107 + .resultFormat(QwenParam.ResultFormat.MESSAGE)
  108 + .topP(Double.valueOf(chatOptions.getTopP()))
  109 + .topK(chatOptions.getTopK())
  110 + .temperature(chatOptions.getTemperature())
  111 + // 控制流式输出模式,即后面的内容会包含已经输出的内容;设置为True,将开启增量输出模式,后面的输出不会包含已经输出的内容,您需要自行拼接整体输出
  112 + .incrementalOutput(true)
  113 + /* set the random seed, optional, default to 1234 if not set */
  114 + .seed(100)
  115 + .apiKey(qianWenApi.getApiKey())
  116 + .build();
  117 + }
  118 +
  119 + private @NotNull QianWenOptions getChatOptions(Prompt prompt) {
89 // 两个都为null 则没有配置文件 120 // 两个都为null 则没有配置文件
90 if (qianWenOptions == null && prompt.getOptions() == null) { 121 if (qianWenOptions == null && prompt.getOptions() == null) {
91 throw new ChatException("ChatOptions 未配置参数!"); 122 throw new ChatException("ChatOptions 未配置参数!");
@@ -96,37 +127,27 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { @@ -96,37 +127,27 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient {
96 options = (ChatOptions) prompt.getOptions(); 127 options = (ChatOptions) prompt.getOptions();
97 } 128 }
98 // Prompt 里面是一个 ChatOptions,用户可以随意传入,这里做一下判断 129 // Prompt 里面是一个 ChatOptions,用户可以随意传入,这里做一下判断
99 - if (!(options instanceof QianWenOptions qianWenOptions)) { 130 + if (!(options instanceof QianWenOptions)) {
100 throw new ChatException("Prompt 传入的不是 QianWenOptions!"); 131 throw new ChatException("Prompt 传入的不是 QianWenOptions!");
101 } 132 }
102 - return (QianWenChatCompletionRequest) QianWenChatCompletionRequest.builder()  
103 - .model(qianWenApi.getQianWenChatModal().getValue())  
104 - .apiKey(qianWenApi.getApiKey())  
105 - .messages(prompt.getInstructions().stream().map(m -> {  
106 - Message message = new Message();  
107 - message.setRole(m.getMessageType().getValue());  
108 - message.setContent(m.getContent());  
109 - return message;  
110 - }).collect(Collectors.toList()))  
111 - .resultFormat(QwenParam.ResultFormat.MESSAGE)  
112 - // 动态改变的三个参数  
113 - .topP(Double.valueOf(qianWenOptions.getTopP()))  
114 - .topK(qianWenOptions.getTopK())  
115 - .temperature(qianWenOptions.getTemperature())  
116 - .incrementalOutput(true)  
117 - .build(); 133 + return (QianWenOptions) options;
118 } 134 }
119 135
120 @Override 136 @Override
121 public Flux<ChatResponse> stream(Prompt prompt) { 137 public Flux<ChatResponse> stream(Prompt prompt) {
122 // ctx 会有重试的信息 138 // ctx 会有重试的信息
123 // 创建 request 请求,stream模式需要供应商支持 139 // 创建 request 请求,stream模式需要供应商支持
124 - QianWenChatCompletionRequest request = this.createRequest(prompt, true); 140 + QwenParam request = this.createRequest(prompt, true);
125 // 调用 callWithFunctionSupport 发送请求 141 // 调用 callWithFunctionSupport 发送请求
126 Flowable<GenerationResult> responseResult = this.qianWenApi.chatCompletionStream(request); 142 Flowable<GenerationResult> responseResult = this.qianWenApi.chatCompletionStream(request);
  143 +
127 return Flux.create(fluxSink -> 144 return Flux.create(fluxSink ->
128 responseResult.subscribe( 145 responseResult.subscribe(
129 - value -> fluxSink.next(new ChatResponse(List.of(new Generation(value.getOutput().getText())))), 146 + value -> fluxSink.next(
  147 + new ChatResponse(value.getOutput().getChoices().stream()
  148 + .map(choices -> new Generation(choices.getMessage().getContent()))
  149 + .collect(Collectors.toList()))
  150 + ),
130 error -> fluxSink.error(error), 151 error -> fluxSink.error(error),
131 () -> fluxSink.complete() 152 () -> fluxSink.complete()
132 ) 153 )
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenOptions.java
@@ -15,7 +15,7 @@ import java.util.List; @@ -15,7 +15,7 @@ import java.util.List;
15 * time: 2024/3/15 19:57 15 * time: 2024/3/15 19:57
16 */ 16 */
17 @Data 17 @Data
18 -@Accessors 18 +@Accessors(chain = true)
19 public class QianWenOptions implements ChatOptions { 19 public class QianWenOptions implements ChatOptions {
20 20
21 /** 21 /**
@@ -28,6 +28,10 @@ public class QianWenOptions implements ChatOptions { @@ -28,6 +28,10 @@ public class QianWenOptions implements ChatOptions {
28 * 默认值为0.8。注意,取值不要大于等于1 28 * 默认值为0.8。注意,取值不要大于等于1
29 */ 29 */
30 private Float topP; 30 private Float topP;
  31 + /**
  32 + * 用于限制模型生成token的数量,max_tokens设置的是生成上限,并不表示一定会生成这么多的token数量。其中qwen1.5-14b-chat、qwen1.5-7b-chat、qwen-14b-chat和qwen-7b-chat最大值和默认值均为1500,qwen-1.8b-chat、qwen-1.8b-longcontext-chat和qwen-72b-chat最大值和默认值均为2000
  33 + */
  34 + private Integer maxTokens = 1500;
31 35
32 // 36 //
33 // 适配 ChatOptions 37 // 适配 ChatOptions
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal;
4 import cn.iocoder.yudao.framework.ai.exception.AiException; 4 import cn.iocoder.yudao.framework.ai.exception.AiException;
5 import com.alibaba.dashscope.aigc.generation.Generation; 5 import com.alibaba.dashscope.aigc.generation.Generation;
6 import com.alibaba.dashscope.aigc.generation.GenerationResult; 6 import com.alibaba.dashscope.aigc.generation.GenerationResult;
  7 +import com.alibaba.dashscope.aigc.generation.models.QwenParam;
7 import com.alibaba.dashscope.common.Message; 8 import com.alibaba.dashscope.common.Message;
8 import com.alibaba.dashscope.common.Role; 9 import com.alibaba.dashscope.common.Role;
9 import com.alibaba.dashscope.exception.InputRequiredException; 10 import com.alibaba.dashscope.exception.InputRequiredException;
@@ -34,9 +35,7 @@ public class QianWenApi { @@ -34,9 +35,7 @@ public class QianWenApi {
34 this.qianWenChatModal = qianWenChatModal; 35 this.qianWenChatModal = qianWenChatModal;
35 } 36 }
36 37
37 - public ResponseEntity<GenerationResult> chatCompletionEntity(QianWenChatCompletionRequest request) {  
38 - Message userMsg = Message.builder().role(Role.USER.getValue()).content("用萝卜、土豆、茄子做饭,给我个菜谱").build();  
39 - 38 + public ResponseEntity<GenerationResult> chatCompletionEntity(QwenParam request) {
40 GenerationResult call; 39 GenerationResult call;
41 try { 40 try {
42 call = gen.call(request); 41 call = gen.call(request);
@@ -49,7 +48,7 @@ public class QianWenApi { @@ -49,7 +48,7 @@ public class QianWenApi {
49 return new ResponseEntity<>(call, HttpStatusCode.valueOf(200)); 48 return new ResponseEntity<>(call, HttpStatusCode.valueOf(200));
50 } 49 }
51 50
52 - public Flowable<GenerationResult> chatCompletionStream(QianWenChatCompletionRequest request) { 51 + public Flowable<GenerationResult> chatCompletionStream(QwenParam request) {
53 Flowable<GenerationResult> resultFlowable; 52 Flowable<GenerationResult> resultFlowable;
54 try { 53 try {
55 resultFlowable = gen.streamCall(request); 54 resultFlowable = gen.streamCall(request);
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
@@ -47,6 +47,7 @@ public class YudaoAiAutoConfiguration { @@ -47,6 +47,7 @@ public class YudaoAiAutoConfiguration {
47 QianWenOptions qianWenOptions = new QianWenOptions(); 47 QianWenOptions qianWenOptions = new QianWenOptions();
48 qianWenOptions.setTopK(qianWenProperties.getTopK()); 48 qianWenOptions.setTopK(qianWenProperties.getTopK());
49 qianWenOptions.setTopP(qianWenProperties.getTopP()); 49 qianWenOptions.setTopP(qianWenProperties.getTopP());
  50 + qianWenOptions.setMaxTokens(qianWenProperties.getMaxTokens());
50 qianWenOptions.setTemperature(qianWenProperties.getTemperature()); 51 qianWenOptions.setTemperature(qianWenProperties.getTemperature());
51 return new QianWenChatClient( 52 return new QianWenChatClient(
52 new QianWenApi( 53 new QianWenApi(
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
@@ -48,6 +48,10 @@ public class YudaoAiProperties { @@ -48,6 +48,10 @@ public class YudaoAiProperties {
48 */ 48 */
49 private String apiKey; 49 private String apiKey;
50 /** 50 /**
  51 + * 用于限制模型生成token的数量,max_tokens设置的是生成上限,并不表示一定会生成这么多的token数量
  52 + */
  53 + private Integer maxTokens;
  54 + /**
51 * model 55 * model
52 */ 56 */
53 private YiYanChatModel model; 57 private YiYanChatModel model;
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java
1 package cn.iocoder.yudao.framework.ai.chat; 1 package cn.iocoder.yudao.framework.ai.chat;
2 2
  3 +import cn.iocoder.yudao.framework.ai.chat.messages.SystemMessage;
  4 +import cn.iocoder.yudao.framework.ai.chat.messages.UserMessage;
3 import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; 5 import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt;
4 -import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi;  
5 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient; 6 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient;
  7 +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal;
6 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions; 8 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions;
  9 +import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi;
  10 +import com.alibaba.dashscope.aigc.generation.GenerationResult;
  11 +import com.alibaba.dashscope.aigc.generation.models.QwenParam;
  12 +import com.alibaba.dashscope.common.Message;
  13 +import com.alibaba.dashscope.common.MessageManager;
  14 +import com.alibaba.dashscope.common.Role;
  15 +import com.alibaba.dashscope.exception.InputRequiredException;
  16 +import com.alibaba.dashscope.exception.NoApiKeyException;
7 import org.junit.Before; 17 import org.junit.Before;
8 import org.junit.Test; 18 import org.junit.Test;
9 import reactor.core.publisher.Flux; 19 import reactor.core.publisher.Flux;
10 20
  21 +import java.util.ArrayList;
  22 +import java.util.List;
11 import java.util.Scanner; 23 import java.util.Scanner;
12 import java.util.function.Consumer; 24 import java.util.function.Consumer;
13 25
@@ -21,28 +33,34 @@ public class QianWenChatClientTests { @@ -21,28 +33,34 @@ public class QianWenChatClientTests {
21 33
22 @Before 34 @Before
23 public void setup() { 35 public void setup() {
24 - QianWenApi qianWenApi = new QianWenApi(  
25 - "LTAI5tNTVhXW4fLKUjMrr98z",  
26 - "ZJ0JQeyjzxxm5CfeTV6k1wNE9UsvZP",  
27 - "f0c1088824594f589c8f10567ccd929f_p_efm",  
28 - null  
29 - ); 36 + QianWenApi qianWenApi = new QianWenApi("sk-Zsd81gZYg7", QianWenChatModal.QWEN_72B_CHAT);
  37 + QianWenOptions qianWenOptions = new QianWenOptions();
  38 + qianWenOptions.setTopP(0.8F);
  39 + qianWenOptions.setTopK(3);
  40 + qianWenOptions.setTemperature(0.6F);
30 qianWenChatClient = new QianWenChatClient( 41 qianWenChatClient = new QianWenChatClient(
31 qianWenApi, 42 qianWenApi,
32 - new QianWenOptions()  
33 - .setAppId("5f14955f201a44eb8dbe0c57250a32ce") 43 + qianWenOptions
34 ); 44 );
35 } 45 }
36 46
37 @Test 47 @Test
38 public void callTest() { 48 public void callTest() {
39 - ChatResponse call = qianWenChatClient.call(new Prompt("Java语言怎么样?")); 49 + List<cn.iocoder.yudao.framework.ai.chat.messages.Message> messages = new ArrayList<>();
  50 + messages.add(new SystemMessage("你是一个优质的小红书文艺作者,抒写着各城市的美好文化和风景。"));
  51 + messages.add(new UserMessage("长沙怎么样?"));
  52 +
  53 + ChatResponse call = qianWenChatClient.call(new Prompt(messages));
40 System.err.println(call.getResult()); 54 System.err.println(call.getResult());
41 } 55 }
42 56
43 @Test 57 @Test
44 public void streamTest() { 58 public void streamTest() {
45 - Flux<ChatResponse> flux = qianWenChatClient.stream(new Prompt("Java语言怎么样?")); 59 + List<cn.iocoder.yudao.framework.ai.chat.messages.Message> messages = new ArrayList<>();
  60 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  61 + messages.add(new UserMessage("长沙怎么样?"));
  62 +
  63 + Flux<ChatResponse> flux = qianWenChatClient.stream(new Prompt(messages));
46 flux.subscribe(new Consumer<ChatResponse>() { 64 flux.subscribe(new Consumer<ChatResponse>() {
47 @Override 65 @Override
48 public void accept(ChatResponse chatResponse) { 66 public void accept(ChatResponse chatResponse) {
@@ -54,4 +72,32 @@ public class QianWenChatClientTests { @@ -54,4 +72,32 @@ public class QianWenChatClientTests {
54 Scanner scanner = new Scanner(System.in); 72 Scanner scanner = new Scanner(System.in);
55 scanner.nextLine(); 73 scanner.nextLine();
56 } 74 }
  75 +
  76 + @Test
  77 + public void qianwenDemoTest() throws NoApiKeyException, InputRequiredException {
  78 + com.alibaba.dashscope.aigc.generation.Generation gen = new com.alibaba.dashscope.aigc.generation.Generation();
  79 + MessageManager msgManager = new MessageManager(10);
  80 + Message systemMsg =
  81 + Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
  82 + Message userMsg = Message.builder().role(Role.USER.getValue()).content("就当前的海洋污染的情况,写一份限塑的倡议书提纲,需要有理有据地号召大家克制地使用塑料制品").build();
  83 + msgManager.add(systemMsg);
  84 + msgManager.add(userMsg);
  85 + QwenParam param =
  86 + QwenParam.builder().model("qwen-72b-chat").messages(msgManager.get())
  87 + .resultFormat(QwenParam.ResultFormat.MESSAGE)
  88 + .topP(0.8)
  89 + /* set the random seed, optional, default to 1234 if not set */
  90 + .seed(100)
  91 + .apiKey("sk-Zsd81gZYg7")
  92 + .build();
  93 + GenerationResult result = gen.call(param);
  94 + System.out.println(result);
  95 + System.out.println("-----------------");
  96 + System.out.println("-----------------");
  97 + msgManager.add(result);
  98 + param.setPrompt("能否缩短一些,只讲三点");
  99 + param.setMessages(msgManager.get());
  100 + result = gen.call(param);
  101 + System.out.println(result);
  102 + }
57 } 103 }
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/midjourney/MidjourneyInteractionsTests.java
@@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.ai.midjourney.api.req.AttachmentsReq; @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.ai.midjourney.api.req.AttachmentsReq;
6 import cn.iocoder.yudao.framework.ai.midjourney.api.req.DescribeReq; 6 import cn.iocoder.yudao.framework.ai.midjourney.api.req.DescribeReq;
7 import cn.iocoder.yudao.framework.ai.midjourney.api.req.ReRollReq; 7 import cn.iocoder.yudao.framework.ai.midjourney.api.req.ReRollReq;
8 import cn.iocoder.yudao.framework.ai.midjourney.api.res.UploadAttachmentsRes; 8 import cn.iocoder.yudao.framework.ai.midjourney.api.res.UploadAttachmentsRes;
9 -import com.alibaba.fastjson.JSON; 9 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
10 import org.junit.Before; 10 import org.junit.Before;
11 import org.junit.Test; 11 import org.junit.Test;
12 import org.springframework.core.io.FileSystemResource; 12 import org.springframework.core.io.FileSystemResource;
@@ -58,7 +58,7 @@ public class MidjourneyInteractionsTests { @@ -58,7 +58,7 @@ public class MidjourneyInteractionsTests {
58 new AttachmentsReq().setFileSystemResource( 58 new AttachmentsReq().setFileSystemResource(
59 new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG"))) 59 new FileSystemResource(new File("/Users/fansili/Downloads/DSC01402.JPG")))
60 ); 60 );
61 - System.err.println(JSON.toJSONString(res)); 61 + System.err.println(JsonUtils.toJsonString(res));
62 } 62 }
63 63
64 @Test 64 @Test
yudao-server/src/main/resources/application-local.yaml
@@ -228,14 +228,11 @@ yudao: @@ -228,14 +228,11 @@ yudao:
228 qianwen: 228 qianwen:
229 enable: true 229 enable: true
230 aiPlatform: QIAN_WEN 230 aiPlatform: QIAN_WEN
231 - temperature: 1  
232 - topP: 1  
233 - topK: 1  
234 - endpoint: bailian.cn-beijing.aliyuncs.com  
235 - accessKeyId: LTAI5tNTVhXW4fLKUjMrr98z  
236 - accessKeySecret: ZJ0JQeyjzxxm5CfeTV6k1wNE9UsvZP  
237 - agentKey: f0c1088824594f589c8f10567ccd929f_p_efm  
238 - appId: 5f14955f201a44eb8dbe0c57250a32ce 231 + temperature: 0.85
  232 + topP: 0.8
  233 + topK: 0
  234 + api-key: sk-Zsd81gZYg7
  235 + max-tokens: 1500
239 xinghuo: 236 xinghuo:
240 enable: true 237 enable: true
241 aiPlatform: XING_HUO 238 aiPlatform: XING_HUO