Commit 0cc30bdf by zhangxingmin

push

parent 6ea71055
...@@ -8,7 +8,6 @@ import com.alibaba.dashscope.common.Role; ...@@ -8,7 +8,6 @@ import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable; import io.reactivex.Flowable;
import lombok.var;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent; import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -22,72 +21,30 @@ public class ApiAiStreamController { ...@@ -22,72 +21,30 @@ public class ApiAiStreamController {
@CrossOrigin(origins = "*") // 开发时允许跨域 @CrossOrigin(origins = "*") // 开发时允许跨域
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> streamChat(@RequestParam String question) { public Flux<ServerSentEvent<String>> streamChat(@RequestParam String question) {
if (question == null || question.trim().isEmpty()) { Generation gen = new Generation();
return Flux.error(new IllegalArgumentException("question cannot be empty")); Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
} Message userMsg = Message.builder().role(Role.USER.getValue()).content(question).build();
// 优化系统提示词,强制输出标准 Markdown 表格
Message systemMsg = Message.builder()
.role(Role.SYSTEM.getValue())
.content("你是一个专业的AI助手。请使用标准Markdown格式回答,尤其是表格必须满足以下规范:\n" +
"1. 表格由表头行、分隔行、数据行组成,前后各留一个空行。\n" +
"2. 分隔行仅由竖线(|)、连字符(-)和冒号(:)构成,例如 | --- | --- |。\n" +
"3. 表格的每一行列数必须相同,不允许列数不一致。\n" +
"4. 禁止输出非标准的表格结构(如用文本模拟表格)。\n" +
"5. 如果表格内容复杂,请用列表或段落替代。")
.build();
Message userMsg = Message.builder()
.role(Role.USER.getValue())
.content(question)
.build();
GenerationParam param = GenerationParam.builder() GenerationParam param = GenerationParam.builder()
.apiKey("sk-d6551c67cfbe4a759a78dc3625729291") .apiKey("sk-d6551c67cfbe4a759a78dc3625729291")
.model("qwen-plus") .model("qwen-plus")
.messages(Arrays.asList(systemMsg, userMsg)) .messages(Arrays.asList(systemMsg, userMsg))
.resultFormat(GenerationParam.ResultFormat.MESSAGE) .resultFormat(GenerationParam.ResultFormat.MESSAGE)
.incrementalOutput(true) .incrementalOutput(true)
.temperature(0.5f) // 降低温度使输出更稳定
.build(); .build();
Generation gen = new Generation(); Flowable<GenerationResult> flowable = null;
try {
// 使用 defer 延迟执行,避免 flowable 为 null flowable = gen.streamCall(param);
return Flux.from(Flowable.defer(() -> { } catch (NoApiKeyException e) {
try { e.printStackTrace();
return gen.streamCall(param); } catch (InputRequiredException e) {
} catch (NoApiKeyException e) { e.printStackTrace();
return Flowable.error(new RuntimeException("API Key missing", e)); }
} catch (InputRequiredException e) { // 将 RxJava Flowable 转为 Reactor Flux
return Flowable.error(new RuntimeException("Invalid input", e)); return Flux.from(flowable)
} catch (Exception e) {
return Flowable.error(new RuntimeException("DashScope call failed", e));
}
}))
.map(result -> { .map(result -> {
String delta = ""; String delta = result.getOutput().getChoices().get(0).getMessage().getContent();
if (result.getOutput() != null && !result.getOutput().getChoices().isEmpty()) { return ServerSentEvent.builder(delta).build();
var choice = result.getOutput().getChoices().get(0); });
if (choice.getMessage() != null) {
delta = choice.getMessage().getContent();
}
}
return ServerSentEvent.<String>builder()
.event("message")
.data(delta) // 不要加 \n,让原始内容保持完整
.build();
})
.concatWith(Flux.just(
ServerSentEvent.<String>builder()
.event("complete")
.data("[DONE]")
.build()
))
.onErrorResume(error ->
Flux.just(ServerSentEvent.<String>builder()
.event("error")
.data("Error: " + error.getMessage())
.build())
);
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment