Powrót do bloga

API i SDKPrzewodnik

Pierwsze żądanie w Ruby z gemem openai: base_url, klucz, usage

Krótki skrypt Ruby: oficjalny gem openai, własny base_url i klucz ze zmiennej środowiskowej. Wypisuje tekst odpowiedzi i zużycie tokenów.

Autor: CheapTokens TeamOpublikowano 4 min czytania

Skrypt Ruby z OpenAI::Client.new i własnym base_url wskazującym na CheapTokens
Na tej stronie
  1. Co potrzebujesz przed startem
  2. Skrypt
  3. Jak czytać odpowiedź
  4. Ile kosztuje takie wywołanie
  5. Jeśli nie działa
  6. Co dalej

Tak, oficjalny gem openai działa z CheapTokens: przekaż base_url: "https://api.cheaptokens.dev/v1" i swój klucz do OpenAI::Client.new, wywołaj client.chat.completions.create i odczytaj tekst z choices.first.message.content. Reszta tej strony to pełny skrypt, sposób odczytu odpowiedzi i to, co sprawdzić, gdy nie działa.

Załóżmy, że masz zadanie rake, które oznacza zgłoszenia do supportu, albo zadanie w tle, które streszcza notatkę przed zapisaniem. Chcesz użyć oficjalnego SDK, a nie ręcznego HTTP, i chcesz widzieć, ile tokenów zużyło każde wywołanie. Dokładnie temu służy ten skrypt.

Co potrzebujesz przed startem#

Strona gemu na RubyGems (sprawdzona 8 listopada 2026) podaje openai 0.120.0, wydany 5 listopada 2026, licencja Apache-2.0. Wymaga Ruby 3.3.0 lub nowszego; jeśli utknąłeś na Ruby 3.2, notatki samego gemu wskazują linię 0.75.x. Pakiet wciąż jest w wersji 0.x i szybko się zmienia, więc przypnij wersję.

W swoim Gemfile:

ruby
gem "openai", "~> 0.120.0"

Następnie bundle install. Bez Bundlera to samo robi gem install openai -v 0.120.0.

Potrzebujesz też klucza API ze swojego konta CheapTokens. Trzymaj go poza kodem: umieść go w zmiennej środowiskowej, a jeśli słowo .gitignore jest dla ciebie nowe, ten przewodnik po bezpiecznym przechowywaniu kluczy to lektura na pięć minut.

bash
export CHEAPTOKENS_API_KEY="sk-your-key"

Skrypt#

Utwórz 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

Uruchom go przez ruby ask.rb. Trzy rzeczy warte drugiego spojrzenia.

ENV.fetch zamiast ENV[...]. Jeśli zmiennej brakuje, fetch zatrzymuje się od razu z KeyError, który ją nazywa. ENV[...] po cichu przekazuje nil i kilka linii dalej dostajesz mylący błąd uwierzytelniania.

base_url: to jedyna linia różniąca się od przykładów OpenAI w README gemu. Cała reszta to ten sam kod, i o to właśnie chodzi w API zgodnym z OpenAI. Jeśli to dla ciebie nowość, czym jest base_url i jak go przełączyć wyjaśnia to na analogii z restauracją.

Identyfikator modelu jest pełny, deepseek-ai/DeepSeek-V4-Flash-0731. Krótka nazwa z tabeli cen nie jest akceptowana przez API; bierz identyfikatory z dokumentacji CheapTokens lub z GET /v1/models.

Terminal z linią w Gemfile, wyeksportowanym kluczem i ruby ask.rb
Trzy polecenia: przypnij gem, wyeksportuj klucz, uruchom skrypt.

Jak czytać odpowiedź#

Odpowiedź to obiekt, nie hash, więc wywołujesz na nim metody. Tekst znajduje się pod completion.choices.first.message.content; tej samej ścieżki używa README gemu.

