AI SDK:统一模型调用、工具循环与 Web 流式界面
核验日期:2026-07-16。本文依据 AI SDK 当前 Core/UI 文档中的
generateText、streamText、Tools、Structured Output、MCP Client 与 UI Message/Data Stream 概念。major 版本和实验性 API 会变化,采用时固定版本并核对迁移指南。
AI SDK 面向 TypeScript 应用,为不同模型提供商提供相对统一的生成、流、结构化输出、工具与 UI 协议。它最有价值的地方不是把所有模型抹平成完全相同,而是把共同控制流放入一套类型和 Web Stream 接口,同时把 provider-specific 能力显式留在边缘。它不是数据库、权限系统或持久工作流引擎。
Core 与 UI 的分层
Core 在服务端调用语言/Embedding/图像等模型,执行工具并产出流;UI 层管理浏览器消息、提交、增量 parts、工具交互和错误。Provider adapter 把统一请求映射到厂商 API。应用层在外侧负责身份、租户、RAG、业务任务、授权、持久化和评测。
路由不应把浏览器传来的完整 messages 原样转发。先认证,验证消息 Schema、角色、parts、长度和附件;服务端重新构造系统策略、可用工具和受权上下文。模型密钥只在服务端。
generateText 与 streamText
generateText 适合后台任务、结构化处理或响应完成后一次返回;streamText 适合交互 UI,暴露文本/完整事件流及转换为 HTTP Response 的辅助能力。流改善首屏感知,不减少总费用,也不代表最终结果已验证。
import { streamText } from "ai";
const result = streamText({
model: configuredModel,
system: "仅依据已提供证据回答,并返回来源标识。",
messages: validatedMessages,
tools: allowedTools,
stopWhen: projectStopCondition,
abortSignal: request.signal,
});
return result.toUIMessageStreamResponse({
onError: () => "生成暂时失败,请稍后重试",
});这是一段集成骨架。configuredModel、工具和停止条件由项目配置;生产还需总 deadline、费用、授权、trace、持久化和敏感错误映射。不要把原始异常字符串通过 onError 发给浏览器。
流不是字符串分片
完整流会包含 text delta、reasoning(若提供且允许)、source、file、tool-call、tool-result/tool-error、step、finish、error 等不同 part。客户端按 discriminated union 处理,未知 part 使用兼容策略;不能把全部内容拼成一段 HTML。工具状态可能从 input streaming 到 available、output available 或 error,UI 要显示真实状态。
网络 chunk 不对应 token、Unicode 字符或 Markdown 节点。渲染器累积安全解析,URL/HTML 做 allowlist/sanitize。流开始后 HTTP 状态通常已发送,后续错误只能作为流事件表达;监控必须同时看 route status 和 stream finish/error。
取消分两类:用户停止读取流;服务端通过 AbortSignal 取消仍在执行的模型/工具。若工具已提交写入,取消不等于回滚。长任务应先持久化 task,再流状态;浏览器断线后可按 task id 重连。
UIMessage 与 ModelMessage
UI message 含用于展示的 parts、客户端状态和自定义 metadata;model message 是发给模型的规范化输入。两者不应共用未验证对象。浏览器可以篡改 role、tool result、approval 或 metadata,服务端按会话事件重建可信历史。
保存会话时优先保存版本化 UI/领域事件,而非供应商原始对象;升级时做 migration。工具执行结果由服务端生成并标记 call id,客户端提交的人机工具结果只在明确的 client tool/approval 协议中接受,并再次认证授权。
Tools 与多步生成
AI SDK tool/Schema 让参数类型推断和运行时验证靠近。工具有 description、input schema 与可选 execute;没有 execute 的 client-side tool 需要 UI 回传结果。模型提出调用后,框架可以执行并进入后续 step,stopWhen 控制何时停止。
停止条件是安全关键配置。限制 step、总 token、总时间、费用和工具次数;内建/自定义条件只能覆盖它声明的维度。onStepFinish 可收集该步文本、调用、结果、usage 和 finish reason,用于审计,但 callback 错误/语义按当前版本测试,不能把关键事务只放在遥测回调。
工具错误区分不存在工具、输入无效、执行失败和模型修复失败。流中错误可能以 tool-error/error part 出现;服务端映射安全消息,trace 保留分类。无效参数不执行;重试由幂等与 deadline 决定。
结构化输出
当前接口允许在生成配置中声明 output specification,具体 helper/API 随版本变化。无论写法如何,输出先满足供应商支持的 Schema 子集,再经过应用语义验证。流式 partial object 只能用于预览,完整完成并验证前不能作为命令。
结构化输出与工具选择不同:前者返回应用数据,后者请求外部动作。若模型只需提取分类,不要伪造一个工具;若需要执行查询,不要把“准备调用”当最终 JSON 再由前端随意执行。
Provider 抽象的真实边界
统一接口覆盖 prompt/messages、tools、usage、finish 等共同概念,但不同 provider 在模型角色、Schema 子集、并行工具、缓存、reasoning、文件、source、usage 分类、错误、速率和数据政策上不同。SDK 可能返回 warnings;生产应记录并在不允许能力降级时失败。
使用 providerOptions 等逃生口会增加锁定和测试范围。把它封装在 model profile:声明所需能力、允许 provider、参数、回退和数据地域。业务代码依赖能力而非模型名。更换 provider 时跑同一质量/安全/流/工具契约,不把“TypeScript 编译通过”等于语义等价。
type ModelProfile = {
id: string;
supportsTools: boolean;
supportsStructuredOutput: boolean;
maxInputTokens: number;
dataRegion: "cn" | "eu" | "us";
};这些字段来自团队核验配置,不信任客户端选择。高风险请求不自动 fallback 到未通过门禁或不满足地域的模型。provider outage 时可排队、稳定失败或切到已评测等价 profile。
MCP Client 的使用边界
AI SDK 可创建 MCP Client,把 MCP server tools 纳入生成。应用仍要执行 MCP 生命周期、认证、server allowlist、能力冻结、工具审批和结果限制。远程 server 的描述/结果是不可信内容;不要因为 SDK 自动转换 Schema 就跳过本地策略。
静态工具集优先显式注册,便于类型、最小权限和评测;动态 MCP 适合真实互操作需求。每次请求发现全世界工具会增加延迟和注入面,可缓存已验证 capability,同时按协议变更失效。
生成式 UI 的边界
工具可以返回结构化数据,UI 根据 tool name/result 渲染本地组件;模型不直接生成任意可执行 React/HTML。组件注册表是 allowlist,props 经过 Schema,链接/富文本安全处理。写操作组件显示预览与审批,不因模型输出一个“确认按钮”就获得权限。
无障碍要求:流状态使用可感知但不过度播报的 live region;停止/重试/审批可键盘操作;工具进行中、失败、完成有文本状态,不仅颜色;流结束后焦点不乱跳;用户可复制最终稳定答案和引用。错误保留已完成内容并给出恢复选项。
持久化与恢复
AI SDK 帮助传输流,不自动提供 durable workflow。保存用户消息后再启动生成,给 assistant response 分配 ID;增量可以缓冲或记录事件,完成时提交 final state。进程崩溃后标记 interrupted,允许用户重试或从任务系统恢复。不要把未完成 token 当正式答案。
同会话并发需要版本/sequence;客户端重发使用 message id/idempotency。工具副作用沿用 operation id。服务端部署时 drain 流或把运行放入可恢复 worker;serverless/edge 最大执行时间不适合超长工具循环。
Telemetry
AI SDK 提供 telemetry/回调入口,可与 OpenTelemetry 集成。模型 prompt、response 和 tool args 可能敏感,默认关闭内容采集或脱敏,只记录 function/model/profile、usage、duration、finish、step、tool/error 和 trace id。实验性 telemetry/API 可能在小版本改变,包版本固定并用 contract test 覆盖。
端到端 span 分 route/auth/context/retrieval/generation/tool/stream/write;首字节、首 token、完成和客户端取消分开。HTTP 200 + 流内 error 计入失败指标。监控每租户并发/费用、step 分布、未知工具、invalid input、aborted 和 incomplete response。
离线测试
用 SDK 的 mock/test utilities(若当前版本稳定)或自建 LanguageModel adapter 产生确定性流。随机把事件拆 chunk,覆盖 text、tool call/result/error、multi-step、finish、abort、provider warning 和中途异常;断言 UI parts 与最终持久状态。工具用领域 fake,不请求真实 API。
浏览器 E2E 测慢流、停止、刷新、重连、审批、键盘/屏幕阅读状态和安全渲染。真实 provider smoke 在受控环境运行,质量由 Agent 评测 数据集判断。升级 SDK 前跑序列化 golden 和 route/UI compatibility。
性能与部署
边缘运行可降低网络接入延迟,但模型/数据库/工具仍可能远端;检查 provider adapter、Node API、MCP transport 和 telemetry 是否兼容目标 runtime。不要只因流式聊天就迁到 Edge。Node server 适合较完整网络与 SDK 生态,长工作放 worker/队列。
上下文/工具描述压缩、稳定前缀缓存、合适模型 profile、有限 step 和并行只读工具可控成本。测 p50/p95/p99、TTFT、token rate、完整时间、错误和费用,不用单次肉眼“流很快”。backpressure 防止慢客户端堆积内存;响应/附件大小有限。
何时采用
需要 TypeScript 多 provider、Next.js/React 等 Web 流式 UI、类型化工具和结构化生成时采用。只用单一 provider 的后台单次调用可直接用官方 SDK;需要复杂 durable 图和人工等待用 LangGraph/工作流;需要 Agent 角色、handoff/guardrail/tracing 可考虑 Agents SDK。它们可以组合,但先定义每层 owner,避免三套 tool loop 嵌套。
验收应从浏览器输入追到服务端重建消息、模型 profile、工具、流事件、持久结果和 trace,证明取消、错误、权限、provider 差异、可访问性和恢复;不能只展示一个会逐字输出的页面。