Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-ai
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-ai
Commits
0cc30bdf
Commit
0cc30bdf
authored
Apr 01, 2026
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
6ea71055
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
17 additions
and
59 deletions
+17
-59
yd-ai-api/src/main/java/com/yd/ai/api/controller/ApiAiStreamController.java
+17
-59
No files found.
yd-ai-api/src/main/java/com/yd/ai/api/controller/ApiAiStreamController.java
View file @
0cc30bdf
...
...
@@ -8,7 +8,6 @@ import com.alibaba.dashscope.common.Role;
import
com.alibaba.dashscope.exception.InputRequiredException
;
import
com.alibaba.dashscope.exception.NoApiKeyException
;
import
io.reactivex.Flowable
;
import
lombok.var
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.codec.ServerSentEvent
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -22,72 +21,30 @@ public class ApiAiStreamController {
@CrossOrigin
(
origins
=
"*"
)
// 开发时允许跨域
@GetMapping
(
value
=
"/stream"
,
produces
=
MediaType
.
TEXT_EVENT_STREAM_VALUE
)
public
Flux
<
ServerSentEvent
<
String
>>
streamChat
(
@RequestParam
String
question
)
{
if
(
question
==
null
||
question
.
trim
().
isEmpty
())
{
return
Flux
.
error
(
new
IllegalArgumentException
(
"question cannot be empty"
));
}
// 优化系统提示词,强制输出标准 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
();
Generation
gen
=
new
Generation
();
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
();
GenerationParam
param
=
GenerationParam
.
builder
()
.
apiKey
(
"sk-d6551c67cfbe4a759a78dc3625729291"
)
.
model
(
"qwen-plus"
)
.
messages
(
Arrays
.
asList
(
systemMsg
,
userMsg
))
.
resultFormat
(
GenerationParam
.
ResultFormat
.
MESSAGE
)
.
incrementalOutput
(
true
)
.
temperature
(
0.5f
)
// 降低温度使输出更稳定
.
build
();
Generation
gen
=
new
Generation
();
// 使用 defer 延迟执行,避免 flowable 为 null
return
Flux
.
from
(
Flowable
.
defer
(()
->
{
try
{
return
gen
.
streamCall
(
param
);
}
catch
(
NoApiKeyException
e
)
{
return
Flowable
.
error
(
new
RuntimeException
(
"API Key missing"
,
e
));
}
catch
(
InputRequiredException
e
)
{
return
Flowable
.
error
(
new
RuntimeException
(
"Invalid input"
,
e
));
}
catch
(
Exception
e
)
{
return
Flowable
.
error
(
new
RuntimeException
(
"DashScope call failed"
,
e
));
}
}))
Flowable
<
GenerationResult
>
flowable
=
null
;
try
{
flowable
=
gen
.
streamCall
(
param
);
}
catch
(
NoApiKeyException
e
)
{
e
.
printStackTrace
();
}
catch
(
InputRequiredException
e
)
{
e
.
printStackTrace
();
}
// 将 RxJava Flowable 转为 Reactor Flux
return
Flux
.
from
(
flowable
)
.
map
(
result
->
{
String
delta
=
""
;
if
(
result
.
getOutput
()
!=
null
&&
!
result
.
getOutput
().
getChoices
().
isEmpty
())
{
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
())
);
String
delta
=
result
.
getOutput
().
getChoices
().
get
(
0
).
getMessage
().
getContent
();
return
ServerSentEvent
.
builder
(
delta
).
build
();
});
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment