返回博客

API 与 SDK指南

用 openai gem 在 Ruby 中发出第一个请求:base_url、密钥、用量

一个简短的 Ruby 脚本:官方 openai gem、自定义 base_url 和来自环境变量的密钥。打印回复文本和 token 用量。

作者:CheapTokens Team发布于 4 分钟阅读

Ruby 脚本,使用 OpenAI::Client.new 和指向 CheapTokens 的自定义 base_url
本页内容
  1. 开始之前你需要准备什么
  2. 脚本
  3. 解读返回内容
  4. 这样一次调用要花多少钱
  5. 如果运行不起来
  6. 接下来去哪里

是的,官方 openai gem 可以与 CheapTokens 配合使用:将 base_url: "https://api.cheaptokens.dev/v1" 和你的密钥传给 OpenAI::Client.new,调用 client.chat.completions.create,然后从 choices.first.message.content 读取文本。本页其余部分是完整脚本、如何解读返回内容,以及运行失败时该检查什么。

假设你有一个为支持工单打标签的 rake 任务,或者一个在保存笔记前先做摘要的后台作业。你想要官方 SDK,而不是手写 HTTP,并且想看到每次调用用了多少 token。这个脚本正是为此而写。

开始之前你需要准备什么#

RubyGems 上的 gem 页面(2026 年 11 月 8 日查看)列出 openai 0.120.0,发布于 2026 年 11 月 5 日,Apache-2.0。它需要 Ruby 3.3.0 或更新版本;如果你还停留在 Ruby 3.2,gem 自己的说明指向 0.75.x 系列。该包仍是 0.x 且迭代很快,所以要固定版本。

在你的 Gemfile 中:

ruby
gem "openai", "~> 0.120.0"

然后 bundle install。不用 Bundler 的话,gem install openai -v 0.120.0 效果相同。

你还需要 CheapTokens 账户的 API 密钥。不要把它写进代码:放进环境变量,如果 .gitignore 这个词对你来说很陌生,这篇关于保护密钥安全的指南 只需五分钟阅读。

bash
export CHEAPTOKENS_API_KEY="sk-your-key"

脚本#

创建 ask.rb:

ruby
require "openai"

client = OpenAI::Client.new(
  api_key: ENV.fetch("CHEAPTOKENS_API_KEY"),
  base_url: "https://api.cheaptokens.dev/v1"
)

completion = client.chat.completions.create(
  model: "deepseek-ai/DeepSeek-V4-Flash-0731",
  messages: [
    { role: "user", content: "Explain in one sentence what a token is." }
  ]
)

choice = completion.choices.first
puts choice.message.content
puts "finish_reason: #{choice.finish_reason}"
puts completion.usage

用 ruby ask.rb 运行它。有三处值得再看一眼。

用 ENV.fetch 而不是 ENV[...]。如果变量缺失,fetch 会立刻停止,并抛出一个指明该变量的 KeyError。ENV[...] 会悄悄传入 nil,几行之后你就会遇到令人困惑的认证错误。

base_url: 是唯一与 gem README 中 OpenAI 示例不同的行。其余代码完全相同,这正是 OpenAI 兼容 API 的意义所在。如果这个概念对你来说很新,base_url 是什么以及如何切换 用餐厅类比做了解释。

模型 id 要用完整的,即 deepseek-ai/DeepSeek-V4-Flash-0731。价格表中的短名称不被 API 接受;请从 CheapTokens 文档 或 GET /v1/models 获取 id。

终端中显示 Gemfile 行、导出的密钥和 ruby ask.rb
三条命令:固定 gem、导出密钥、运行脚本。

解读返回内容#

回复是一个对象,不是哈希,所以你要在它上面调用方法。文本位于 completion.choices.first.message.content;gem 的 README 也使用这个路径。

从第一天起就值得多打印两行:

  • finish_reason 告诉你模型为什么停止。stop 是正常结束。length 表示答案被长度限制截断。如果你看到这种情况,答案为什么会被截断以及如何修复。
  • usage 保存本次调用计费的 token:你发送的和模型写出的。脚本用 puts completion.usage 打印整个对象,所以你能看到 API 返回的两个数字。

为什么要记录它们?因为 token 就是账单。一个一句话的问题配一句话的回答很小,但每天运行一千次的作业就不小了。输入 token 与输出 token 解释了为什么第二个数字通常每 token 更贵。

这样一次调用要花多少钱#

CheapTokens 上的 DeepSeek-V4-Flash 是每 1M 输入 token $0.015,每 1M 输出 token $0.10,一天中任何时段价格相同。以一个工单打标签作业为例:每张工单约 300 输入 token、150 输出 token。一张工单花费 $0.00002。一千张工单如下所示,下一列是 OpenRouter 的参考价格:

模型 每次请求 1,000 次请求 OpenRouter,1,000 次请求
GLM-5.3-Flash $0.000012 $0.012 $0.0225
DeepSeek-V4-Flash $0.00002 $0.0195 $0.042
MiniMax-M2.7 $0.000038 $0.0375 $0.45

每次请求 300 个输入 token 和 150 个输出 token。每 100 万 token 的价格为当前价格,会随我们的资费一同变动;OpenRouter 列显示相同工作负载的参考价格。

该模型最多支持 380K token 上下文和单次回答最多 32,768 token,所以摘要作业很少会撞墙。如果你想用同一个脚本试试第二个模型,只需把 model: 字符串改成 zai-org/GLM-5.3-Flash(390K 上下文,最多 8,192 输出 token)。

如果运行不起来#

首次运行失败大多是五种情况之一。挑一个与你屏幕相符的。

选择你的情况

你看到什么?

KeyError: key not found: "CHEAPTOKENS_API_KEY"

该变量在这个终端中没有设置。再次运行 export 行,或打开新 shell 并用 echo $CHEAPTOKENS_API_KEY 检查。

401 Unauthorized

密钥存在但错误:多余的空格或引号、粘贴被截断,或旧密钥。从你的账户重新复制。

404 Not Found

先检查 base_url:它以 /v1 结尾,后面没有多余路径。然后检查模型 id:它是带 deepseek-ai/ 前缀的完整 id。

cannot load such file -- openai

该 gem 没有为这个 Ruby 安装。运行 bundle install 并用 bundle exec ruby ask.rb 启动脚本。

Bundler 找不到可用版本

检查 ruby -v。0.120.x 系列需要 Ruby 3.3.0 或更新版本;在 3.2 上请改为固定 0.75.x 系列。

401 和 404 情况会出现在每个 SDK 中,不只是 Ruby;API 401 或 404:密钥、base URL 或模型 id 错误 按顺序逐一讲解。

快速检查

finish_reason "length" 告诉你什么?

显示答案

答案: 答案被长度限制截断

stop 是正常结束;length 表示答案在模型完成之前就达到了限制。

接下来去哪里#

你现在有了最小可用的循环:发送、读取文本、记录 token。从这里开始,把调用包装成方法,并把 usage 数字加入你的日志记录器。如果你的技术栈是混合的,其他语言也有同样的模式:Go、Java 和 C#。完整的模型和价格列表在模型页面,API 参考在文档中。