Dwie kolejne linie warto wypisywać od pierwszego dnia:

  • finish_reason mówi, dlaczego model się zatrzymał. stop to normalne zakończenie. length oznacza, że limit długości uciął odpowiedź. Jeśli to zobaczysz, dlaczego odpowiedzi są ucinane i jak to naprawić.
  • usage zawiera tokeny, za które rozliczono wywołanie: to, co wysłałeś, i to, co napisał model. Skrypt wypisuje cały obiekt przez puts completion.usage, więc widzisz obie liczby tak, jak zwróciło je API.

Po co je logować? Bo tokeny to rachunek. Pytanie jednym zdaniem z odpowiedzią jednym zdaniem to drobiazg, ale zadanie uruchamiane tysiąc razy dziennie już nie. Tokeny wejściowe vs wyjściowe wyjaśnia, dlaczego druga liczba zwykle kosztuje więcej za token.

Ile kosztuje takie wywołanie#

DeepSeek-V4-Flash w CheapTokens kosztuje $0.015 za 1M tokenów wejściowych i $0.10 za 1M tokenów wyjściowych, w tej samej cenie o każdej porze dnia. Weźmy zadanie oznaczania zgłoszeń: około 300 tokenów wejściowych i 150 tokenów wyjściowych na zgłoszenie. Jedno zgłoszenie kosztuje $0.00002. Tysiąc zgłoszeń wygląda tak, z ceną referencyjną OpenRoutera w następnej kolumnie:

Model Za żądanie 1000 żądań OpenRouter, 1000 żądań
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ów wejściowych i 150 tokenów wyjściowych na żądanie. Ceny za 1 mln tokenów są aktualne i zmieniają się wraz z naszymi taryfami; kolumna OpenRouter pokazuje ceny referencyjne dla tego samego obciążenia.

Model obsługuje do 380K tokenów kontekstu i do 32 768 tokenów w jednej odpowiedzi, więc zadanie streszczające rzadko trafia na ścianę. Jeśli wolisz wypróbować drugi model z tym samym skryptem, zmień tylko ciąg model: na zai-org/GLM-5.3-Flash (390K kontekstu, do 8192 tokenów wyjściowych).

Jeśli nie działa#

Większość błędów przy pierwszym uruchomieniu to jedna z pięciu rzeczy. Wybierz tę, która pasuje do twojego ekranu.

Wybierz swój przypadek

Co widzisz?

KeyError: key not found: "CHEAPTOKENS_API_KEY"

Zmienna nie jest ustawiona w tym terminalu. Uruchom ponownie linię export albo otwórz nową powłokę i sprawdź przez echo $CHEAPTOKENS_API_KEY.

401 Unauthorized

Klucz jest, ale błędny: zbłąkana spacja lub cudzysłów, obcięte wklejenie albo stary klucz. Skopiuj go ponownie ze swojego konta.

404 Not Found

Najpierw sprawdź base_url: kończy się na /v1 i nie ma po nim dodatkowej ścieżki. Potem sprawdź identyfikator modelu: to pełny identyfikator z prefiksem deepseek-ai/.

cannot load such file -- openai

Gem nie jest zainstalowany dla tego Ruby. Uruchom bundle install i uruchom skrypt przez bundle exec ruby ask.rb.

Bundler can't find a version that works

Sprawdź ruby -v. Linia 0.120.x wymaga Ruby 3.3.0 lub nowszego; na 3.2 przypnij zamiast tego linię 0.75.x.

Przypadki 401 i 404 pojawiają się z każdym SDK, nie tylko z Ruby; API 401 lub 404: zły klucz, base URL lub identyfikator modelu przechodzi przez nie po kolei.

Szybkie sprawdzenie

Co mówi ci finish_reason "length"?

Pokaż odpowiedź

Odpowiedź: Odpowiedź została ucięta przez limit długości

stop to normalne zakończenie; length oznacza, że odpowiedź trafiła na limit, zanim model skończył.

Co dalej#

Masz teraz najmniejszą użyteczną pętlę: wyślij, odczytaj tekst, zaloguj tokeny. Stąd opakuj wywołanie w metodę i dodaj liczby usage do swojego loggera. Ten sam wzorzec istnieje w innych językach, jeśli twój stack jest mieszany: Go, Java i C#. Pełna lista modeli i cen jest na stronie modeli, a referencja API jest w dokumentacji.