@ai-sdk/openai 成本控制:模型选择与用量上限

@ai-sdk/openai 是 AI SDK 的 OpenAI 适配器,可通过模型、推理强度和请求限制降低调用成本。

截至 2026-10-30,AI SDK 文档已更新到 v7,Provider Options 也明确了 OpenAI 专属配置入口。现在值得重新配置,是因为应用上线后,成本通常不是单次调用单价决定的,而是模型选择、重复上下文和缺少用量封顶共同累积;只换模型并不能解决问题。

先确定控制成本的三层边界

@ai-sdk/openai 只负责连接 OpenAI 模型。它不会因为包名里带有“开源 SDK”就自动提供免费额度,也不会替应用设置消费上限。当前官方材料能确认的是模型调用方式和 providerOptions 配置方式;没有给出统一的请求次数、Token 配额或账单价格表。

因此,应把成本控制拆成三层:

控制层 具体动作 适合解决的问题 最终验证方式
模型层 默认模型与高难任务模型分开 简单请求误用昂贵模型 日志中的模型字段
生成层 降低推理强度、限制输出长度 输出 Token 过多 响应中的 Token 用量
用量层 按用户、模型和时间窗口限制请求 单个租户持续消耗额度 限流日志与拒绝结果

官方 Provider Options 文档还指出:不同厂商的专属选项放在 providerOptions 下,并按厂商名称隔离;只有与当前模型提供方匹配的配置才会生效。这意味着不能把 Anthropic 的参数原样放进 OpenAI 请求,也不能依赖名称相近但未被当前 provider 识别的字段。

对于刚起步的 TypeScript 应用,下面的配置顺序最省事:先安装,再绑定模型,然后只给确实需要推理的请求增加专属参数,最后增加应用侧用量限制。

安装依赖并确认运行环境

先执行官方仓库给出的安装命令:

npm install ai

直接连接模型厂商时,再执行官方 README 中列出的 provider 安装命令:

npm install @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/google

这条命令会同时安装三个 provider;如果项目只使用 OpenAI,可从 package.json 中移除另外两个依赖,再运行安装命令。仓库 README 明确要求 Node.js 22+,可用下面的命令检查:

node -v
npm -v

确认 node -v 输出以 v22 或更高版本开头。否则先升级 Node.js,再继续安装或运行项目。AI SDK 仓库要求使用 Node.js 22+,并且说明 ai 是基础包;@ai-sdk/openai 则是直接连接 OpenAI 的独立 provider 包。

如果应用还需要让 Cursor、Claude Code 等编程代理直接阅读 AI SDK 文档,可以执行官方仓库提供的命令:

npx skills add vercel/ai

该命令属于可选步骤,不是调用 @ai-sdk/openai 的前置条件。

在两种接入方式中选择

AI SDK 默认通过 Vercel AI Gateway 使用模型,也可以直接连接具体厂商。前者调用方便,后者更便于把 provider 专属配置、账单归属和模型访问范围固定在项目内。

直接使用 OpenAI provider

直接接入方式的官方示例如下:

import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await generateText({
  model: openai('gpt-6-astra'),
  prompt: 'Hello!'
});

console.log(result.text);

先复制这段代码到项目现有调用位置,确认应用能够输出文本,再做后续修改。这里的 gpt-6-astra 来自官方仓库当前示例;模型是否对账户开放仍取决于 provider 侧权限,不能因为示例可写就假设任意账户都有权调用。

通过 AI Gateway 接入

Gateway 方式的官方示例是:

import { generateText } from 'ai';

const result = await generateText({
  model: 'openai/gpt-6-astra',
  prompt: 'What is an agent?'
});

console.log(result.text);

两种写法不要在同一次排错中来回切换,否则很难判断问题来自 OpenAI、Gateway 还是本地依赖。排查时固定一种方式:先确认直连可用,再切 Gateway;或者反过来。成本控制也应先选定接入路径,再统计对应账单的请求。

选择 调用形式 适合谁 排查重点
OpenAI provider openai('gpt-6-astra') 已有 OpenAI API 接入,希望直接使用专属选项 provider 凭据、模型权限、参数名称
AI Gateway 'openai/gpt-6-astra' 希望统一管理多个模型厂商 Gateway 配置、模型路由、账户归属

降低单次调用成本

模型选择的第一步不是寻找“最低价模型”,而是按任务难度分流:分类、改写和格式转换不需要使用推理能力最强的模型;多步规划、复杂代码分析才值得提高推理强度。AI SDK 的统一接口允许在代码中切换模型,因此可以为不同任务保留两个明确入口,而不是让所有请求都走同一个默认模型。

reasoningEffort 是 OpenAI provider 的专属选项。官方 Provider Options 文档给出的完整写法是:

import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await generateText({
  model: openai('gpt-6-astra'),
  prompt: 'Explain quantum entanglement.',
  providerOptions: {
    openai: {
      reasoningEffort: 'low'
    }
  }
});

console.log(result.text);

