AI SDK 7 实战指南:基于 `skills/use-ai-sdk` 的版本对齐、AI Gateway 接入与 Agent 构建全流程
本篇指南以仓库内
skills/use-ai-sdk/SKILL.md为骨架,系统讲解 AI SDK(ai包)的正确打开方式:如何不依赖记忆、以随包文档为准绳进行开发;如何通过 Vercel AI Gateway 一条 API 接入多家模型;如何用ToolLoopAgent等内建抽象构建 Agent 并实现端到端类型安全;以及 DevTools 调试、版本管理与类型检查等工程化细节。读完你将掌握一套"查证驱动"的 AI SDK 实战方法论,可直接应用于本仓库中 examples 目录下的各类示例应用。
一、AI SDK 是什么
AI SDK(npm 上的 ai 包)是面向 TypeScript 生态的 AI 应用开发工具包。它屏蔽了不同模型提供商的差异,为文本生成、结构化输出、工具调用(tool calling)、Agent、Embedding 以及框架级 UI 集成提供统一 API。
从当前仓库的入口文件可以直观看到它的能力版图。packages/ai/src/index.ts 将整个 SDK 按目录导出,涵盖:
agent:Agent 抽象(如ToolLoopAgent);generate-text/stream-text:generateText/streamText文本生成与流式输出;generate-object:结构化输出;embed/rerank:向量嵌入与重排序;generate-image/generate-video/generate-speech/transcribe/translate:多模态能力;ui/ui-message-stream:框架无关的 UI 消息流;middleware/telemetry/registry:中间件、遥测与模型注册表。
此外 ai 包还从 @ai-sdk/gateway、@ai-sdk/provider-utils 透传了 createGateway、gateway、tool、zodSchema、jsonSchema 等核心构造器(见 packages/ai/src/index.ts)。在仓库中,与 ai 包配套的还有 @ai-sdk/openai、@ai-sdk/anthropic、@ai-sdk/google 等数十个提供商包(见 packages 目录),以及 @ai-sdk/react、@ai-sdk/svelte、@ai-sdk/vue 等框架包。
二、铁律:永远不要凭记忆写 AI SDK 代码
SKILL.md 中最核心的一条方法论是:你所记忆的 AI SDK 知识几乎必然是过时的。这个 SDK 跨版本演进极快——API 被重命名、移除、新增。训练数据中很可能包含已废弃的 API、过时模式和不存在的模型 ID。其中 useChat 等 UI Hooks 是变动最频繁的 API 之一,写客户端代码时尤其要小心。
因此:
绝不凭记忆编写 AI SDK 代码。 写任何 API、选项、模式之前,都必须对照项目里实际安装版本的文档与源码进行核实。
这条原则在本仓库同样成立:仓库根目录的 CHANGELOG.md 与 packages/ai/CHANGELOG.md 记录了频繁的 API 演进;packages/ai/package.json 中当前版本为 7.0.97,任何外部记忆都可能与该版本不符。
三、使用随包附带、与版本匹配的文档
ai 包在发布时会把完整文档和源码打进包里(node_modules/ai/docs/ 与 node_modules/ai/src/)。这些内容始终与已安装版本精确匹配,因此优先级高于任何记忆。
使用流程如下:
- 确认
ai已安装。如果node_modules/ai/不存在,只用项目包管理器安装ai包本身(如pnpm add ai)。之后按任务需要再安装提供商包(如@ai-sdk/openai)和框架包(如@ai-sdk/react)——保持"按需安装",避免无关依赖干扰版本匹配。 - 阅读并检索随包文档与源码:文档在
node_modules/ai/docs/,源码在node_modules/ai/src/。 - 提供商包与框架包同样自带文档:
node_modules/@ai-sdk/<name>/docs/。 - 若随包文档中没有答案,再检索在线文档站;任何文档页 URL 后追加
.md即可获得 Markdown 版本,也可用其搜索接口检索。 - 如果文档和源码中都找不到答案,明确说出来,不要猜。
在本仓库(monorepo)中,上述"随包文档"的源就位于 content/docs(含 03-ai-sdk-core、04-ai-sdk-ui、07-reference、08-migration-guides 等目录)。ai 包的构建脚本也印证了这一点:packages/ai/package.json 中的 prepack 脚本执行 cp -r ../../content/docs ./docs,把仓库内文档复制进包里随 npm 发布。也就是说,本仓库的 content/docs 就是你开发时"版本匹配文档"的上游来源。
四、AI Gateway:最快的起步方式
Vercel AI Gateway 是开始使用 AI SDK 的最快路径。它通过单一 API 提供 OpenAI、Anthropic、Google 等多家提供商的模型,无需逐个安装提供商包,也无需管理多把 API Key。
4.1 接入步骤
- 通过 OIDC 认证(适用于 Vercel 部署环境)或获取 AI Gateway API Key;
- 通过环境变量
AI_GATEWAY_API_KEY提供给应用; - 使用
provider/model字符串引用模型,例如anthropic/claude-...、openai/gpt-...。
环境变量名在仓库源码中有明确依据:packages/gateway/src/errors/gateway-authentication-error.ts 的错误提示写明"通过 apiKey 选项或 AI_GATEWAY_API_KEY 环境变量提供 API Key 或 Vercel 访问令牌"。Gateway 提供商的完整实现可参见 packages/gateway/src/gateway-provider.ts 与 packages/gateway/src/gateway-language-model.ts。ai 包通过 packages/ai/src/index.ts 直接导出 createGateway 与 gateway,即开即用。
4.2 选择模型:永远先拉取最新模型列表
模型发布与下架非常频繁,绝不要用记忆中的模型 ID 写代码。写引用模型的代码前,先获取当前模型列表。SKILL.md 给出的命令如下(注意不要用 head 之类截断列表,以免漏掉最新模型):
# 列出所有可用模型
curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '.data[].id'
# 按提供商过滤(如 anthropic、openai、google)
curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '[.data[] | select(.id | startswith("anthropic/")) | .id] | reverse | .[]'
当同一模型存在多个版本时,优先选择版本号最高的那个。
五、构建与消费 Agent
5.1 优先使用内建 Agent 抽象
构建带工具循环的 Agent 时,应优先使用 SDK 内建的 Agent 抽象(如 ToolLoopAgent),而不是手写工具调用循环。
ToolLoopAgent 的实现在 packages/ai/src/agent/tool-loop-agent.ts,其类注释精确描述了循环语义:
工具循环 Agent 在每个步骤中调用 LLM;若返回工具调用,则执行工具并在新步骤中把工具结果回传给 LLM。循环持续,直到满足以下任一条件:
- 返回的推理结束原因不是 tool-calls;
- 被调用的工具没有
execute函数;- 工具调用需要通过
toolApproval或工具级needsApproval审批;- 达到停止条件(默认停止条件是
isStepCount(20))。
其配置项定义在 packages/ai/src/agent/tool-loop-agent-settings.ts,常用关键配置包括:
| 配置项 | 说明 | 默认值 |
|---|---|---|
model |
使用的语言模型(必填) | — |
instructions |
Agent 指令,可为字符串或带 provider options 的 SystemModelMessage |
— |
allowSystemInMessages |
是否允许在 prompt / messages 中携带 system 消息;关闭时系统消息只能走 instructions |
false |
toolChoice |
工具选择策略 | 'auto' |
stopWhen |
最后一步含工具结果时的停止条件,可传数组(任一满足即停) | isStepCount(20) |
activeTools |
限制模型可调用的工具子集,而不改变结果的工具类型 | — |
toolOrder |
控制工具定义发送给提供商的顺序,有助于保持工具定义顺序稳定、改善提供商侧缓存 | — |
output |
结构化输出规格 | — |
runtimeContext |
运行时上下文(应视为不可变,变更请在 prepareStep 中完成) |
— |
toolApproval |
工具审批配置,优先级高于工具自身定义的审批设置 | — |
repairToolCall |
修复解析失败工具调用的函数 | — |
prepareStep |
为每一步提供不同设置的函数 | — |
onStart / onStepStart / onToolExecutionStart / onToolExecutionEnd / onStepEnd / onEnd |
各阶段生命周期回调 | — |
providerOptions |
透传给提供商的额外选项 | — |
include |
控制步骤结果中携带的数据(如请求/响应体),关闭可降低大 payload(如图片)场景的内存占用 | 默认包含请求与响应体,排除请求消息 |
注意源码中以 experimental_ 开头或已标记 @deprecated 的别名(如 experimental_telemetry、experimental_onStart、experimental_repairToolCall、onStepFinish、onFinish)在后续大版本中会被移除,新代码应使用正式命名。
5.2 消费 Agent:端到端类型安全
Agent 在客户端被消费时,要做到端到端类型安全:从 Agent 定义推断 UI 消息类型(例如配合 useChat 使用)。仓库中对应实现为 packages/ai/src/agent/infer-agent-ui-message.ts,配套测试见 packages/ai/src/agent/infer-agent-ui-message.test-d.ts。React 侧 useChat 的泛型签名在 packages/react/src/use-chat.ts 中,它接受 UI_MESSAGE 泛型并返回类型化的 messages 数组(packages/react/src/use-chat.ts)。
消费 Agent 是框架相关的:先查看项目的 package.json 判断技术栈,再按对应框架的 quickstart 接入。本仓库 examples 目录提供了多框架参考实现,例如:
- examples/ai-e2e-next(Next.js + Agent 全流程示例);
- examples/harness-e2e-next(Harness 端到端示例);
- examples/harness-e2e-tui(终端 TUI Agent 示例);
- examples/next 等基础文本生成示例。
当前最新的 Agent、工具与类型安全 API 的权威说明,以随包文档(node_modules/ai/docs/,尤其 agents 章节)为准,其上游即仓库的 content/docs/03-agents 与 content/docs/03-ai-sdk-harnesses。
六、DevTools:开发期调试利器
AI SDK DevTools 会捕获你的 AI SDK 调用——请求、响应、工具调用、Token 用量以及多步运行过程——让你精确查看 Agent 每一步做了什么,适合在开发阶段调试生成结果。
使用要点:
- 它是独立的包(本仓库对应 packages/devtools,含 packages/devtools/src 的实现与 packages/devtools/examples 示例);
- 仅用于本地开发,不应部署到生产环境;
- 安装与接入方式以其随包文档为准(对应源码 packages/devtools/src 中可查阅具体 API 形态)。
七、保持 SDK 版本最新
过时的安装是 AI SDK 报错的最常见来源。开发时应对比已安装版本与最新版本:
- 已安装版本:查看
node_modules/ai/package.json的version字段; - 最新版本:运行
npm view ai version查询。
如果已安装版本落后最新版本一个主版本(或更多),应明确告知用户当前处于旧版本,并建议先升级再继续开发。迁移指南对应仓库中的 content/docs/08-migration-guides(本仓库还提供了专门的迁移技能 skills/migrate-ai-sdk-v6-to-v7)。仓库根目录 CHANGELOG.md 汇总了全部变更记录,是核对版本差异的第一手资料。
八、修改代码之后:跑类型检查,最小化配置
完成代码修改后,必须运行项目的类型检查器。实践中注意两点:
-
配置保持最小化——只设置与默认值不同的选项。判断默认值时先查文档或源码,而不是凭记忆过度指定。例如
ToolLoopAgent的stopWhen默认是isStepCount(20)(packages/ai/src/agent/tool-loop-agent-settings.ts),allowSystemInMessages默认false(同文件 packages/ai/src/agent/tool-loop-agent-settings.ts)——如果你要的就是默认行为,就无需显式传入。 -
绝大多数类型错误来自"记忆中的、已变更的 API"。遇到类型错误时,回头重新核对当前文档与源码,而不是试图用
as之类的断言强行绕过。
本仓库的 ai 包自带完整的类型检查与测试脚本(见 packages/ai/package.json:type-check 执行 tsc --build,test 同时跑 Node 与 Edge 环境的 vitest)。在你的业务项目中,运行相应框架的类型检查命令(如 tsc --noEmit)即可。
九、总结:一份可复用的 AI SDK 工作流
把 SKILL.md 的方法论落成日常开发工作流:
- 先装包:按需安装
ai,再按任务补装@ai-sdk/<provider>与@ai-sdk/<framework>; - 后查证:优先检索
node_modules/ai/docs/与node_modules/ai/src/(上游即本仓库 content/docs 与 packages/ai/src),其次才检索在线文档,找不到就明确说"不支持/未知"; - 接入模型:优先走 AI Gateway(
AI_GATEWAY_API_KEY+provider/model),模型 ID 一律先拉取/v1/models列表确认; - 构建能力:文本生成用
generateText/streamText,结构化输出用generateObject,Agent 用ToolLoopAgent,客户端消费配合useChat推断 UI 消息类型以获得端到端类型安全; - 调试与维护:开发期用 DevTools 观察请求、工具调用与 Token 用量;定期用
npm view ai version对比已装版本,落后主版本时提示升级并参考迁移指南; - 收尾验证:跑类型检查,配置只设与默认不同的值,遇到类型错误回到文档重新核对。
这套工作流的核心不是记住某个 API 的写法,而是建立一条"以版本匹配文档为准绳、以源码为证据"的查证链路——这正是 AI SDK 这类快速演进库的生存之道。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.21 K637- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python330
cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端TypeScript2 K146
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python46567
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go20043
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java33951