流式输出

聊天必须流式:模型可能要几十秒才结束,用户需要立刻看到字。AI SDK Core 用 streamText 做这件事;无 UI 的批处理用 generateText(见 快速上手)。

streamText 一调用就开始流,错误默认吞掉以免打崩 Node 进程。务必传 onError 做日志。流带背压:你不读,模型就不会继续吐 token。


streamText 最小循环(Node)

import { streamText } from 'ai';

const result = streamText({
  model: 'openai/gpt-4.1-mini',
  prompt: 'Invent a holiday in three sentences.',
  onError({ error }) {
    console.error(error);
  },
});

for await (const textPart of result.textStream) {
  process.stdout.write(textPart);
}

result.textStream 既是 ReadableStream 也是 AsyncIterable。流结束后可以 await result.textresult.usageresult.finishReasonresult.toolCalls

系统提示用 instructions,不要抄旧文档的 system


接到 useChat:UI Message Stream

Next.js App Router 里,把 完整 result.stream(含工具、步骤边界)转成 UI 协议:

import {
  convertToModelMessages,
  createUIMessageStreamResponse,
  streamText,
  toUIMessageStream,
  type UIMessage,
} from 'ai';

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages }: { messages: UIMessage[] } = await req.json();

  const result = streamText({
    model: 'openai/gpt-4.1-mini',
    instructions: 'You are a helpful assistant.',
    messages: await convertToModelMessages(messages),
  });

  return createUIMessageStreamResponse({
    stream: toUIMessageStream({ stream: result.stream }),
  });
}

这是 7.x 与 useChat 的默认协议(SSE)。自定义后端需设置头 x-vercel-ai-ui-message-stream: v1。事件包括 text-deltatool-input-*start-step / finish-stepfinishdata: [DONE]。日常开发不必手写这些;用官方 helper 即可。


纯文本流(能力更弱)

没有工具、只要字符串时:

import { createTextStreamResponse, toTextStream } from 'ai';

return createTextStreamResponse({
  stream: toTextStream({ stream: result.stream }),
});

客户端:

import { useChat } from '@ai-sdk/react';
import { TextStreamChatTransport } from 'ai';

useChat({ transport: new TextStreamChatTransport({ api: '/api/chat' }) });

有工具就不要用文本流,工具调用传不过去。聊天助手一律用 UI Message Stream。


其它管道

Helper用途
createUIMessageStreamResponse + toUIMessageStreamApp Router + useChat(默认)
pipeUIMessageStreamToResponse写入 Node 风格 ServerResponse
createTextStreamResponse + toTextStream纯文本
result.textStream自己在脚本里 for await

结构化流

streamText 可加 output: Output.object({ schema }),用 partialOutputStream 读尚未完整的对象;前端用 useObject。注意:部分 JSON 不能按完整 schema 校验。见官方 Generating Structured Data。


调试清单

  1. 页面卡住、永远 submitted:路由没返回 UI stream,或 result.stream 没被消费。
  2. 只有文字、工具 UI 空白:客户端没用 parts,或服务端走了文本协议。
  3. Vercel 上 30 秒被砍:设 export const maxDuration(见 Next.js)。
  4. 控制台没报错但没字:补 onErrorstreamText 默认不把错误 throw 到路由外。

下一步

评论