前端集成 AI:SDK 选型、流式渲染与 Chat UI

前端集成 AI:SDK 选型、流式渲染与 Chat UI

三个需要分别决策的问题

给已有的前端项目增加 AI 能力,看起来是一个任务,实际是三个独立的技术决策:

  1. 用哪套 SDK 调模型——决定了未来换模型时的工作量;
  2. 流式渲染怎么接——决定首字延迟和长回答的体验;
  3. 聊天界面组件从哪来——决定开发速度和后期的定制自由度。

这三个决策之间有一定耦合,但不要绑在一起做。下面逐个拆。

第一件事:SDK 选型

Vercel AI SDK:事实标准,但版本迭代很快

AI SDK 是目前 TypeScript 生态里使用最广的一层模型抽象。两个版本的量级数据:

  • AI SDK 6 发布于 2025 年 12 月 22 日,发布时官方给出的数字是月下载量超过 2000 万。
  • AI SDK 7 发布于 2026 年 6 月 25 日(Vercel 官方博文,作者 Gregor Martynus、Lars Grammel、Felix Arntz、Aayush Kapoor、Josh Singh),周下载量超过 1600 万。

从 6 到 7 的跨度不小,并且有两个硬性破坏性变更,升级前必须先确认:

  1. Node.js 最低 22。原因是 SDK 依赖了未被回移到更早 LTS 版本的原生 fetch 实现和 AsyncLocalStorage 语义。
  2. 必须使用 ESM。不再支持 CommonJS 的 require(),需要给 package.json 加 "type": "module",或把单个文件迁移成 .mjs

迁移工具是现成的:

# AI SDK 6 升级到 7
npx @ai-sdk/codemod v7

# 或者让 agent 直接执行迁移 skill
npx skills add vercel/ai --skill migrate-ai-sdk-v6-to-v7

官方明确说明 codemod 无法自动处理的部分需要人工判断:运行时要求、ESM 导入、instructions 与 message 行为、runtime context 与 tool context 的拆分、审批策略的放置位置、stream helper 的用法、多步结果的形状。

AI SDK 7 值得关注的几个能力

  • 统一的 reasoning 选项。generateTextstreamText 现在接受顶层 reasoning 参数,映射到各家的原生推理设置(覆盖 OpenAI、Anthropic、Google、Groq、xAI、Bedrock、Fireworks、DeepSeek 等)。官方也提醒:各 provider 的具体行为和可用参数并不一致。
  • 类型化运行时上下文。共享的编排状态放在 runtimeContext 里,穿过 prepareStep、审批函数、生命周期回调、遥测和 agent 循环。这让「同一个 agent 在不同场景下注入不同上下文」变得类型安全。
  • 工具级上下文隔离。工具可以声明 contextSchema,调用方通过 toolsContext 传值。第三方工具只能拿到它自己需要的密钥或配置,而不是整个应用的上下文。
  • 持久化执行。新增 @ai-sdk/workflowWorkflowAgent,支持跨进程重启、部署、中断和延迟审批的恢复执行。对需要人工审批的长流程来说这是刚需。
  • 超时配置。支持总量、单步、单块、单工具四级超时,超时抛出 TimeoutError,中止原因会沿着流和 UI 协议传播。
  • MCP Apps。MCP 支持区分「模型可见工具」和「仅应用工具」,并能在沙箱 iframe 里渲染应用界面,通过 JSON-RPC 桥接工具、资源与展示交互。
  • 多模态扩展。实时语音(实验性,基于 WebSocket,支持 OpenAI / Google / xAI)和视频生成(实验性,支持 fal、Google AI Studio、Vertex、Replicate)。
  • 遥测重做。新增 @ai-sdk/otel,在应用启动时用 registerTelemetry 注册一次即可,不必在每个调用点接回调。

还有一个偏架构层面的变化值得注意:AI SDK 7 增加了实验性的 harness 抽象 HarnessAgent,用一套 API 去驱动 Claude Code、Codex、Pi 这类已经成型的 agent 运行时。这意味着「调用外部编程 agent」正在从一个集成技巧变成 SDK 的一等能力。

TanStack AI:给不想绑厂商的团队

如果团队对「SDK 和 Vercel 平台绑定太紧」有顾虑,TanStack AI 是 2026 年最值得认真看的替代方案。时间线很清楚:

  • 2025 年 12 月发布 alpha;
  • 2026 年 6 月 9 日发布 Beta(TanStack 官方博文,作者 Tom Beckenham)。

