블로그로 돌아가기

API & SDK가이드

openai gem으로 Ruby에서 첫 요청: base_url, 키, usage

짧은 Ruby 스크립트: 공식 openai gem, 사용자 지정 base_url, env의 키. 응답 텍스트와 토큰 사용량을 출력합니다.

작성자: CheapTokens Team 게시됨읽는 시간 5분

OpenAI::Client.new와 CheapTokens를 가리키는 사용자 지정 base_url이 있는 Ruby 스크립트
이 페이지의 내용
  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 작업이나, 노트를 저장하기 전에 요약하는 백그라운드 작업이 있다고 해봅시다. 직접 HTTP를 작성하는 대신 공식 SDK를 쓰고 싶고, 각 호출이 몇 개의 토큰을 사용했는지 보고 싶을 것입니다. 바로 이 스크립트가 그런 경우입니다.

시작하기 전에 필요한 것#

RubyGems의 gem 페이지(2026년 11월 8일 확인)에는 2026년 11월 5일 릴리스된 openai 0.120.0이 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이라는 단어가 생소하다면 키를 안전하게 보관하는 방법은 5분이면 읽을 수 있습니다.

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[...] 대신 ENV.fetch을 사용합니다. 변수가 없으면 fetch은 해당 변수 이름을 알려주는 KeyError와 함께 즉시 중단됩니다. ENV[...]은 조용히 nil을 전달하고 몇 줄 뒤에 혼란스러운 인증 오류가 발생합니다.

base_url:는 gem의 README에 있는 OpenAI 예제와 다른 유일한 줄입니다. 나머지는 모두 같은 코드이며, 이것이 OpenAI 호환 API의 핵심입니다. 이 개념이 생소하다면 base_url이 무엇이고 어떻게 전환하는지가 식당 비유로 설명합니다.

모델 id는 전체 id인 deepseek-ai/DeepSeek-V4-Flash-0731입니다. 가격표의 짧은 이름은 API에서 허용되지 않습니다. id는 CheapTokens 문서나 GET /v1/models에서 가져오세요.

Gemfile 줄, export한 키, ruby ask.rb가 있는 터미널
세 명령: gem 고정, 키 export, 스크립트 실행.

응답 읽기#

응답은 해시가 아니라 객체이므로 메서드를 호출합니다. 텍스트는 completion.choices.first.message.content에 있으며, gem의 README에서도 이 경로를 사용합니다.

첫날부터 출력할 가치가 있는 두 줄이 더 있습니다:

  • finish_reason은 모델이 왜 멈췄는지 알려줍니다. stop은 정상 종료입니다. length는 길이 제한으로 답변이 잘렸다는 뜻입니다. 이 경우가 보인다면 답변이 잘리는 이유와 해결 방법을 참고하세요.
  • usage에는 호출에 청구된 토큰, 즉 보낸 내용과 모델이 작성한 내용이 담깁니다. 스크립트는 puts completion.usage로 전체 객체를 출력하므로 API가 반환한 두 숫자를 모두 볼 수 있습니다.

왜 기록할까요? 토큰이 곧 청구서이기 때문입니다. 한 문장 질문에 한 문장 답변은 작지만, 하루에 천 번 실행되는 작업은 그렇지 않습니다. 입력 토큰 vs 출력 토큰은 두 번째 숫자가 보통 토큰당 더 비싼 이유를 설명합니다.

이런 호출의 비용#

CheapTokens의 DeepSeek-V4-Flash는 1M 입력 토큰당 $0.015, 1M 출력 토큰당 $0.10이며 하루 중 어느 시간에도 같은 가격입니다. 티켓 라벨링 작업을 예로 들면 티켓당 약 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개 토큰입니다. 100만 토큰당 가격은 현재 기준이며 당사 요금제에 따라 함께 변경됩니다. 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/ 접두사가 붙은 전체 id입니다.

cannot load such file -- openai

이 Ruby에 gem이 설치되지 않았습니다. 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 사례는 Ruby뿐 아니라 모든 SDK에서 발생합니다. API 401 또는 404: 잘못된 키, base URL 또는 모델 id가 순서대로 설명합니다.

빠른 확인

finish_reason "length"는 무엇을 알려주나요?

정답 보기

정답: 답변이 길이 제한으로 잘렸음

stop는 정상 종료이고, length은 모델이 끝나기 전에 답변이 한계에 도달했다는 뜻입니다.

다음 단계#

이제 가장 작은 유용한 루프를 갖추었습니다: 전송하고, 텍스트를 읽고, 토큰을 기록합니다. 여기서 호출을 메서드로 감싸고 usage 숫자를 로거에 추가하세요. 스택이 혼합되어 있다면 다른 언어에도 같은 패턴이 있습니다: Go, Java, C#. 전체 모델과 가격 목록은 모델 페이지에 있고, API 참조는 문서에 있습니다.