> 技术文档 > 微信小程序AI大模型流式输出实践与总结_微信小程序流式输出

微信小程序AI大模型流式输出实践与总结_微信小程序流式输出


背景

让Cursor生成小程序中大模型调用内容回复的流式输出时一直有问题,参考整理此文章。
参考原文:https://blog.csdn.net/weixin_47684422/article/details/145859543


一、什么是流式传输?

流式传输(Streaming)指的是将数据分为若干段(chunk),边生成边发送,客户端则边接收边处理。常见于视频播放、音频播放、AI对话等场景。其优点包括:

  • 降低延迟,提升响应速度
  • 支持大数据量分段处理
  • 改善用户体验(如AI逐字回复)

二、微信小程序中的流式传输方案

1. 微信小程序的限制

  • 无fetch:小程序没有浏览器的fetch接口,不能直接用Response.body.getReader()流式读取。
  • WebSocket不适用于所有后端:部分AI接口只支持HTTP流,不支持WebSocket。

2. 官方能力:onChunkReceived

微信小程序自基础库2.23.0起,wx.request新增了enableChunked参数和onChunkReceived回调,支持HTTP分块(chunked)传输。

要点:

  • enableChunked: true 开启流式传输
  • 监听onChunkReceived获取每一块数据
  • 需自行拼接与处理数据内容

三、代码实现

1. 发起流式请求

const requestTask = wx.request({ url: `${config.baseUrl}/ai/deepSeek`, header: { \"X-Access-Token\": wx.getStorageSync(\"token\"), }, data: JSON.stringify({ question: this.question, appId: config.APP_ID, userName: \'xxx\' }), method: \"POST\", enableChunked: true, // 开启流式传输 responseType: \"arraybuffer\", // 推荐使用arraybuffer,兼容性更好});// 监听分块数据if (requestTask?.onChunkReceived) { requestTask.onChunkReceived(this.handleChunkData);} else { // 不支持流式,降级为普通请求 this.normalRequest();}

2. 分块数据处理

handleChunkData(res) { try { // 微信小程序ArrayBuffer转字符串 let rawStr = Array.from(new Uint8Array(res.data)) .map(byte => String.fromCharCode(byte)) .join(\"\"); // 处理中文乱码 rawStr = unescape(encodeURIComponent(rawStr)); // 提取JSON内容 const chunkJson = rawStr.split(\"data: \")[1]; const rawData = JSON.parse(chunkJson); // 提取AI回复内容 const text = rawData.choices?.[0]?.delta?.content; // 过滤无用内容(如标签) if (text === \"\") { this.isThink = false; } if (!this.isThink) { const tx = text.replace(\"\", \"\"); this.streamBuffer += tx; // 实时渲染(可用markdown-it等库转换) const answer = this.list[this.list.length - 1]; answer.content = markdown.render(this.streamBuffer); // 节流更新页面 this.throttleUpdate(); } } catch (e) { console.error(\"数据处理异常:\", e); }},

3. 辅助方法

// 节流更新,防止频繁渲染影响性能throttleUpdate() { if (!this.updateTimer) { this.updateTimer = setTimeout(() => { this.$forceUpdate(); this.scrollToBottom(); this.updateTimer = null; }, 500); }}

四、注意事项与优化建议

  1. 字段结束标识:小程序没有onReceivedEnd事件,无法直接判断流式内容是否结束。建议后端返回特殊标识(如[DONE])或协议字段,前端据此判断。
  2. 中文兼容性:ArrayBuffer转字符串时,注意处理中文编码问题,推荐用TextDecoderunescape(encodeURIComponent(...))方法。
  3. 性能优化:流式内容更新频繁,建议节流更新页面,避免卡顿。
  4. uniapp注意:如用uniapp,必须用wx.requestuni.request不支持chunked流。
  5. 内容过滤:部分大模型(如deepSeek)返回的内容含有think标签等无用数据,需按业务过滤。