它的定位是框架无关、厂商无关。核心差异点:

  • 按能力拆分的 provider 适配器。不是一个大而全的 openai 包,而是 openaiTextgeminiAudio 这样的小适配器,用到什么引什么。
  • 涵盖全部模态。文本、结构化输出、工具调用、实时语音(OpenAI Realtime over WebRTC、ElevenLabs over WebSocket)都在同一套 provider 无关架构下。
  • 中间件机制。可以挂进 chat() 生命周期的每个阶段做观测、变换或者短路;官方内置了工具结果缓存、内容脱敏和 OpenTelemetry 追踪三个中间件。
  • 懒加载工具定义。不要的 tool 定义不发给模型,既省 token 也避免干扰模型判断。
  • Code Mode。让模型在安全沙箱里写并执行 TypeScript,用循环、条件判断和 Promise.all 一次性组合多个工具调用,而不是每个工具一次往返。
  • 协议稳定并公开。服务端与客户端如何通信有完整文档,Beta 阶段协议已稳定。

值得一提的还有它的官方态度:TanStack 在文档里维护了一份与 Vercel AI SDK 的逐项对比,包括对方领先的地方。这种写法的可信度比单纯的「我们更好」高得多。

怎么选

你的情况倾向
Next.js 技术栈、要最快落地、接受 Node 22 + ESMVercel AI SDK 7
需要持久化执行、人工审批、长流程 agentVercel AI SDK 7(WorkflowAgent)
Vue / Svelte / Solid 为主,或明确要避开平台绑定TanStack AI
需要精细控制每一步、只把 SDK 当轻量工具调用层TanStack AI
团队里已有大量基于 AI SDK 5/6 的代码先跑 codemod,评估 ESM 改造范围再定

第二件事:流式渲染

流式不是一个「体验优化」,而是交互的基本预期。阻塞式响应要等完整结果生成完才显示,流式响应在生成过程中就陆续呈现。对于一次要写几百个字的回答,两者的感知差距是数量级的。

服务端:返回一个流

AI SDK 的方式是让 streamText 的结果直接转成 UI 消息流响应:

// app/api/chat/route.ts
import { streamText, convertToModelMessages } from 'ai';

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

  const result = streamText({
    model: 'openai/gpt-5.5',
    messages: convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}

TanStack AI 的方式是包装成 SSE 响应:

import {
  chat,
  chatParamsFromRequest,
  toServerSentEventsResponse,
} from '@tanstack/ai';
import { openaiText } from '@tanstack/ai-openai';

export async function POST(req: Request) {
  const stream = chat({
    adapter: openaiText('gpt-5.5'),
    ...chatParamsFromRequest(req),
  });
  return toServerSentEventsResponse(stream);
}

最容易踩的坑:中间层把流缓冲了

这是流式功能「本地好、线上坏」的头号原因。vercel/ai 仓库里有一个典型 issue(#11917,2026 年 1 月):从 AI SDK 5 升级到 AI SDK 6 后,Express 环境下的 UI 消息流不再工作,报告者确认问题出在压缩中间件上。

原理很简单:任何一层代理、压缩或缓冲中间件只要攒够一定字节数才转发,流就会退化成一次性返回。排查时按这个顺序看:

  1. 响应头。确认 Content-Typetext/event-stream 或对应的 UI 消息流类型,并且没有被改写成 application/json
  2. 压缩中间件。gzip / brotli 的缓冲是常见元凶,对 SSE 路径应直接跳过压缩。
  3. 反向代理。Nginx 需要关闭该路径的 proxy_buffering;CDN 和边缘平台也可能有缓冲策略。
  4. 超时。长回答可能超过默认的读超时,表现为流中途断掉。
  5. 本地验证方法。curl -N 直接看服务端是否是逐块输出。如果 curl 是流式的但浏览器不是,问题一定在中间层而不在代码。

升级时容易被忽略的两点

  • 多步结果的语义变了。AI SDK 7 里顶层 usagecontent、工具调用与结果、文件、来源、警告跨所有步骤累加;只有最后一步的数据放在 finalStep 下面。原来读顶层字段拿「最后一步数据」的代码会拿到累计值。
  • 消息部件更统一了。旧的媒体和图片专用部件向带 media type 的 file 部件收敛。自定义渲染逻辑需要跟着调整。

第三件事:Chat UI 组件

聊天界面看起来简单,真做起来要处理的东西不少:消息滚动锚定、流式追加时的自动跟随、向上翻历史时的位置保持、Markdown 与代码块渲染、工具调用状态、推理过程展示、附件上传、打断与重试。从零写一遍不值当。

选项一:shadcn/ui 的聊天组件(2026 年 6 月新增)

shadcn/ui 在 2026 年 6 月的更新里正式把聊天的核心部件纳入组件体系,逐个发布为可以复制、组合、改造成自己产品形态的组件:

  • MessageScroller——滚动行为本身:锚定、自动跟随、向上插入历史时的位置保持、滚动命令、可见性判断。
  • Message、Bubble、Attachment、Marker——消息、气泡、附件和标记这几块界面元素,组合起来就是一个 AI 对话界面。
  • 工具类组件 scroll-fadeshimmer,分别处理滚动边缘渐隐和加载时的微光效果。

同时新增了 @shadcn/react 包,用作无样式的 headless React 组件层。第一个原语就是 @shadcn/react/message-scroller:注册表里的组件负责外观,滚动行为本身沉在包里,这样行为逻辑可以独立测试,也不会被某一种视觉风格锁死。目前同时支持 Radix 和 Base UI 两套底层。

另外 @shadcn/helpers 下提供了 AI SDK 和 TanStack AI 的辅助函数(例如 createChat()),把会话状态管理和上面两套 SDK 对接起来。这个安排很聪明——组件层不对 SDK 选型做假设。

官方特别说明了这次发布不替代 AI Elements:已经在用 AI Elements 的项目不需要重写,想用更新的抽象、更新的样式或跨 Radix / Base UI 支持时再逐个替换即可。目标是每个部件都能独立采用。

选项二:AI Elements

AI Elements 是构建在 shadcn/ui 之上的 AI 原生组件库与注册表,特点是和 AI SDK 深度集成——流式状态、类型安全都是内置的,同时沿用 shadcn/ui 的约定,项目已有的主题直接生效。它的组件覆盖面是目前最广的:

  • 对话相关:Conversation、Message、Prompt Input、Attachments、Reasoning、Chain of Thought、Tool、Task、Sources、Inline Citation、Confirmation、Checkpoint、Queue、Model Selector、Plan、Context、Suggestion、Shimmer。
  • 代码相关:Agent、Artifact、Code Block、File Tree、JSX Preview、Sandbox、Schema Display、Stack Trace、Terminal、Test Results、Web Preview、Package Info。
  • 语音相关:Speech Input、Transcription、Audio Player、Persona、Mic Selector、Voice Selector。
  • 工作流相关:Canvas、Node、Edge、Panel、Toolbar、Controls、Connection。

官方还提供了对话机器人、IDE、v0 克隆、工作流四个完整示例。如果你的产品形态是「编程类 AI 应用」,代码相关那一组组件能省掉相当多的重复劳动。

选项三:assistant-ui 等社区方案

assistant-ui 走的是可组合原语的路线,在 shadcn/ui 生态的模板盘点里经常被列为起点之一。除了它,社区还有 chatcn 这类补充方案。选社区方案时重点看三件事:是否跟上所依赖 SDK 的大版本节奏(AI SDK 6 到 7 有破坏性变更)、滚动行为是不是自己实现的(这是最容易出 bug 的部分)、样式是否通过复制进项目而非包依赖(决定后期改造自由度)。

选型建议

  1. 先明确产品形态。标准对话产品选 AI Elements 起步最快;需要高度定制界面或深度融入现有设计系统,用 shadcn/ui 的聊天组件逐块组合更合适。
  2. 把滚动行为当成独立问题。如果组件库把滚动逻辑沉到了一个可测试的包里(例如 @shadcn/react/message-scroller),优先考虑——流式追加、翻历史、自动跟随这几个场景自己调过就知道有多麻烦。
  3. 组件层尽量不绑定 SDK。选那些通过 helper 层对接 SDK、而不是把 SDK 写进组件内部的方案,这样将来从 AI SDK 换到 TanStack AI 时不用重写界面。

结语

2026 年前端集成 AI 的技术栈其实已经收敛得比较清楚了:SDK 层是 Vercel AI SDK 和 TanStack AI 两个主要选项,流式协议基本统一在 SSE 和 UI 消息流上,界面层则集中在 shadcn/ui 体系里。

真正需要花心思的地方不在选型,而在两件容易被低估的事:一个是部署链路上任何一环的缓冲都会让流式失效,另一个是 SDK 的大版本迭代节奏很快,升级成本要提前算进技术债。选型时把这两点考虑进去,比纠结用哪个库更有价值。

本文数据来源:Vercel 官方博文《AI SDK 7》(2026-06-25)与《AI SDK 6》(2025-12-22)、Vercel 官方 changelog、vercel/ai 仓库 issue #11917、shadcn/ui 官方 2026 年 6 月变更日志、AI Elements 官方文档、TanStack 官方博文《TanStack AI Beta》(2026-06-09)与 TanStack AI 文档。