reasoningEffort: 'low' 表示把 OpenAI 的推理强度设为 low。官方文档同时建议:如果目标只是控制推理强度,应优先使用顶层的 reasoning 参数,因为它能跨 provider 使用;只有确实需要厂商专属能力,例如精确 Token 预算,才使用 providerOptions。

这段官方示例也揭示了一个容易忽略的点:providerOptions.openai 是命名空间。参数必须放在 openai 键下,不能写成顶层 reasoningEffort,也不能误放到 anthropic 命名空间。Provider Options 文档说明,同一次调用可以携带多个 provider 的选项,但只有与当前 provider 匹配的选项会被使用;这不等于其他 provider 的参数会被自动转换。

生成层还要检查两个容易漏掉的项目:

  1. 给输出设置合理上限,避免用户要求“尽可能详细”时无限拉长响应。
  2. 不要每轮都把完整历史和重复系统提示重新发送。Provider Options 文档支持在消息及消息片段级别应用选项,但长对话能否直接复用上下文,要结合当前 generateText 或 streamText 调用检查,不能仅凭 SDK 支持就假定会自动裁剪。

给请求加一层可执行的上限

“用量上限”必须区分两种含义:provider 账户上的可用额度和应用内部允许消耗的额度。前者由 OpenAI 账户侧决定;后者由业务代码控制。官方 Provider Options 示例没有展示一个通用的 maxCostUsd 或“达到预算自动停机”选项,因此不要把 providerOptions 当成账单封顶器。

应用侧上限至少要包含三个维度:调用频率、输入与输出 Token 预算,以及按用户或租户划分的累计消耗。社区已有 ai-sdk-rate-limiter 提供请求队列、成本统计、按模型与时间窗口限流以及预算触达回调。其 README 示例中可观察到的报告结构如下:

const report = limiter.getCostReport();

// hour:  { requests: 42,   inputTokens: 84_000,  outputTokens: 21_000, costUsd: 0.29 },
// day:   { requests: 318,  inputTokens: 620_000, outputTokens: 155_000, costUsd: 2.11 },
// month: { requests: 4821, inputTokens: 9_100_000, outputTokens: 2_200_000, costUsd: 34.80 },

这是第三方工具的实现示例,不是 AI SDK 官方结论。安装和初始化应以该项目的 npm 页面为准。它的成本统计按 API 响应返回的实际 Token 数量计算,而不是预先估算;报告窗口是滚动窗口,例如 hour 表示最近 60 分钟。

接入后先做一项小规模验证:给测试用户设置一个很小的预算,让程序持续请求到限制触发,再检查三件事:

  • 日志是否出现预算告警或 budgetHit 回调;
  • 超限后的请求是否没有继续发往 OpenAI;
  • getCostReport() 中按小时、天、月统计的请求数和 Token 数是否增长。

如果使用未知模型,该工具的公开说明是回退到默认 RPM 和 ITPM 限制,并且不提供成本跟踪。解决方法是先在模型注册表中补齐该模型的价格与限制,不要把“没有成本数字”误判为“没有发生调用”。

三个常见卡点及对应处理

参数已经填写,但模型表现没有变化。先检查 reasoningEffort 是否位于 providerOptions.openai 下。Provider Options 文档明确说明,provider 专属配置通过 providerOptions 传递,并按 provider 名称分命名空间。把参数移到顶层,或写进 anthropic 命名空间,都不会让当前 OpenAI provider 使用它。

切换成 Gateway 后,专属参数不生效。固定 model: 'openai/gpt-6-astra' 这一种写法做基线,再切回 openai('gpt-6-astra') 直连。若直连有效而 Gateway 无效,就沿 Gateway 路由、账户与模型权限检查;若两种写法都无效,再检查 @ai-sdk/openai 是否安装、模型 ID 是否拼写正确。

请求量突然升高,但单次 Token 看起来正常。不要只看模型单价,按用户、模型和滚动时间窗口查看累计报告。社区限流器会按实际响应 Token 统计成本,并支持 scope 区分用户;没有 scope 的请求不会进入按用户分组的统计。给入口请求设置稳定 scope,才能找出是哪一段流量在持续消耗预算。

怎么确认成本控制已经生效

同时满足下面四个可观察结果,才算配置完成:

  1. node -v 输出 Node.js 22 或更高版本。
  2. 最小 generateText 示例能够输出 result.text。
  3. 日志能记录实际使用的模型、输入 Token、输出 Token 和请求所属用户。
  4. 测试请求达到设定上限后被阻止,并出现预算告警;报告中的小时、天、月累计值继续更新。

如果最后两项还没有,就先不要扩大流量。AI SDK 官方文档把 ai 定义为用于构建 AI 应用与代理的 TypeScript 工具包,并提供统一的文本生成、结构化对象和工具调用接口;它统一了调用方式,但账单治理仍需要在模型路由和请求入口处完成。

官方入口与延伸阅读

参考来源

评论区

0 条评论

登录后可评论。

小土豆 104 阅读