Ruby SDK

Ruby SDK

Anthropic Ruby 라이브러리로 Ruby 3.2.0+ 애플리케이션에서 Claude API에 편리하게 접근해요. Yard, RBS, RBI로 포괄적인 타입과 독스트링을 제공하고, 표준 라이브러리의 net/http를 HTTP 전송으로, connection_pool 젬으로 연결 풀링을 해요.

출처: 문서

본문

코드 예제가 있는 API 기능 문서는 [API 레퍼런스](https://platform.claude.com/docs/en/api/overview)를 참고하세요. 이 페이지는 Ruby 전용 SDK 기능과 설정을 다뤄요.

설치

Bundler로 애플리케이션 Gemfile에 젬을 추가하세요:

bundle add anthropic

요구사항

Ruby 3.2.0 이상.

사용법

anthropic = Anthropic::Client.new(
  api_key: ENV["ANTHROPIC_API_KEY"] # This is the default and can be omitted
)

message = anthropic.messages.create(
  max_tokens: 1024,
  messages: [{role: "user", content: "Hello, Claude"}],
  model: :"claude-opus-5-5"
)

message.content.each do |block|
  puts block.text if block.type == :text
end

Workload Identity Federation을 포함한 인증 옵션은 인증을 참고하세요. API 키가 여러 워크스페이스 액세스가 있는 개인·서비스 계정 키라면 anthropic-workspace-id 요청 헤더에 워크스페이스 ID를 설정하세요. 워크스페이스 선택하기가 이 SDK의 요청별 옵션을 보여 줘요.

스트리밍

SDK는 Server-Sent Events(SSE)를 사용한 스트리밍 응답을 지원해요.

anthropic = Anthropic::Client.new
stream = anthropic.messages.stream(
  max_tokens: 1024,
  messages: [{role: "user", content: "Hello, Claude"}],
  model: :"claude-opus-5-5"
)

stream.each do |message|
  puts(message.type)
end

스트리밍 헬퍼

이 라이브러리는 메시지 스트리밍을 위한 몇 가지 편의 기능을 제공해요. 예를 들어:

anthropic = Anthropic::Client.new
stream = anthropic.messages.stream(
  max_tokens: 1024,
  messages: [{role: :user, content: "Say hello there!"}],
  model: :"claude-opus-5-5"
)

stream.text.each do |text|
  print(text)
end

anthropic.messages.stream(...)으로 스트리밍하면 누적과 SDK 전용 이벤트를 포함한 여러 헬퍼가 노출돼요.

입력 스키마와 도구 호출

SDK는 도구용 구조화 데이터 클래스를 정의하고 Claude가 자동으로 실행하게 하는 헬퍼 메커니즘을 제공해요. 도구 러너를 포함한 도구 사용 패턴의 상세 문서는 도구 러너 (SDK)를 참고하세요.

anthropic = Anthropic::Client.new
class CalculatorInput < Anthropic::BaseModel
  required :lhs, Float
  required :rhs, Float
  required :operator, Anthropic::InputSchema::EnumOf[:+, :-, :*, :/]
end

class Calculator < Anthropic::BaseTool
  input_schema CalculatorInput

  def call(expr)
    expr.lhs.public_send(expr.operator, expr.rhs)
  end
end

# Automatically handles tool execution loop
anthropic.beta.messages.tool_runner(
  model: "claude-opus-5-5",
  max_tokens: 1024,
  messages: [{role: "user", content: "What's 15 * 7?"}],
  tools: [Calculator.new]
).each_message { |message| puts message.content }

구조화된 출력

Ruby 예제를 포함한 완전한 구조화된 출력 문서는 구조화된 출력을 참고하세요.

오류 처리

라이브러리가 API에 연결하지 못하거나, API가 성공이 아닌 상태 코드(4xx 또는 5xx 응답)를 반환하면 Anthropic::Errors::APIError의 하위 클래스가 발생해요:

anthropic = Anthropic::Client.new
begin
  message = anthropic.messages.create(
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    model: :"claude-opus-5-5"
  )
rescue Anthropic::Errors::APIConnectionError => e
  puts("The server could not be reached")
  puts(e.cause)  # an underlying Exception, likely raised within `net/http`
rescue Anthropic::Errors::RateLimitError => e
  puts("A 429 status code was received; we should back off a bit.")
rescue Anthropic::Errors::APIStatusError => e
  puts("Another non-200-range status code was received")
  puts(e.status)
end

오류 코드는 다음과 같아요:

원인 오류 유형
HTTP 400 BadRequestError
HTTP 401 AuthenticationError
HTTP 403 PermissionDeniedError
HTTP 404 NotFoundError
HTTP 409 ConflictError
HTTP 422 UnprocessableEntityError
HTTP 429 RateLimitError
HTTP >= 500 InternalServerError
기타 HTTP 오류 APIStatusError
타임아웃 APITimeoutError
네트워크 오류 APIConnectionError

재시도

일부 오류는 기본적으로 짧은 지수 백오프로 2회 자동 재시도돼요.

연결 오류(예: 네트워크 연결 문제), 408 Request Timeout, 409 Conflict, 429 Rate Limit, >=500 내부 오류, 타임아웃은 모두 기본적으로 재시도돼요.

max_retries 옵션으로 설정하거나 끌 수 있어요:

# Configure the default for all requests:
anthropic = Anthropic::Client.new(
  max_retries: 0 # default is 2
)

# Or, configure per-request:
anthropic.messages.create(
  max_tokens: 1024,
  messages: [{role: "user", content: "Hello, Claude"}],
  model: :"claude-opus-5-5",
  request_options: {max_retries: 5}
)

타임아웃

기본적으로 요청은 10분 후에 타임아웃돼요. timeout 옵션으로 설정할 수 있어요:

# Configure the default for all requests:
anthropic = Anthropic::Client.new(
  timeout: 20 # 20 seconds (default is 10 minutes)
)

# Or, configure per-request:
anthropic.messages.create(
  max_tokens: 1024,
  messages: [{role: "user", content: "Hello, Claude"}],
  model: :"claude-opus-5-5",
  request_options: {timeout: 5}
)

타임아웃 시 Anthropic::Errors::APITimeoutError가 발생해요.

타임아웃된 요청은 기본적으로 재시도된다는 점에 유의하세요.

페이징

Claude API의 목록 메서드는 페이징돼요.

이 라이브러리는 각 목록 응답과 함께 자동 페이징 반복자를 제공하므로, 연속 페이지를 수동으로 요청할 필요가 없어요:

anthropic = Anthropic::Client.new
page = anthropic.messages.batches.list(limit: 20)

# Fetch single item from page.
batch = page.data[0]
puts(batch.id)

# Automatically fetches more pages as needed.
page.auto_paging_each do |batch|
  puts(batch.id)
end

페이지를 더 세밀하게 제어하려면 #next_page?#next_page 메서드를 쓸 수도 있어요.

anthropic = Anthropic::Client.new
page = anthropic.messages.batches.list(limit: 20)
loop do
  page.data&.each { |batch| puts(batch.id) }
  break unless page.next_page?
  page = page.next_page
end

파일 업로드

파일 업로드에 해당하는 요청 파라미터는 원시 내용, Pathname 인스턴스, StringIO 등으로 넘길 수 있어요.

anthropic = Anthropic::Client.new
require "pathname"

# Use `Pathname` to send the filename and/or avoid paging a large file into memory:
file_metadata = anthropic.files.upload(file: Pathname("/path/to/file"))

# Alternatively, pass file contents or a `StringIO` directly:
file_metadata = anthropic.files.upload(file: File.read("/path/to/file"))

# Or, to control the filename and/or content type:
file = Anthropic::FilePart.new(File.read("/path/to/file"), filename: "/path/to/file", content_type: "...")
file_metadata = anthropic.files.upload(file: file)

puts(file_metadata.id)

원시 IO 디스크립터를 넘길 수도 있지만, 디스크립터가 파일인지(되감을 수 없는) 파이프인지 확신할 수 없어 재시도를 끄는 점에 유의하세요.

Sorbet

이 라이브러리는 포괄적인 RBI 정의를 제공하고, sorbet-runtime에 대한 의존성이 없어요.

타입 안전한 요청 파라미터를 이렇게 제공할 수 있어요:

anthropic = Anthropic::Client.new
anthropic.messages.create(
  max_tokens: 1024,
  messages: [Anthropic::MessageParam.new(role: "user", content: "Hello, Claude")],
  model: :"claude-opus-5-5"
)

또는 동등하게:

anthropic = Anthropic::Client.new
# Hashes work, but are not typesafe:
anthropic.messages.create(
  max_tokens: 1024,
  messages: [{role: "user", content: "Hello, Claude"}],
  model: :"claude-opus-5-5"
)

# You can also splat a full Params class:
params = Anthropic::MessageCreateParams.new(
  max_tokens: 1024,
  messages: [Anthropic::MessageParam.new(role: "user", content: "Hello, Claude")],
  model: :"claude-opus-5-5"
)
anthropic.messages.create(**params)

열거형 (Enums)

이 라이브러리는 sorbet-runtime에 의존하지 않으므로 T::Enum 인스턴스를 제공할 수 없어요. 대신 SDK는 런타임에 항상 원시형인 "태그된 심볼"을 제공해요:

# :auto
puts(Anthropic::MessageCreateParams::ServiceTier::AUTO)

# Revealed type: `T.all(Anthropic::MessageCreateParams::ServiceTier, Symbol)`
T.reveal_type(Anthropic::MessageCreateParams::ServiceTier::AUTO)

열거형 파라미터는 "느슨한" 타입이므로 열거형 상수나 리터럴 값 중 하나를 넘길 수 있어요:

# Using the enum constants preserves the tagged type information:
anthropic.messages.create(
  service_tier: Anthropic::MessageCreateParams::ServiceTier::AUTO,
  # ...
)

# Literal values are also permissible:
anthropic.messages.create(
  service_tier: :auto,
  # ...
)

BaseModel

모든 파라미터·응답 객체는 Anthropic::Internal::Type::BaseModel을 상속하며, 여기에는 여러 편의 기능이 있어요:

  1. 모든 필드(알 수 없는 것 포함)를 obj[:prop] 문법으로 접근할 수 있고, obj => {prop: prop} 또는 패턴 매칭 문법으로 구조 분해할 수 있어요.

  2. 동등성에 대한 구조적 동등성: 두 API 호출이 같은 값을 반환하면 ==로 응답을 비교했을 때 true가 돼요.

  3. 인스턴스와 클래스 모두 예쁘게 출력할 수 있어요.

  4. #to_h, #deep_to_h, #to_json, #to_yaml 같은 헬퍼.

동시성과 연결 풀링

Anthropic::Client 인스턴스는 스레드 안전하지만, 진행 중인 HTTP 요청이 있을 때만 fork 안전해요.

Anthropic::Client 인스턴스는 기본 크기 99의 자체 HTTP 연결 풀을 가져요. 그래서 대부분의 설정에서 애플리케이션당 클라이언트를 한 번 만드는 걸 권장해요.

풀에서 사용 가능한 연결이 모두 체크아웃되면 요청은 새 연결이 가능해질 때까지 기다리고, 큐 시간은 요청 타임아웃에 포함돼요.

별도로 명시되지 않는 한 SDK의 다른 클래스는 기본 데이터 구조를 보호하는 잠금이 없어요.

커스텀·미문서화 요청 하기

미문서화 속성

어느 엔드포인트에든 미문서화 파라미터를 보내고, 미문서화 응답 속성을 읽을 수 있어요:

같은 이름의 `extra_` 파라미터는 문서화된 파라미터를 덮어써요. 보안상의 이유로 이 메서드들은 신뢰할 수 있는 입력 데이터에만 쓰세요.
anthropic = Anthropic::Client.new
value = "example"
message =
  anthropic.messages.create(
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    model: :"claude-opus-5-5",
    request_options: {
      extra_query: {my_query_parameter: value},
      extra_body: {my_body_parameter: value},
      extra_headers: {"my-header": value}
    }
  )

puts(message[:my_undocumented_property])

미문서화 요청 파라미터

추가 파라미터를 명시적으로 보내려면, 위 예제처럼 요청을 만들 때 request_options: 아래의 extra_query, extra_body, extra_headers로 할 수 있어요.

미문서화 엔드포인트

인증, 재시도 등의 이점을 유지하면서 미문서화 엔드포인트에 요청하려면 anthropic.request를 쓰세요:

response = anthropic.request(
  method: :post,
  path: '/undocumented/endpoint',
  query: {"dog": "woof"},
  headers: {"useful-header": "interesting-value"},
  body: {"hello": "world"}
)

플랫폼 통합

코드 예제가 있는 상세 플랫폼 설정 가이드는 다음을 참고하세요:

Ruby SDK는 다음 플랫폼을 지원해요:

  • Agent Platform: Anthropic::VertexClient. googleauth 젬 필요.
  • Bedrock: Anthropic::BedrockMantleClient, 또는 bedrock-runtime 경로용 Anthropic::BedrockClient. Anthropic::BedrockMantleClientaws-sdk-core 젬, Anthropic::BedrockClientaws-sdk-bedrockruntime 젬이 필요해요.
  • AWS의 Claude Platform: 메인 anthropic 젬의 일부(aws-sdk-core 젬 필요). Anthropic::AWSClient 제공. 생성자에 workspace_id:를 넘기거나 ANTHROPIC_AWS_WORKSPACE_ID 환경 변수를 설정하세요(워크스페이스 참고). 베타에서 사용 가능.
  • Foundry: Ruby SDK에서는 현재 지원하지 않아요. 지원되는 SDK는 Microsoft Foundry의 Claude 참고.

새 프로젝트에는 Anthropic::BedrockMantleClient를, Bedrock InvokeModel API를 쓰는 기존 애플리케이션에는 Anthropic::BedrockClient를 쓰세요.

시맨틱 버저닝

이 패키지는 SemVer 규칙을 따라요.

이 패키지는 (비런타임) *.rbi*.rbs 타입 정의의 개선을 비호환 변경으로 간주하지 않아요.

추가 자료

더 알아보기 (Learn more)