Назад до блогу

API та SDKПосібник

Перший запит у Ruby з гемом openai: base_url, ключ, usage

Короткий скрипт на Ruby: офіційний гем openai, власний base_url і ключ із env. Друкує текст відповіді та використання токенів.

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

Скрипт на Ruby з OpenAI::Client.new і власним base_url, що вказує на CheapTokens
На цій сторінці
  1. Що потрібно перед початком
  2. Скрипт
  3. Читання відповіді
  4. Скільки коштує такий виклик
  5. Якщо не запускається
  6. Куди рухатися далі

Так, офіційний гем openai працює з CheapTokens: передайте base_url: "https://api.cheaptokens.dev/v1" і ваш ключ у OpenAI::Client.new, викличте client.chat.completions.create і прочитайте текст із choices.first.message.content. Решта цієї сторінки — повний скрипт, як читати те, що повертається, і що перевіряти, коли він не запускається.

Припустімо, у вас є rake-задача, яка позначає теги підтримки, або фонова задача, яка підсумовує нотатку перед збереженням. Ви хочете офіційний SDK, а не саморобний HTTP, і хочете бачити, скільки токенів використав кожен виклик. Саме це й робить цей скрипт.

Що потрібно перед початком#

Сторінка гема на RubyGems (перевірено 8 листопада 2026) вказує openai 0.120.0, випущений 5 листопада 2026, Apache-2.0. Йому потрібен Ruby 3.3.0 або новіший; якщо ви застрягли на Ruby 3.2, власні примітки гема вказують на лінійку 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 гема. Усе інше — той самий код, і це вся суть OpenAI-сумісного API. Якщо ідея нова, що таке base_url і як його змінити пояснює це на аналогії з рестораном.

Ідентифікатор моделі — повний, deepseek-ai/DeepSeek-V4-Flash-0731. Коротка назва з таблиці цін не приймається API; беріть ідентифікатори з документації CheapTokens або з GET /v1/models.

Термінал із рядком Gemfile, експортованим ключем і ruby ask.rb
Три команди: зафіксувати гем, експортувати ключ, запустити скрипт.

Читання відповіді#

Відповідь — це об'єкт, а не хеш, тому ви викликаєте на ньому методи. Текст міститься за completion.choices.first.message.content; це той самий шлях, який використовує README гема.

Ще два рядки варто друкувати з першого дня:

  • finish_reason повідомляє, чому модель зупинилася. stop — це нормальне завершення. length означає, що відповідь обрізано через обмеження довжини. Якщо ви це побачите, чому відповіді обрізаються і як це виправити.
  • usage містить токени, за які було виставлено рахунок за виклик: те, що ви надіслали, і те, що написала модель. Скрипт друкує весь об'єкт за допомогою puts completion.usage, тож ви бачите обидва числа так, як їх повернув API.

Навіщо їх логувати? Бо токени — це рахунок. Питання з одного речення з відповіддю з одного речення — це дрібниця, але задача, що запускається тисячу разів на день, — ні. Вхідні vs вихідні токени пояснює, чому друге число зазвичай коштує більше за токен.

Скільки коштує такий виклик#

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 вихідних токенів на запит. Ціни за 1 млн токенів актуальні та змінюються разом із нашими тарифами; стовпець 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 і не має додаткового шляху після нього. Потім перевірте ідентифікатор моделі: це повний ідентифікатор із префіксом deepseek-ai/.

cannot load such file -- openai

Гем не встановлено для цього Ruby. Запустіть bundle install і запустіть скрипт за допомогою bundle exec ruby ask.rb.

Bundler can't find a version that works

Перевірте ruby -v. Лінійка 0.120.x потребує Ruby 3.3.0 або новішого; на 3.2 зафіксуйте натомість лінійку 0.75.x.

Випадки 401 і 404 трапляються з кожним SDK, не лише з Ruby; API 401 або 404: неправильний ключ, base URL або ідентифікатор моделі проходить їх по порядку.

Швидка перевірка

Що вам каже finish_reason "length"?

Показати відповідь

Відповідь: Відповідь було обрізано через обмеження довжини

stop — це нормальне завершення; length означає, що відповідь досягла ліміту, перш ніж модель закінчила.

Куди рухатися далі#

Тепер у вас є найменший корисний цикл: надіслати, прочитати текст, залогувати токени. Звідси оберніть виклик у метод і додайте числа usage до свого логера. Той самий шаблон існує в інших мовах, якщо ваш стек змішаний: Go, Java і C#. Повний список моделей і цін — на сторінці моделей, а довідка API — у документації.