ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI SDK 的 @ai-sdk/openai-compatible 包:从 ChangeLog 看 OpenAI 兼容 Provider 的演进与技术实现

AI SDK 的 @ai-sdk/openai-compatible 包:从 ChangeLog 看 OpenAI 兼容 Provider 的演进与技术实现 AI SDK 的 ai-sdk/openai-compatible 包从 ChangeLog 看 OpenAI 兼容 Provider 的演进与技术实现【免费下载链接】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本文以当前仓库中 packages/openai-compatible/CHANGELOG.md 为主线系统梳理ai-sdk/openai-compatible包的核心能力、版本演进与底层实现它如何以一套轻量的createOpenAICompatible工厂方法对接所有遵循 OpenAI API 形态的第三方服务以及流式工具调用、token 用量解析、推理流reasoning、结构化输出等关键特性在源码中是如何落地的。读完本文你将掌握该包的配置全貌、常用 providerOptions并能从 CHANGELOG 与源码的对应关系出发理解 OpenAI 兼容生态中常见的兼容性坑及其修复思路。一、包定位AI SDK 中的 OpenAI 兼容 Provider 基座ai-sdk/openai-compatible是整个 AI SDK monorepo本仓库packages/openai-compatible/中承担OpenAI 兼容协议适配职责的基础包。其定位在 README 中有明确说明它为实现任何暴露 OpenAI 兼容 API 的 Provider提供统一的基座与工厂方法与功能更丰富、包含 OpenAI 专属实验与遗留特性的 ai-sdk/openai 相比本包更轻量聚焦核心的 OpenAI 兼容能力社区中大量基于 OpenAI 协议二次封装的服务如各类代理网关、自建推理服务、兼容层都可以通过它快速接入。从 package.json 可以看到包的运行时依赖仅有ai-sdk/provider与ai-sdk/provider-utils两个 workspace 包peerDependencies 为zod ^3.25.76 || ^4.1.8运行时要求 Node.js 22CHANGELOG 3.0.0 中7fc6bd6明确最低支持 Node.js 22支持版本为 22、24、26。其构建产物为 ESM-onlytype: moduleCHANGELOG 3.0.0 的ef992f8变更即移除了所有 CommonJS 导出。包的源码结构src 目录清晰地划分为五类模型能力src/ ├── chat/ # Chat 语言模型OpenAICompatibleChatLanguageModel ├── completion/ # Completion 语言模型OpenAICompatibleCompletionLanguageModel ├── embedding/ # Embedding 模型OpenAICompatibleEmbeddingModel ├── image/ # 图像生成模型OpenAICompatibleImageModel ├── utils/ # providerOptions key 的 camelCase 转换等工具 ├── openai-compatible-provider.ts # createOpenAICompatible 工厂 └── openai-compatible-error.ts # 错误结构解析这一架构在 CHANGELOG 1.0.107ca3aeemove models into folders中成形并在后续版本中持续演进。二、快速上手createOpenAICompatible 工厂与四类模型2.1 基础用法按 README 的标准示例安装并创建 Provider 实例npm i ai-sdk/openai-compatibleimport { createOpenAICompatible } from ai-sdk/openai-compatible; import { generateText } from ai; const { text } await generateText({ model: createOpenAICompatible({ baseURL: https://api.example.com/v1, name: example, apiKey: process.env.MY_API_KEY, }).chatModel(meta-llama/Llama-3-70b-chat-hf), prompt: Write a vegetarian lasagna recipe for 4 people., });也可以通过headers自定义鉴权方式例如不使用apiKey选项而自行拼接Authorizationimport { createOpenAICompatible } from ai-sdk/openai-compatible; import { generateText } from ai; const { text } await generateText({ model: createOpenAICompatible({ baseURL: https://api.example.com/v1, name: example, headers: { Authorization: Bearer ${process.env.MY_API_KEY}, }, }).chatModel(meta-llama/Llama-3-70b-chat-hf), prompt: Write a vegetarian lasagna recipe for 4 people., });2.2 工厂方法产出的四类模型从 openai-compatible-provider.ts 的OpenAICompatibleProvider接口可见一个 Provider 实例对外暴露以下模型创建方法方法模型类型说明chatModel(modelId)/ 直接调用(modelId)LanguageModelV4聊天补全模型走/chat/completions语义completionModel(modelId)LanguageModelV4文本补全模型embeddingModel(modelId)EmbeddingModelV4向量嵌入模型textEmbeddingModel为已废弃别名imageModel(modelId)ImageModelV4图像生成模型createOpenAICompatible支持四个泛型参数分别约束上述四类模型的 ID从而在调用chatModel等时获得模型 ID 的自动补全README 中给出了完整示例type ExampleChatModelIds | meta-llama/Llama-3-70b-chat-hf | (string {}); const model createOpenAICompatible ExampleChatModelIds, string, // completion 模型 ID string, // embedding 模型 ID string // image 模型 ID ({ baseURL: https://api.example.com/v1, name: example, apiKey: process.env.MY_API_KEY, });从源码看createOpenAICompatible内部做了几件关键的统一处理openai-compatible-provider.tsbaseURL会经withoutTrailingSlash去掉尾部斜杠请求头统一合并apiKey自动加Bearer前缀与自定义headers并用withUserAgentSuffix附加ai-sdk/openai-compatible/${VERSION}的 User-Agent对应 CHANGELOG 1.0.17 的3aed04c变更支持queryParams向请求 URL 追加自定义查询参数对应 CHANGELOG 0.0.17 的ae57beb变更specificationVersion v4即实现的是 AI SDK Provider v4 规范。2.3 Provider 配置项全表OpenAICompatibleProviderSettings 定义了完整的配置项下表汇总各字段的作用与来源配置项类型说明引入版本CHANGELOGbaseURLstring必填API 基础地址如https://api.example.com/v10.0.1namestring必填Provider 名称用于 provider 元数据与 providerOptions 命名空间0.0.1apiKeystring自动生成Authorization: Bearer key头0.0.1443b37f7headersRecordstring, string自定义请求头0.0.1queryParamsRecordstring, string追加到请求 URL 的查询参数0.0.17ae57bebfetchFetchFunction自定义 fetch 实现测试、拦截中间件0.0.1includeUsageboolean流式响应中是否包含 usage 信息1.0.0737f1e2supportsStructuredOutputsbooleanChat 模型是否支持结构化输出JSON Schema 约束解码1.0.1828363datransformRequestBodyfunction发送前转换请求体适用于代理类 Provider2.0.1278a133ametadataExtractorMetadataExtractor从响应中提取 Provider 专属元数据0.1.2ed012d2、2.0.196900916supportedUrlsfunctionChat 模型支持的 URL 列表由源码结构推断的扩展点convertUsagefunction自定义 token 用量转换器适配记账语义不同的 Provider由源码结构推断的扩展点三、3.0.0 大版本面向 v7 的破坏性变更CHANGELOG 中 3.0.0 是内容最丰富的一个版本节点其中的 Major Changes 定义了 v7 时代的整体方向3.1 ESM-only 与 Node 版本门槛ef992f8所有包移除 CommonJS 导出全面转为 ESM-only。使用require()的消费者必须切换到 ESMimport语法7fc6bd6最低 Node.js 版本提升到 22支持 22、24、26。3.2 顶层 reasoning 参数与 Provider 规范升级74d520f各 Provider 迁移到新的顶层reasoning参数8f3e1daopenai-compat 的 v3 规范升级到 v4c29a26f支持 Provider 引用provider references与按 Provider 能力上传文件04e9009统一 Provider 实现的代码模式重命名了部分导出符号旧名称通过 deprecated alias 继续可用。3.3 工作流Workflow序列化支持b3976a2为所有 Provider 模型增加了跨工作流步骤边界的序列化能力ai-sdk/provider-utils新增serializeModel()助手只提取模型实例中可序列化的属性过滤函数及包含函数的对象所有 Provider 模型类新增静态方法WORKFLOW_SERIALIZE与WORKFLOW_DESERIALIZEProvider 配置类型中headers变为可选——当模型从工作流步骤边界反序列化、鉴权由外部单独提供时可以省略headers。这一设计在 openai-compatible-chat-language-model.ts 中有直接实现OpenAICompatibleChatLanguageModel通过serializeModelOptions序列化modelId与config。四、流式工具调用StreamingToolCallTracker 与安全修复演进流式工具调用是 OpenAI 兼容生态中最容易出现兼容性问题的环节之一CHANGELOG 围绕它有多轮修复均可在 openai-compatible-chat-language-model.ts 中找到对应实现StreamingToolCallTracker在约第 470、548、697、718 行处被实例化、注册与flush。4.1 防止可解析的部分 JSON提前终结工具调用安全修复3.0.6ac306ed与3.0.0中的45b3d76记录了一个关键的安全修复流式工具调用的参数此前使用isParsableJson()作为是否完成的启发式判断。如果累积的部分 JSON 恰好是合法 JSON但它可能只是更长参数串的前缀工具调用就会被提前执行——用不完整的参数执行。修复方案工具调用的终结finalize只在flush()中、流被完全消费后发生。f807e45进一步将StreamingToolCallTracker抽取到ai-sdk/provider-utils在 OpenAI 兼容 Provider 之间去重流式工具调用处理逻辑并确保所有 Provider 在流 flush 时终结未完成的工具调用。4.2 工具调用 delta 的缓冲与索引兼容3.0.0ab81968缓冲工具调用 delta直到function.name到达后再处理——因为部分 Provider 会先发id/index再发name3.0.231bec07d修复了非零、非连续、复用或缺失索引的流式工具调用3.0.32e6087c9处理空字符串的工具调用 IDtoolCallId3.0.44e5a22f0当 delta 包含空的工具调用数组时保持 reasoning 流的连续性3.0.55c5c0f5为转录模型如 OpenAIgpt-realtime-whisper、xAI WebSocket STT增加实验性流式转录支持。4.3 流式语义细节2.0.878fcb18流式输出中先发reasoning-end再发text-start3.0.09f1e1ba接受 OpenAI 兼容 Provider 流式 delta 块中的空字符串role1.0.8515c891修复某些场景下tool-input-start重复发送的问题1.0.2b499112过滤空 content 以保证 chunk 顺序正确。五、Token 用量解析usage.raw、宽松 Schema 与推理 token 归零5.1 从非标准响应中宽松解析 usageOpenAI 兼容生态的 Provider 在usage字段上差异极大CHANGELOG 对此有持续投入2.0.279e490ad与2.0.5d54c380将 usage 相关 Schema 从z.object改为z.looseObject以兼容非标准的 OpenAI 兼容 API1.0.45f4c71f/da314cd当顶层没有usage时回退到在choices中查找 usage3.0.3186892f3保留未映射的 usage 字段到usage.raw——将嵌套的prompt_tokens_details与completion_tokens_details也改为宽松解析。此前 Provider 在这些嵌套对象中返回的区分性信息如audio_tokens、image_tokens、text_tokens会被丢弃且 completion 模型的 usage Schema 此前一直是严格模式。该变更只影响usage.raw映射后的 token 计数不受影响。5.2 默认 usage 转换的源码实现默认的转换逻辑在 convert-openai-compatible-chat-usage.tsexport function convertOpenAICompatibleChatUsage(usage) { if (usage null) return createNullLanguageModelUsage(); const promptTokens usage.prompt_tokens ?? 0; const completionTokens usage.completion_tokens ?? 0; const cacheReadTokens usage.prompt_tokens_details?.cached_tokens ?? 0; const reasoningTokens usage.completion_tokens_details?.reasoning_tokens ?? 0; return { inputTokens: { total: promptTokens, noCache: promptTokens - cacheReadTokens, cacheRead: cacheReadTokens, cacheWrite: undefined, }, outputTokens: { total: completionTokens, text: Math.max(0, completionTokens - reasoningTokens), reasoning: reasoningTokens, }, raw: usage, }; }两个值得注意的细节与 CHANGELOG 直接对应text: Math.max(0, completionTokens - reasoningTokens)即3.0.2883e6510的修复当 Provider 报告的completion_tokens_details.reasoning_tokens大于completion_tokens时Baseten 托管推理模型在推理中途命中长度上限时会出现把outputTokens.text钳制在 0文本部分的完成 token 数不可能为负而total与reasoning保持 Provider 原始报告值raw: usage保留完整原始结构配合 3.0.31 的宽松解析确保 Provider 特有信息不丢失。5.3 其他 usage 相关变更0.1.10a699f1新增推理 token 支持0.2.5d186cca增加额外 token 用量指标1.0.0cf8280e修复 xAI 流式返回 NaN 的问题改为返回真实 usage3.0.205fc7da5/93b2acd将空 usage 的创建与响应元数据转换集中到 provider-utils3.0.3499989ba为图像生成报告 token 用量。六、推理流Reasoning与 thought 兼容推理类模型是 OpenAI 兼容 Provider 的重头戏CHANGELOG 记录了以下能力演进0.1.10a699f1推理 token 支持1.0.3a0934f8除reasoning_content外也支持在reasoning字段中查找推理内容2.0.7cd7bb0e为 Google 模型增加thoughtSignature处理Gemini 的思考签名2.0.20a1a0175多轮工具调用时在助手消息中包含reasoning_content——确保携带推理内容的对话上下文在后续轮次不丢失3.0.36ece5bdb当顶层 reasoning 被禁用时发送reasoning_effort: none3.0.322f77de8为自定义命名的 OpenAI 兼容 Provider 保留 Gemini thought 签名1.0.14818f021避免请求体中出现冗余的reasoningEffort字段统一使用reasoning_effort1.0.042e32b0/7b069ed新增reasoningEffortprovider option且允许任意字符串值。6.1 Chat 模型的 providerOptionsopenai-compatible-chat-language-model-options.ts 定义了 Chat 模型可用的 providerOptions通过providerOptions.openaiCompatible传入选项类型默认值说明userstring—终端用户唯一标识帮助 Provider 监控与防滥用reasoningEffortstringmedium推理模型的推理强度textVerbositystringmedium生成文本的详细程度2.0.0 的b689220引入strictJsonSchemabooleantrue是否使用严格 JSON Schema 校验约束解码保证 Schema 合规仅在 Provider 支持结构化输出且提供了 Schema 时生效2.0.9 的bc02a3c引入6.2 providerOptions 的 key 命名演进CHANGELOG 记录了 providerOptions key 从 kebab-case 到 camelCase 的完整迁移2.0.157116ef3统一使用 camelCase 的openaiCompatiblekeykebab-case 的openai-compatible废弃但仍支持带 console 警告3.0.0-beta.19008271d使用 kebab-case 时发出警告3.0.0816ff67在 chat 与 completion 模型中同时尊重 camelCase 的 providerOptions key2.0.1678555ad接受非 OpenAI 的 Provider 选项。七、图像模型与多模态内容7.1 图像生成的 providerOptionsopenai-compatible-image-model-options.ts 定义了图像模型的公共 providerOptions使用z.looseObject以便额外 Provider 专属选项透传选项类型说明sizestring生成图像尺寸取值范围取决于 Provider 与模型qualitystring生成图像质量output_formatstring输出文件格式output_compressionnumber0–100JPEG/WebP 压缩级别backgroundstring背景行为3.0.138b52503为图像模型请求增加了可扩展的providerOptions类型并停止强制发送response_format。7.2 图像设置迁移1.0.0 破坏性变更1.0.0 的516be5b将图像模型设置移入 generate optionsmaxImagesPerCall直接传给generateImage()其余设置通过providerOptions传入。CHANGELOG 给出了迁移前后对照// 迁移前设置挂在模型实例上 await generateImage({ model: luma.image(photon-flash-1, { maxImagesPerCall: 5, pollIntervalMillis: 500, }), prompt, n: 10, }); // 迁移后maxImagesPerCall 直接传入其余走 providerOptions await generateImage({ model: luma.image(photon-flash-1), prompt, n: 10, maxImagesPerCall: 5, providerOptions: { luma: { pollIntervalMillis: 5 }, }, });7.3 多模态内容转换3.0.357dd9ec3将视频文件 part 转换为video_urlcontent part1.0.58f8a521使用convertToBase64将Uint8Array图像 part 转为合法的 data URL同时保留 mediaType 归一化与 URL 直通3.0.4123eb659数组式 chat completion content 支持文本与思考 part并忽略未知 part 类型2.0.141612a57支持一次传递多种文件类型2.0.3389caf28解码 base64 字符串数据。八、错误处理与兼容性细节8.1 流式与错误语义3.0.110b61267保留 chat completion SSE 流中的结构化错误数据3.0.46ccb8952当 chat completion 的 choices 为空时返回 AI SDK 错误而非静默吞掉3.0.33d68139c将截断的 chat 流报告为错误3.0.06fd51c0在getErrorMessage中保留错误类型前缀。错误结构由 openai-compatible-error.ts 提供OpenAICompatibleErrorData与ProviderErrorStructure也通过 src/index.ts 对外导出便于自定义错误解析。8.2 消息转换细节3.0.0cd9c311仅对带工具调用的助手消息发送content: null3.0.0-beta.31bfb756d对纯工具助手消息发送content: null而非空字符串0.0.1270003b8允许通过 metadata 扩展消息0.0.3a9a19cb防止发送重复的工具调用。8.3 其他值得注意的变更0.0.86faab13引入、1.0.06db02c9移除的模拟流式设置simulateStreaming1.0.0b9a6121将tool_call类型 Schema 改为 nullish允许 Provider 不指定 function 类型1b101e11.0.0737f1e2createOpenAICompatible的可选includeUsage选项0.1.7f2c6c37在generateText/streamText中支持 providerOptions0.1.13e1d3d42在generateText与generateObject中暴露原始响应体0.0.136564812导出更多自定义扩展点2.0.03bd2689扩展 token 用量模型0c4822d新增EmbeddingModelV32.0.0 的8d9e8ad将textEmbeddingModel泛型化调用改为embeddingModel。九、从 CHANGELOG 到工程实践的三点启示综合来看这份 CHANGELOG 本身就是一份难得的OpenAI 兼容协议踩坑手册可以提炼出三条对开发者有直接价值的经验兼容性问题的重灾区是流式工具调用参数缓冲等待function.name、索引乱序非零/非连续/复用、部分 JSON 提前终结——这些问题在本包中被系统性修复并最终收敛为StreamingToolCallTracker统一处理。如果你在自研兼容 Provider应优先对齐这套行为。usage 解析必须宽松进、严格出z.looseObject、choices回退、usage.raw保留原始字段共同保证非标准 Provider 的 token 信息不丢失同时映射后的inputTokens/outputTokens语义cacheRead、reasoning、text保持 AI SDK 的统一口径。命名与规范要跟随 v7 大版本ESM-only、Node 22、顶层reasoning参数、embeddingModel命名、camelCase 的openaiCompatibleproviderOptions key——升级到 v3/v7 时需要重点检查这些破坏性变更点。如果需要进一步探索实现细节可以直接阅读 聊天模型实现、usage 转换、provider 工厂 以及对应的 测试用例其中__fixtures__目录下还保留了 xAI、Anthropic 回退等真实 SSE 流样本可作为理解协议细节的第一手资料。【免费下载链接】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),仅供参考
返回列表