从 vercel/ai README 看 TypeScript AI Agent 的工具链结构

在 README 的 Agent 示例里,一个 Agent 被写成 ToolLoopAgent,工具里可以调 openai.tools.localShell,在前端则通过 useChat 和消息 parts 渲染工具调用。这种从模型调用、工具执行到 UI 状态同步的链路,正是 TypeScript AI 应用工具链最容易被低估的部分。官方 README 没有展开内部实现,但它公开的 API 表面已经能说明一些选型问题。

官方明确给出的定位与运行时

AI SDK 被描述为 provider-agnostic 的 TypeScript toolkit,用于构建 AI-powered applications 和 agents,支持 Next.js、React、Svelte、Vue、Angular 等 UI 框架,以及 Node.js 运行时。安装要求写的是 Node.js 22+ 和 npm(或其他包管理器),安装命令是 npm install ai。对 coding agents 用户,README 还建议运行 npx skills add vercel/ai 把 AI SDK skill 加入仓库。

这些是事实层面的硬信息:最低 Node.js 版本、包名、skill 安装入口。选型时可以先对齐运行时基线,再判断前端框架支持是否覆盖现有工程。

统一 Provider 抽象:网关与直连两条路

README 的 Unified Provider Architecture 部分给出了两种接入方式。

默认方式走 Vercel AI Gateway,代码只传模型字符串:

const result = await generateText({
  model: 'anthropic/claude-opus-4.6', // 或 'openai/gpt-5.4'、'google/gemini-3-flash'
  prompt: 'Hello!',
});

另一种是安装 provider SDK 包,再直接调用:

import { anthropic } from '@ai-sdk/anthropic';

const result = await generateText({
  model: anthropic('claude-opus-4-6'),
  prompt: 'Hello!',
});

README 明确列出的 provider 包括 OpenAI、Anthropic、Google,并指向更多 provider 文档。这里有一个值得注意的细节:网关示例里的模型串是 anthropic/claude-opus-4.6,而直连 SDK 示例里是 anthropic('claude-opus-4-6')。两者写法不同,README 没有解释差异来源。实际接入时,模型标识、默认网关行为和直连 SDK 的参数映射需要单独验证,不能默认两条路径完全等价。

从工程角度看,这种「默认网关 + 直连逃生舱」的结构对选型有直接影响。如果团队已经在用某一家 provider 的独家能力,直连 SDK 的抽象层是否够薄、是否会把 provider 特有参数吃掉,是需要看源码或文档确认的。反过来,如果希望一套代码快速切模型,网关的字符串路由方式降低了接入成本,但也引入了对网关可用性和配置的依赖。

结构化输出与 Agent 循环

在结构化数据部分,README 展示的是 generateText 配合 Output.object 和 zod schema:

import { generateText, Output } from 'ai';
import { z } from 'zod';

const { output } = await generateText({
  model: 'openai/gpt-5.4',
  output: Output.object({
    schema: z.object({...}),
  }),
  prompt: 'Generate a lasagna recipe.',
});

这说明 AI SDK 把结构化输出做进了统一调用入口,而不是要求开发者自己拼 provider 的 JSON mode 或 function calling。对需要稳定数据结构的应用,这是一个明确的 API 面。

Agent 部分则出现了 ToolLoopAgent

import { ToolLoopAgent } from 'ai';

const sandboxAgent = new ToolLoopAgent({
  model: 'openai/gpt-5.4',
  system: 'You are an agent with access to a shell environment.',
  tools: {
    shell: openai.tools.localShell({
      execute: async ({ action }) => {
        const [cmd, ...args] = action.command;
        const sandbox = await getSandbox(); // Vercel Sandbox
        const command = await sandbox.runCommand({ cmd, args });
        return { output: await command.stdout() };
      },
    }),
  },
});

README 没有说明 ToolLoopAgent 内部如何驱动工具循环、如何决定继续调用还是停止、错误和重试如何处理。它只展示了定义方式、工具注册方式,以及工具执行函数可以返回结果。从选型角度,这意味着「Agent 循环控制权」是必须进一步查文档或源码的点:循环次数、终止条件、并行工具调用、人工确认、超时与取消,都会影响生产可用性。

UI 集成:框架无关的 hooks 与消息 parts

README 的 UI Integration 部分明确说,AI SDK UI 模块提供一组 hooks,用于构建 chatbot 和 generative UI。这些 hooks 是 framework agnostic,可以用在 Next.js、React、Svelte、Vue。使用时要安装对应框架包,例如 npm install @ai-sdk/react

一个端到端的 image generation agent 示例展示了前后端分工:

Agent 文件导出 ToolLoopAgent,工具是 openai.tools.imageGeneration({ partialImages: 3 }),并用 InferAgentUIMessage 导出消息类型。

Next.js App Router 的 route 里,用 createAgentUIStreamResponse({ agent, messages }) 把 agent 接到 UI。

前端组件用 UIToolInvocation 接收工具调用,根据 invocation.stateinput-availableoutput-available 渲染不同 UI。页面用 useChat(),遍历 message.parts,按 part.type 区分文本和 tool-generateImage

这段示例的工程信息量在于:AI SDK 没有把 UI 状态藏在内部,而是把消息拆成 parts,工具调用作为一类 part 暴露给前端。类型上通过 InferAgentUIMessage 从 agent 定义推导消息类型。这意味着前后端共享同一套 TypeScript 类型,工具名到 UI 渲染分支是对齐的:tool-generateImage 对应 openai.tools.imageGeneration

但 README 同样没有说明:parts 的完整类型集合、流式增量如何合并、工具调用中间状态如何持久化、多轮工具调用如何排序。这些是 UI 集成中容易出问题的地方,需要结合 API Reference 和实际运行验证。

选型时值得验证的边界

如果把 AI SDK 放进 TypeScript AI Agent 工具链的候选名单,README 能支撑的结论是有限的但具体的:

  • 它明确支持 Node.js 22+,安装包是 ai
  • 它提供统一 Provider 抽象,默认走 Vercel AI Gateway,也可直连 @ai-sdk/openai@ai-sdk/anthropic@ai-sdk/google
  • 它包含 generateTextOutput.objectToolLoopAgent 等公开 API。
  • 它的 UI hooks 框架无关,但需要按框架安装 @ai-sdk/react 等包。
  • 示例覆盖了 Next.js App Router 的 route、createAgentUIStreamResponseuseChat 和工具调用渲染。

需要进一步验证的则包括:Provider 直连与网关的行为差异、模型串映射规则、Agent 循环的终止和错误策略、工具执行的安全边界、UI parts 的流式协议、以及与现有状态管理、鉴权、计费、可观测性系统的集成方式。

对使用 TypeScript 构建 AI 应用的团队来说,一个可行的做法是先用一个最小工具调用链做验证:定义 ToolLoopAgent,注册一个幂等工具,通过 createAgentUIStreamResponse 接到前端,再用 useChat 渲染 parts。在进入生产前,把上述边界项逐条对照文档和源码确认,而不是只根据 README 的示例判断完整能力。