We gebruiken cookies. Cookies en browseropslag houden je ingelogd en onthouden je voorkeuren. Met je toestemming meten we ook hoe de site wordt gebruikt. Je kunt je wanneer je wilt. Zie ons cookiebeleid.

Ruby

SDK-gidsen

Ruby

Gebruik de gem ruby-openai met api14: uri_base instellen, chat, streaming, tool calling, structured output, embeddings en retries met backoff.

Gebruik de gem ruby-openai met api14. Stel uri_base in en gebruik model-id's zoals openai/gpt-5-mini.

Installeren

gem install ruby-openai
export API14_API_KEY="sk-api14-..."

Configureren

ruby-openai voegt zijn API-versie (v1) toe aan uri_base, dus de basis is https://api14.com/api en requests gaan naar https://api14.com/api/v1/....

require "openai"

client = OpenAI::Client.new(
  access_token: ENV.fetch("API14_API_KEY"),
  uri_base: "https://api14.com/api",
  request_timeout: 120
)

Configureer de gem in een Rails-app eenmalig in een initializer en maak clients zonder argumenten aan:

# config/initializers/openai.rb
OpenAI.configure do |config|
  config.access_token = ENV.fetch("API14_API_KEY")
  config.uri_base = "https://api14.com/api"
  config.request_timeout = 120 # seconden, standaard 120
end

client = OpenAI::Client.new

Chat

response = client.chat(
  parameters: {
    model: "openai/gpt-5-mini",
    messages: [{ role: "user", content: "Explain vector databases in two sentences." }]
  }
)
puts response.dig("choices", 0, "message", "content")

Streaming

Geef een proc mee als stream; die wordt per chunk aangeroepen:

client.chat(
  parameters: {
    model: "anthropic/claude-sonnet-4.5",
    messages: [{ role: "user", content: "Write a haiku about APIs." }],
    stream: proc { |chunk, _bytesize| print chunk.dig("choices", 0, "delta", "content") }
  }
)

Zie Streaming.

Tool calling

require "json"

tools = [{
  type: "function",
  function: {
    name: "get_weather",
    description: "Current weather for a city",
    parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"] }
  }
}]
messages = [{ role: "user", content: "What's the weather in Istanbul?" }]

loop do
  response = client.chat(parameters: { model: "openai/gpt-5-mini", messages: messages, tools: tools })
  message = response.dig("choices", 0, "message")
  unless message["tool_calls"]
    puts message["content"]
    break
  end

  messages << message
  message["tool_calls"].each do |call|
    args = JSON.parse(call.dig("function", "arguments"))
    messages << { role: "tool", tool_call_id: call["id"], content: get_weather(args["city"]).to_json } # je eigen methode
  end
end

Zie Tool calling.

Gestructureerde uitvoer

response = client.chat(
  parameters: {
    model: "openai/gpt-5-mini",
    messages: [{ role: "user", content: "Extract: Ada Lovelace, born 1815 in London." }],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "person",
        strict: true,
        schema: {
          type: "object",
          properties: { name: { type: "string" }, born: { type: "integer" }, city: { type: "string" } },
          required: %w[name born city],
          additionalProperties: false
        }
      }
    }
  }
)
person = JSON.parse(response.dig("choices", 0, "message", "content"))

Zie Structured outputs.

Afbeeldingen als invoer

require "base64"

image = Base64.strict_encode64(File.binread("photo.png"))

client.chat(
  parameters: {
    model: "google/gemini-2.5-flash",
    messages: [{
      role: "user",
      content: [
        { type: "text", text: "What is in this picture?" },
        { type: "image_url", image_url: { url: "data:image/png;base64,#{image}" } }
      ]
    }]
  }
)

Zie Beeld en bestanden.

Gateway-parameters

De gem stuurt parameters ongewijzigd door, dus gateway-velden werken direct:

client.chat(
  parameters: {
    model: "openai/gpt-5-mini",
    models: ["anthropic/claude-sonnet-4.5"], # fallbacks
    provider: { sort: "throughput" },
    reasoning: { effort: "low" },
    messages: [{ role: "user", content: "Hi" }]
  }
)

Embeddings

response = client.embeddings(
  parameters: { model: "openai/text-embedding-3-small", input: ["The quick brown fox", "Lorem ipsum"] }
)
puts response.dig("data", 0, "embedding").length

Fouten

HTTP-fouten worden gegooid als Faraday::Error; de response-hash bevat de status, headers en de body in het OpenAI-formaat:

begin
  client.chat(parameters: { model: "openai/gpt-5-mini", messages: [{ role: "user", content: "Hi" }] })
rescue Faraday::Error => e
  case e.response&.dig(:status)
  when 402 then warn "Balance too low, add funds (insufficient_balance)"
  when 429 then warn "Rate limited, retry after #{e.response[:headers]['retry-after']}s"
  else raise
  end
end

Zie Fouten voor elke code.

Nieuwe pogingen met backoff

ruby-openai probeert standaard niet opnieuw. Een kleine wrapper probeert rate_limited, 5xx en timeouts opnieuw en laat daily_limit_reached en insufficient_balance met rust:

def with_retry(attempts: 5)
  attempts.times do |i|
    return yield
  rescue Faraday::TimeoutError, Faraday::ConnectionFailed
    raise if i == attempts - 1
    sleep([2**i, 60].min + rand)
  rescue Faraday::Error => e
    status = e.response&.dig(:status).to_i
    retryable = status >= 500 || (status == 429 && !e.response[:body].to_s.include?("daily_limit_reached"))
    raise if !retryable || i == attempts - 1
    wait = e.response.dig(:headers, "retry-after")&.to_i || 2**i
    sleep([wait, 60].min + rand)
  end
end

with_retry { client.chat(parameters: { model: "openai/gpt-5-mini", messages: [{ role: "user", content: "Hi" }] }) }

Zie Rate limits.

Alle mogelijkheden

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api14.com/api/v1",
  apiKey: process.env.API14_API_KEY,
});

const result = await client.chat.completions.create({
  "model": "openai/gpt-5-mini",
  "messages": [
    {
      "role": "user",
      "content": "Explain vector databases in two sentences."
    }
  ]
});
console.log(result.choices[0].message.content);