# 流式输出
流式输出可以让 AI 的回复像打字一样逐字显示,而不是等全部生成完才展示,显著提升用户体验。
# 基本用法
使用 streamText() 进行流式调用,通过 textStream 逐步获取文本:
const model = wx.cloud.extend.AI.createModel("cloudbase");
const res = await model.streamText({
data: {
model: "hy3-preview",
messages: [{role: "user", content: "介绍一下云开发"}],
},
});
let fullText = "";
for await (const text of res.textStream) {
fullText += text;
console.log("当前文本:", fullText);
}
# 在小程序中实时更新 UI
流式输出的核心场景是实时更新页面显示:
Page({
data: {
answer: "",
isLoading: false,
},
async askAI() {
this.setData({ answer: "", isLoading: true });
try {
const model = wx.cloud.extend.AI.createModel("cloudbase");
const res = await model.streamText({
data: {
model: "hy3-preview",
messages: [{ role: "user", content: "写一首关于春天的诗" }],
},
});
let answer = "";
for await (const text of res.textStream) {
answer += text;
this.setData({ answer });
}
} catch (error) {
console.error("调用失败:", error);
} finally {
this.setData({ isLoading: false });
}
},
});
对应的 WXML:
<view class="container">
<view class="answer">{{answer}}</view>
<button bindtap="askAI" disabled="{{isLoading}}">
{{isLoading ? '生成中...' : '开始生成'}}
</button>
</view>
# 使用 eventStream 获取完整数据
textStream 只返回文本片段,如果需要获取完整的 SSE 事件数据(如 token 使用量、finish_reason 等),使用 eventStream:
const res = await model.streamText({
data: {
model: "hy3-preview",
messages: [{ role: "user", content: "你好" }],
},
});
for await (const event of res.eventStream) {
if (event.data === "[DONE]") {
console.log("流式传输结束");
break;
}
const data = JSON.parse(event.data);
const delta = data.choices[0]?.delta;
if (delta?.content) {
console.log("文本片段:", delta.content);
}
}
# 检测流结束
for await (const text of res.textStream) {
console.log(text);
}
// textStream 循环结束后,流式传输已完成
console.log("流式传输结束");
或者通过 eventStream 检测 [DONE] 信号:
for await (const event of res.eventStream) {
if (event.data === "[DONE]") {
break;
}
}
# 超时处理
流式调用耗时较长,建议在 app.json 中配置全局超时时间:
{
"networkTimeout": {
"request": 600000
}
}
# 注意事项
textStream和eventStream不能同时消费:一个响应只能选择其中一种方式读取- setData 频率:小程序的
setData频率过高可能影响性能,可考虑合并多次文本片段后再更新 - 用户中断:用户离开页面时,流式请求仍会继续,建议在
onUnload中处理