一条 part 分支,给出生成式 UI 的设计前提
消息流里出现 'tool-generateImage' 时,UI 层要决定渲染什么。官方示例的做法是分支:
case 'text':
return {part.text};
case 'tool-generateImage':
return ;
这段代码背后是对“生成式 UI”的一种设计取舍:模型没有把组件代码写进消息流,模型只是触发了一个开发者预先注册的工具调用,前端拿到这个结构化 part 后,从本地组件实现中选出 ImageGenerationView。真正被“生成”的,是消息流中的文本与工具输出;UI 容器仍受开发者声明的组件清单控制。
这个示例来自 Vercel AI SDK。README 给自己的定义是 provider-agnostic TypeScript toolkit:面向 AI 应用与 Agent,覆盖 Next.js、React、Svelte、Vue、Angular 等 UI 框架和 Node.js runtime,要求 Node.js 22+。项目作者是 Vercel 与 Next.js 团队成员,并接受社区贡献。如果你只把它当作一个 LLM 调用封装,会忽略它真正想解决的问题:让 AI 应用与 Agent 的前后端交互拥有一套统一、类型化的数据结构。
若你使用 Claude Code、Cursor 这类编码 Agent,官方还建议在仓库中加入对应的 skill:npx skills add vercel/ai。这算是项目对“Agent 对话工程化”的自我定位细节。
Provider 接入有两条默认不同的路径
接入模型时,README 展示了两种写法。第一种直接传模型字符串:
const result = await generateText({
model: 'anthropic/claude-opus-4.6', // 或 'openai/gpt-5.4', 'google/gemini-3-flash'
prompt: 'Hello!',
});
这段代码下方注明:默认情况下,AI SDK 使用 Vercel AI Gateway 接入各主要 Provider。因此这里有一个需要提前确认的工程边界:最简写法并不等价于请求直连模型厂商,默认接入通道是 Vercel 的 AI Gateway。若你的场景要求直连,README 给出的替代路径是安装对应 Provider 的 SDK 包:
import { anthropic } from '@ai-sdk/anthropic';
const result = await generateText({
model: anthropic('claude-opus-4-6'),
prompt: 'Hello!',
});
两种写法并存,给 AI SDK 留出了“默认方便”与“链路可控”的切换空间。但这也意味着选型时就要确定走哪条路:模型字符串方案把 Provider 路由交给网关;直连方案会让代码多一层对 provider SDK 的引用。
从 Agent 工具到前端消息类型的完整链路
在基础生成能力上,README 还出现了几个关键原语:generateText 负责文本生成;配合 Output.object 与 zod schema 可让模型返回结构化数据;ToolLoopAgent 则把模型、system prompt 与 tools 组合成一个 Agent 对象。对 TypeScript 团队来说,结构化输出沿用了自己熟悉的 zod 生态,SDK 不必为此引入另一套 schema 语言。
真正把 Agent 与 UI 连接起来的设计,体现在图片生成 Agent 的示例中。Agent 在服务端定义:
export const imageGenerationAgent = new ToolLoopAgent({
model: 'openai/gpt-5.4',
tools: {
generateImage: openai.tools.imageGeneration({
partialImages: 3,
}),
},
});
随后通过 InferAgentUIMessage 把 Agent 的工具集合直接推导为前端消息类型:
export type ImageGenerationAgentMessage = InferAgentUIMessage;
服务端路由把请求接到 Agent 的响应通道上:
export async function POST(req: Request) {
const { messages } = await req.json();
return createAgentUIStreamResponse({
agent: imageGenerationAgent,
messages,
});
}
前端 useChat() 拿到消息后,对 message.parts 做类型分支。对应的图片生成组件,接收的 prop 类型直接来自工具本身:
import { openai } from '@ai-sdk/openai';
import { UIToolInvocation } from 'ai';
export default function ImageGenerationView({
invocation,
}: {
invocation: UIToolInvocation>;
}) {
switch (invocation.state) {
case 'input-available':
return Generating image...;
case 'output-available':
return ;
}
}
从官方 README 的图片生成示例可看出,“生成式 UI”的一种实现模式是:服务端声明 Agent 的工具集,工具类型被 InferAgentUIMessage 推导到前端;前端每个工具 part 对应一个组件;组件又通过 invocation.state 感知工具在服务端的执行阶段。模型只在“选择哪个已注册工具、生成什么内容”上有自由度,不再有“生成任意组件结构”的自由度。
这套边界适合什么场景
基于 README 的示例,可以提炼出几个可供选型判断的工程结论。
第一,如果你的应用需要 Agent 工具执行结果驱动前端展示,AI SDK 的这套类型链路会省掉大量手写消息协议的功夫。Agent 每增加一个工具,前端消息类型在类型层面会相应扩展;UI 组件只要按约定实现并做分支即可。至于类型推导的具体边界,可进一步用 ToolLoopAgent 的源码验证。
第二,UI 的可表达范围以“预先注册的工具”为上限。想展示新的界面形态,必须先在 Agent 侧定义工具、再在前端注册对应组件。如果产品需要的不是工具调用型交互,而是模型自由布局式的界面生成,这套把 UI 工具化的模型反而会成为约束。
第三,部署链路不是“开箱即直连”。README 默认接入的是 Vercel AI Gateway;不经过网关的用法需要改用 provider 直连 SDK。README 只在开头声明 Node.js 22+,并未给出边缘 Runtime 或自建网关的说明,这类环境兼容性应在官方文档或最小验证中确认。
如果准备进一步读源码,建议优先验证这几个问题:createAgentUIStreamResponse 内部使用什么协议切分流式消息?ToolLoopAgent 如何控制循环边界与工具异常?Svelte、Vue 的 UI hooks 与 React 版本的能力是否完全平级?这些问题都无法从当前 README 的示例中获得结论,但决定了 AI SDK 是否值得放进你的长期技术底座。