资讯详情

为 AI SDK 添加 first-party Provider 包:从 OpenAPI 契约分析到 npm 发布的全流程指南

📅 2026/9/12 16:18:10 | 华诺云谱 👁 阅读
为 AI SDK 添加 first-party Provider 包:从 OpenAPI 契约分析到 npm 发布的全流程指南
为 AI SDK 添加 first-party Provider 包从 OpenAPI 契约分析到 npm 发布的全流程指南【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai导读本指南面向想要在 AI SDKThe AI Toolkit for TypeScript仓库中新增一个官方一等公民first-partyai-sdk/provider包的开发者完整梳理了从阅读规范文档、分析服务商 OpenAPI 契约、规划模型形状、搭建包骨架、实现 Provider 工厂与模型类、落实安全 URL 处理与工作流序列化到编写测试与示例、补齐文档、准备 npm 发布并最终通过全量校验的端到端流程。读完本文你将掌握仓库内 Provider 包的统一结构约定、版本管理策略与发布前置条件能够参照现有包如ai-sdk/deepseek独立交付一个符合仓库规范、可被ai主包直接调用的新 Provider 包。一、动手前必须阅读的 Sources of TruthSKILL.md 反复强调在实现任何代码之前先阅读仓库中四份规范文档它们分别定义了包与发布要求、命名与序列化约定、Provider 抽象架构以及安全 URL 处理规则Add new provider定义 first-party 包与第三方包的边界、包版本初始化为2.0.0的规则、changeset 要求与 npm 引导步骤Provider development notesProvider 选项 Schema、响应 Schema、validateUrl约定、命名规则如AnthropicLanguageModelOptions与工作流序列化workflow serialization要求Provider architecture说明 AI SDK 采用适配器adapter模式的分层 Provider 架构——主包ai、规范包ai-sdk/provider、共享工具包ai-sdk/provider-utils与各 Provider 包如ai-sdk/openai之间单向依赖Provider 包最终调用外部服务商 APISecure URL handling当 Provider 需要拉取轮询、图片、音频、视频或其他来自响应体的 URL 时必须遵守的信任决策规则。同时文档建议把 PR #18595 当作一个最近的端到端参考实现但更重要的是选择当前仓库中 API 形状与模型类型最接近新 Provider 的现有包作为实现蓝本——照着一个真实、仍在维护的包抄写远比凭记忆重建配置可靠。first-party 与第三方包的边界任何服务商都可以在仓库之外自行发布第三方 Provider 包社区包同样会被官方文档收录与链接。但一个新的 first-partyai-sdk/provider包必须先在前置 issue 中讨论并达成共识确认存在明确意向之后才允许实现。这一点在 add-new-provider.md 中被明确为第一步。二、发现并固定 API Contract在设计模型类之前首先要寻找服务商官方、带版本号的 OpenAPI 或 Swagger 规范优先采用 first-party服务商官方规范并在实现说明或 PR 中记录规范来源 URL 及其版本号、发布日期或 commit用规范与官方文档交叉识别base URL 与认证方式、支持的端点/模型类型/能力、请求参数与响应形状、流式传输与事件格式、错误响应外壳error envelope、异步轮询与下载 URL 流程把 OpenAPI 规范当作实现证据而非不容置疑的真理。规范对 server-sent events、流式增量、多态内容、工具调用、可空字段和错误处理往往覆盖不全。默认不要引入生成式客户端或生成式生产类型应手写最小化的类型与 Zod Schema再对照官方文档和抓取的真实 API 响应进行核验若服务商没有官方规范则从官方文档和真实响应 fixture 中推导契约并在 PR 中说明这一局限。仓库中的真实包正是这一思路的产物以packages/deepseek为例其请求/响应类型手写在 deepseek-chat-api-types.ts配合__fixtures__/目录下deepseek-json.json、deepseek-tool-call.json、deepseek-reasoning.chunks.txt等抓取自真实 API 的 fixture 一起验证解析逻辑。三、规划 Provider 形状根据服务商实际能力确定新包要实现哪些 AI SDK 模型接口。ProviderV4定义于 provider-v4.ts规定了必须实现的工厂方法与可选的工厂方法接口工厂方法必选/可选LanguageModelV4languageModel(modelId)必选EmbeddingModelV4embeddingModel(modelId)必选ImageModelV4imageModel(modelId)必选TranscriptionModelV4transcriptionModel?(modelId)可选SpeechModelV4speechModel?(modelId)可选RerankingModelV4rerankingModel?(modelId)可选FilesV4files?()可选SkillsV4skills?()可选SKILL.md 还提到Experimental_VideoModelV4这类实验性接口可视服务商能力决定是否实现。在引入任何新依赖、公共 API 模式或抽象之前先阅读 contributing/decisions/README.md 及已接受的 ADR架构决策记录优先复用现有的 Provider 工具与实现模式避免重复造轮子。四、搭建包骨架Scaffold在packages/provider/下新建包推荐直接改编一个当前可比对的 Provider 包。典型结构如下packages/provider/ ├── src/ │ ├── index.ts │ ├── version.ts │ ├── provider-provider.ts │ ├── provider-provider.test.ts │ ├── provider-model-type-model.ts │ ├── provider-model-type-model.test.ts │ └── provider-model-type-options.ts ├── CHANGELOG.md ├── README.md ├── package.json ├── tsconfig.json ├── tsconfig.build.json ├── tsup.config.ts ├── turbo.json ├── vitest.node.config.js └── vitest.edge.config.js仓库中 packages/deepseek 的实际布局与之吻合src/deepseek-provider.ts、src/version.ts、src/index.ts、按模型类型拆分的src/chat/与src/files/子目录以及各自的*.test.ts/*.test-d.ts测试。所有文件保留当前仓库约定不要凭记忆重建配置具体要点版本号仓库包版本精确设置为2.0.0不带任何预发布后缀不要用2.0.0-canary.0。这样设置的目的见 add-new-provider.md 中的说明预发布后缀会把版本标记为 premajor之后 semver 对 premajor 的major提升只会摘掉后缀导致包永远卡在2.0.0-canary.N无法升到3.0.0从干净的2.0.0出发majorchangeset 才能正确计算出3.0.0-canary.0。注意这与 npm 上临时引导用的0.0.0是两套版本互不冲突CHANGELOG.md以# ai-sdk/provider作为首个标题构建使用 ESM 输出与当前tsup包版本注入模式。参考 packages/deepseek/tsup.config.ts入口src/index.ts及可选的src/internal/index.tsformat: [esm]、dts: true、sourcemap: true并通过define.__PACKAGE_VERSION__从package.json注入版本号供src/version.ts引用TypeScript继承./node_modules/vercel/ai-tsconfig/ts-library.json启用 composite 工程并为工作区依赖添加 project references脚本包含标准的 build、clean、type-check、Node 测试与 Edge 测试脚本。以 deepseek 为例build为pnpm clean tsup --tsconfig tsconfig.build.jsontest为pnpm test:node pnpm test:edge发布元数据包含标准files白名单dist/**/*、docs/**/*、src并排除测试文件、文档 prepack、repository、bugs、engines、公共 provenance 发布配置publishConfig.access: public、publishConfig.provenance: true依赖AI SDK 工作区依赖一律用workspace:*如ai-sdk/provider: workspace:*、ai-sdk/provider-utils: workspace:*仅当测试确实用到ai-sdk/test-server时才加入它Zod支持仓库的 Zod 3 与 Zod 4 双 peer dependency 范围如zod: ^3.25.76 || ^4.1.8新实现的 Schema 使用zod/v4新增或变更工作区依赖后运行pnpm update-references同步根目录与各包的 TypeScript references。五、实现 Provider 工厂Provider 工厂是包的对外入口必须遵循当前仓库的工厂模式。以 deepseek-provider.ts 为模板可以归纳出以下实现要点定义继承ProviderV4的 Provider 接口并声明工厂方法的完整签名如(modelId: DeepSeekChatModelId): LanguageModelV4、languageModel(modelId): LanguageModelV4、chat(modelId): LanguageModelV4导出createProvider(settings)工厂与默认实例deepseek 同时导出了createDeepSeek与deepSeek默认实例当 Provider 有有意义的默认模型类型、且可比对的现有包也采用可调用模式时让 Provider 本身可被调用const provider (modelId) createLanguageModel(modelId)否则只返回 Provider 对象设置provider.specificationVersion v4与ProviderV4接口中的readonly specificationVersion: v4对齐实现ProviderV4要求的全部工厂方法languageModel、embeddingModel、imageModel对不支持的必要工厂方法抛出NoSuchModelError例如 deepseek 对embeddingModel与imageModel直接throw new NoSuchModelError({ modelId, modelType: embeddingModel })仅在确实改善 API 时添加短别名如chat、embedding、image支持 Provider 相关设置apiKey、baseURL、headers、自定义fetch。deepseek 的设置接口完整地定义了这四项baseURL默认值为服务商官方端点并用withoutTrailingSlash规整凭据加载与 User-Agent用loadApiKey读取 API Key传入environmentVariableName与descriptiondeepseek 使用DEEPSEEK_API_KEY用withUserAgentSuffix在请求头中追加ai-sdk/provider/VERSION形式的 UA 后缀从src/index.ts导出Provider 工厂、默认实例、公共选项类型、模型 ID 类型与VERSION。deepseek 的version.ts与index.ts正是这样组织的。六、实现模型类每个受支持的模型使用ai-sdk/provider中对应的模型接口如LanguageModelV4与ai-sdk/provider-utils的共享工具实现。选项与响应 Schema 的命名及宽容度规则按 providers.md 的约定命名Provider 特定模型选项的类型与 Zod Schema 遵循{Provider}{ModelType}Options模式如AnthropicLanguageModelOptions同一模型类型有多种实现时加限定符如OpenAILanguageModelChatOptions与OpenAILanguageModelResponsesOptionsProvider 全局选项用{Provider}ProviderOptions如GatewayProviderOptions。类型用 PascalCase 且必须从包导出Zod Schema 用 camelCase如openaiLanguageModelChatOptions且不得导出面向用户的选项 Schema尽量严格字段用.optional()除非null本身有意义响应 Schema保持最小不包含未使用的属性、容忍 Provider 未知字段使用.nullish()而不是.optional()以容纳 API 可能省略或返回null的情况。工作流序列化Workflow Serialization所有模型类必须实现工作流序列化契约以便模型对象能跨工作流步骤边界传递。这在 providers.md 中有明确要求SKILL.md 将其归纳为四点模型配置中的headers必须为可选headers?:而非headers:访问时用可选链this.config.headers?.()或对Resolvable类型做条件判断添加静态 serde 方法[WORKFLOW_SERIALIZE]与[WORKFLOW_DESERIALIZE]使用ai-sdk/provider-utils的serializeModel/deserializeModel/serializeModelOptions等辅助函数classId由工作流 SWC 编译器在构建时生成不要手写确保认证等不可序列化函数能从请求选项或工作流环境环境变量中恢复。以 deepseek-chat-language-model.ts 为例其实现是static WORKFLOW_SERIALIZE { return serializeModelOptions({ modelId: model.modelId, config: model.config, }); } static WORKFLOW_DESERIALIZE { return new DeepSeekChatLanguageModel(options.modelId, options.config); }serializeModel()会自动过滤掉不可序列化的配置属性headers、fetch、generateId等函数以及包含函数的对象如errorStructure、metadataExtractor反序列化得到的模型不会携带headers认证、fetch、generateId或supportedUrls认证必须来自工作流步骤上下文中的请求级选项或环境变量。七、安全地处理响应、错误与 URLSKILL.md 对本节给出了严格的硬性规定并与 secure-url-handling.md 相呼应生产代码中绝不使用JSON.parse一律使用ai-sdk/provider-utils的parseJSON或safeParseJSON用最小 Schema 与共享响应处理器校验成功/失败响应例如createJsonResponseHandler与createJsonErrorResponseHandler。deepseek 的模型类构造函数中就通过createJsonErrorResponseHandler({ errorSchema, errorToMessage })装配了错误响应处理器只有当包需要新的公共 SDK 错误类型时才自定义AISDKError子类普通 Provider HTTP 失败走共享的 API 错误处理即可每一次getFromApi调用都必须显式设置validateUrl。该选项在类型上是可选的仅仅是为了不破坏ai-sdk/provider-utils的外部调用者——省略它等同于跳过校验因此仓库内 Provider 代码绝不允许漏写。CI 中的ai-sdk/require-validate-urloxlint 规则位于 tools/oxlint-plugin-ai-sdk会强制这一点任何未显式传validateUrl的getFromApi调用都会让pnpm check失败。validateUrl 的 true / false 决策validateUrl: true——URL 主机来自 Provider 响应体如json.audio.url、image.url等下载 URL或finalPrediction.urls.get等轮询 URL属于可被攻击者影响的数据。请求会经过fetchWithValidatedRedirects拒绝私有/回环/link-local 目标并重新校验每一跳重定向被拦截的 URL 抛出DownloadErrorvalidateUrl: false——URL 由开发者配置的端点拼接而来${config.baseURL}/…最多只插值路径段或 id主机由配置固定不会构成 SSRF判定口诀只要主机或超出路径段的任何部分来自响应体或认证轮询需要校验重定向就用validateUrl: true。trustedOrigin 与 credentialedOrigintrustedOrigin当合法的响应 URL 指向开发者配置的私有或自托管端点本地 Replicate 兼容 cog server、内部 fal 部署时把配置的 base URL 传给trustedOrigin与它同源的跳转跳过目标校验其余每一跳仍被校验。注意trustedOrigin必须是开发者配置的值绝不能从响应数据推导credentialedOrigin当凭据如 API Key可能合法地在第一跳发送如同主机的轮询 URL时传入保证凭据只在与其同源的 URL 上发送跨源 URL 与重定向一律不携带凭据。示例来自 secure-url-handling.md用于响应体轮询 URLawait getFromApi({ url: pollUrl, // from the response body validateUrl: true, credentialedOrigin: this.config.baseURL, trustedOrigin: this.config.baseURL, headers: authHeaders, successfulResponseHandler, failedResponseHandler, fetch: this.config.fetch, });在 Node.js 上默认的已校验下载 fetch 会在undiciconnector hook 内解析全部 DNS 记录若任一地址为私有/内网则整体拒绝并把校验后的精确记录返回给 connector从而固定连接目标、防止 DNS rebinding注入或全局替换的自定义fetch必须提供等效的连接时校验其他服务端运行时没有 Node 的 DNS/socket hook应通过限制网络出口来加固。实现任何轮询或 Provider 提供的下载 URL 流程前务必通读 secure-url-handling.md。八、针对真实契约编写测试SKILL.md 要求为新包添加聚焦测试覆盖范围包括Provider 默认值、自定义设置、工厂别名与不支持的模型类型请求序列化与响应解析流式事件、usage、finish reasons、warnings、工具调用与 Provider 元数据视支持情况错误响应解析与畸形响应工作流序列化与反序列化轮询/下载的 URL 信任决策Node.js 与 Edge 两个运行时仓库每个包都同时提供vitest.node.config.js与vitest.edge.config.js。尽可能使用真实 Provider 响应作为 fixture。动手抓取之前先读 capture API response fixture skill。超大 fixture 只有在不改变语义的前提下才允许裁剪。deepseek 包的src/chat/__fixtures__/下存放了deepseek-json.json、deepseek-reasoning.chunks.txt、deepseek-tool-call.json等真实抓取数据__snapshots__/下则是快照测试结果可以作为组织 fixture 的范本。九、添加示例与仓库集成添加示例前先阅读 AI Functions example skill。每个受支持的模型类型入口示例放在examples/ai-functions/src/function/provider/basic.ts其余示例放在同一 Provider 目录下用描述性的kebab-case.ts命名禁止创建src/generate-text/provider.ts这类扁平文件。仓库现状与此一致例如 generate-text/deepseek/ 下就有basic.ts、chat.ts、reasoner.ts、output-json.ts等多个 kebab-case 示例以 moonshotai 的 basic.ts 为参照示例形态通常是一段调用generateText或对应函数并打印result.text、result.usage、result.finishReason的脚本。同时更新仓库集成点在examples/ai-functions/package.json中加入ai-sdk/provider依赖在examples/ai-functions/tsconfig.json中加入对应的 project reference在examples/ai-functions/.env.example中加入所需凭据该文件已按 Provider 列出了DEEPSEEK_API_KEY、MOONSHOT_API_KEY等全部环境变量名需要时把凭据名加入根目录 turbo.json 的环境配置运行pnpm update-references同步根目录与包的 TypeScript references。最后用真实 API 运行有代表性的示例确认非流式与流式行为均符合预期流式能力视 Provider 支持情况而定。十、补齐包与 Provider 文档编写包级README.md覆盖安装、认证、配置、支持的模型与基本用法在content/providers/01-ai-sdk-providers/last number 10-provider.mdx新增 Provider 文档页包含 setup、模型能力、Provider 选项与示例编号规则见 add-new-provider.md取目录中最后一个编号 10例如 deepseek 对应30-deepseek.mdx配置包的文档 prepack 脚本把该 Provider 页一并打包。参考 packages/deepseek/package.json 的做法prepack: mkdir -p docs cp ../../content/providers/01-ai-sdk-providers/30-deepseek.mdx ./docs/, postpack: del-cli docs同时package.json中files包含docs/**/*、directories.doc指向./docs保证文档随包发布。十一、准备发布changeset为新包创建majorchangeset发布流程使用 changesets仓库包版本保持干净的2.0.0不要加-beta、-canary或其他预发布后缀npm 引导关键前置条件首次自动化发布前需要由 Vercel IT 团队在 npm 上引导一个空的ai-sdk/provider包版本0.0.0并配置 Trusted Publisher。npm 要求包先存在才能配置 Trusted Publisher因此首次发布必须由拥有ai-sdkscope 发布权限的成员在 monorepo 外手动执行新建空目录 → 写一个仅含name与version: 0.0.0的package.json→npm publish→ 在 npm 包管理页配置 Trusted PublisherPublisher 为 GitHub Actions仓库vercel/ai工作流release.yml。完整步骤见 releases.md#bootstrapping-a-new-ai-sdk-package。这个临时的 npm 引导版本与仓库包版本是两套体系互不影响pre-release 注意事项当main处于预发布模式时不要将新包 backport 到稳定的vX.Y分支否则退出预发布模式后会引发 npm 版本冲突所有包都通过publishConfig.provenance: true、release workflow 的id-token: write权限与逐包配置的 Trusted Publisher 发布带 npm provenance 的制品。十二、验证完整变更至少运行以下命令将provider替换为实际包名pnpm --filter ai-sdk/provider build pnpm --filter ai-sdk/provider test pnpm --filter ai-sdk/provider type-check pnpm type-check:full pnpm check此外用所需 Provider 凭据运行新增示例当变更涉及共享包或构建配置时运行根目录构建。十三、完成清单SKILL.md 以一份可勾选的完成清单收尾逐项对应上述全部环节可作为 PR 提交前的自查表first-party 包已在 issue 中获批已审阅官方 OpenAPI 规范或记录其缺失API 规范已对照官方文档与真实响应核验已选定可比对的现有 Provider 实现仓库包以2.0.0版本创建已添加包、TypeScript、构建、测试、provenance 与文档配置Provider 工厂实现ProviderV4已实现受支持的模型类与公共选项类型每个模型类均已实现工作流序列化响应解析、错误处理与 URL 获取符合仓库安全规则Node 与 Edge 测试在代表性响应 fixture 下通过嵌套 AI Functions 示例已添加并成功运行示例依赖、TypeScript references、环境变量与 Turbo 配置已更新README 与 Provider 文档已添加已添加 major changeset已协调 npm 包与 Trusted Publisher 引导包构建、测试、全量类型检查与仓库检查全部通过这份清单连同前文的步骤构成了一条从零到发布、可重复执行的 first-party Provider 交付路径。任何新包在合并前都应逐条满足这些约束从而与仓库内既有 Provider如ai-sdk/openai、ai-sdk/deepseek、ai-sdk/moonshotai保持一致的接口契约、安全水位与发布纪律。【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。