AI SDK 流式响应本地正常但部署后失效怎么排查
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
用 AI SDK(Vercel 出品的 TypeScript AI 工具库)开发的应用在本地开发环境里流式输出正常,一旦部署,界面不再逐字显示,而是等待一段时间后一次性返回完整响应。官方排错文档将这一现象列为部署环境常见问题,并明确说明:此问题的成因多样,取决于具体部署环境,没有统一根因。本文按照部署场景给出官方文档中给出的排查路径与对应修复配置,包括通用部署环境、经过压缩代理的环境,以及部署到 Vercel 时的超时截断。
先确认现象属于哪一类
部署后流式失效的表象都是"整段响应延迟返回",但文档把根因区分成了三种场景,先对照判断:
- 一般部署环境:本地正常、部署后失效,文档未限定具体平台,属于
content/docs/09-troubleshooting/06-streaming-not-working-when-deployed.mdx描述的通用问题; - 请求经过代理中间件:如果应用前面挂了配置了响应压缩(compression)的代理/中间件,流式会失败,见 Streaming Not Working When Proxied;
- 部署在 Vercel 且响应被截断:长回复在 UI 中被截断,Vercel 日志出现 timeout,或前端报错
Uncaught (in promise) Error: Connection closed,见 Getting Timeouts When Deploying on Vercel。
注意第 3 类与前一类的表象不同:前两类是"响应完整但不再逐字显示",Vercel 超时类则是"响应被中途切断"。先确定属于哪一类,再执行对应修复。
通用部署环境:为流式响应添加分块传输头
针对"本地正常、部署后失效"的通用场景,官方给出的处理方式是给流式响应添加'Transfer-Encoding': 'chunked'和Connection: 'keep-alive'请求头。修改点在返回流式响应的服务端代码里,给createUIMessageStreamResponse的headers参数(可选参数,类型为Headers | Record<string, string>)加上这两个头:
return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }), headers: { 'Transfer-Encoding': 'chunked', Connection: 'keep-alive', }, });其中result是流式调用(如streamText)的返回值,result.stream交给toUIMessageStream转换为 UI 消息流;createUIMessageStreamResponse与toUIMessageStream均从ai包导入(import { createUIMessageStreamResponse, toUIMessageStream } from 'ai')。这个函数创建向客户端流式推送 UI 消息的Response对象,参数详情见 createUIMessageStreamResponse API 参考。文档原文用的是"you can try the following",即这是建议尝试的修复项,而非保证覆盖所有部署环境的结论。
经过压缩代理时:声明不压缩
如果请求链路中存在配置了响应压缩的代理中间件,压缩会导致流式失败。修复方式是给流式 API 的响应加上'Content-Encoding': 'none'头:
return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }), headers: { 'Content-Encoding': 'none', }, });文档特别注明该方案只影响流式 API 的响应,不改动代理对其他接口的处理,因此可以直接对当前任务放心使用。如果你的环境既经过代理、又有前述通用部署问题,两个头可以同时出现在headers里。
部署在 Vercel:处理函数超时截断
当现象是"长回复被截断、Vercel 日志出现 timeout、前端报Uncaught (in promise) Error: Connection closed"时,问题出在函数执行时长上。使用 Vercel Fluid Compute 时,所有套餐的默认函数执行时长是 5 分钟(300 秒),文档认为这对多数流式应用已经足够;需要更长超时时再提高maxDuration。
Next.js(App Router)项目:在路由文件(route file)或调用 Server Action 的页面中添加:
export const maxDuration = 600;其他框架:在vercel.json中按路由配置超时:
{ "functions": { "api/chat/route.ts": { "maxDuration": 600 } } }上例中的api/chat/route.ts与600是文档示例值,替换为你实际的流式接口路径和需要的秒数。文档对maxDuration的限制如下,调整前需核对套餐:
| 套餐 | 最大执行时长 |
|---|---|
| Hobby | 最高 300 秒(5 分钟) |
| Pro | 最高 800 秒(约 13 分钟) |
| Enterprise | 最高 800 秒(约 13 分钟) |
把maxDuration设置到超过 300 秒需要 Pro 或 Enterprise 套餐,Hobby 套餐无法通过该配置突破 300 秒上限。
如何验证修复生效
成功条件与故障现象相对:部署环境中的应用恢复逐字(增量)显示,而不再"等待一段时间后一次性返回完整响应";如果属于 Vercel 超时场景,则长回复不再被截断,Vercel 日志不再出现 timeout,前端不再报Uncaught (in promise) Error: Connection closed。
两点边界需要记住:一是文档明确"成因取决于部署环境",若添加请求头后仍未恢复流式,说明你的部署链路还有其他未覆盖的环节,官方文档未给出进一步的统一排查顺序;二是本文各修复项对应各自场景,不要脱离对应现象盲目套用(例如没有代理压缩的环境无需Content-Encoding: none,没有 Vercel 超时现象的部署无需调整maxDuration)。
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考