Назад в блог

API и SDKИнструкция

Первый запрос в Ruby через gem openai: base_url, ключ, usage

Короткий Ruby-скрипт: официальный gem openai, свой base_url и ключ из окружения. Печатает текст ответа и расход токенов.

Автор: CheapTokens TeamОпубликовано 4 мин чтения

Ruby-скрипт с OpenAI::Client.new и своим base_url, указывающим на CheapTokens
Содержание
  1. Что нужно до начала
  2. Скрипт
  3. Как читать ответ
  4. Сколько стоит такой вызов
  5. Если не запускается
  6. Что дальше

Да, официальный gem openai работает с CheapTokens: передайте base_url: "https://api.cheaptokens.dev/v1" и свой ключ в OpenAI::Client.new, вызовите client.chat.completions.create и прочитайте текст из choices.first.message.content. Ниже — полный скрипт, разбор ответа и список того, что проверить, если он не запускается.

Допустим, у вас есть rake-задача, которая размечает обращения в поддержку, или фоновая джоба, которая сжимает заметку перед сохранением. Хочется официальный SDK вместо ручного HTTP и хочется видеть, сколько токенов ушло на каждый вызов. Это как раз тот скрипт.

Что нужно до начала#

Страница gem на RubyGems (сверено 8 ноября 2026) показывает openai 0.120.0, выпущен 5 ноября 2026, лицензия 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.

Ещё нужен API-ключ из вашего аккаунта CheapTokens. В код его не кладём, а храним в переменной окружения. Если слово .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: — единственная строка, которой скрипт отличается от примеров OpenAI в README gem. Всё остальное — тот же код, в этом и смысл OpenAI-совместимого API. Если идея новая, что такое base_url и как переключиться объяснено там на бытовом примере.

id модели — полный: deepseek-ai/DeepSeek-V4-Flash-0731. Короткое имя из таблицы цен API не принимает; id берите из документации CheapTokens или из GET /v1/models.

Терминал: строка Gemfile, экспорт ключа и запуск ruby ask.rb
Три команды: зафиксировать gem, экспортировать ключ, запустить скрипт.

Как читать ответ#

Ответ — объект, а не хеш, поэтому к нему обращаются методами. Текст лежит в completion.choices.first.message.content; тот же путь использует README gem.

Ещё две строки полезно печатать с первого дня:

  • finish_reason говорит, почему модель остановилась. stop — нормальный конец. length — ответ обрезал лимит длины. Если увидите это, здесь разобрано, как исправить.
  • usage — токены, за которые списали деньги: сколько вы отправили и сколько написала модель. Скрипт печатает объект целиком через puts completion.usage, так что оба числа видны так, как их вернул API.

Зачем их логировать? Токены — это и есть счёт. Вопрос в одну фразу с ответом в одну фразу почти ничего не стоит, но джоба, которая запускается тысячу раз в день, уже стоит. Почему вторая цифра обычно дороже за токен, объясняет статья про входные и выходные токены.

Сколько стоит такой вызов#

DeepSeek-V4-Flash в CheapTokens — $0.015 за 1M входных токенов и $0.10 за 1M выходных, в любое время суток одна и та же цена. Возьмём разметку обращений: около 300 токенов на входе и 150 на выходе. Одно обращение стоит $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 входных и 150 выходных токенов на запрос. Цены за 1M токенов актуальны и меняются вместе с нашими тарифами; столбец OpenRouter показывает справочные цены для той же нагрузки.

У модели контекст до 380K токенов и до 32 768 токенов в одном ответе, так что задачи на сжатие текста редко упираются в лимит. Хотите попробовать вторую модель тем же скриптом — поменяйте только строку model: на zai-org/GLM-5.3-Flash (контекст 390K, до 8 192 токенов в ответе).

Если не запускается#

Большинство сбоев при первом запуске — одно из пяти. Выберите то, что совпадает с вашим экраном.

Выберите свой случай

Что вы видите?

KeyError: key not found: "CHEAPTOKENS_API_KEY"

Переменная не задана в этом терминале. Выполните export ещё раз или откройте новую оболочку и проверьте через echo $CHEAPTOKENS_API_KEY.

401 Unauthorized

Ключ есть, но неверный: лишний пробел или кавычка, обрезанная вставка или старый ключ. Скопируйте его из аккаунта заново.

404 Not Found

Сначала проверьте base_url: он заканчивается на /v1, и после него нет лишнего пути. Затем id модели: он полный, с префиксом deepseek-ai/.

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; статья про 401 и 404 разбирает их по порядку.

Быстрая проверка

Что означает finish_reason "length"?

Показать ответ

Ответ: Ответ обрезал лимит длины

stop — нормальный конец; length — ответ упёрся в лимит раньше, чем модель закончила.

Что дальше#

У вас теперь минимальный полезный цикл: отправить, прочитать текст, записать токены. Дальше оберните вызов в метод, и добавьте числа из usage в свой логгер. Тот же приём есть и для других языков, если стек смешанный: Go, Java и C#. Список моделей и цен — на странице моделей, описание API — в документации.