نستخدم ملفات تعريف الارتباط. تُبقيك ملفات تعريف الارتباط وتخزين المتصفح مسجّلًا للدخول وتتذكر تفضيلاتك. وبإذنك نقيس أيضًا كيفية استخدام الموقع. يمكنك في أي وقت. راجع سياسة ملفات تعريف الارتباط.

Ruby

أدلة SDK

Ruby

استخدم جوهرة ruby-openai مع api14 بضبط uri_base، مع أمثلة للمحادثة والبث والأدوات والمخرجات المنظمة وإعادة المحاولة في Rails.

استخدم جوهرة ruby-openai مع api14. اضبط uri_base واستخدم معرّفات نماذج مثل openai/gpt-5-mini.

التثبيت

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

الإعداد

تضيف ruby-openai إصدار API الخاص بها (v1) إلى uri_base، لذا يكون العنوان الأساسي https://api14.com/api وتذهب الطلبات إلى 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
)

في تطبيق Rails اضبط الجوهرة مرة واحدة في initializer وأنشئ العملاء دون وسائط:

# 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 # seconds, default 120
end

client = OpenAI::Client.new

المحادثة

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")

البث

مرّر proc بوصفه stream، ويُستدعى مرة لكل جزء:

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") }
  }
)

راجع البث.

استدعاء الأدوات

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 } # your method
  end
end

راجع استدعاء الأدوات.

المخرجات المنظمة

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"))

راجع المخرجات المنظمة.

إدخال الصور

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}" } }
      ]
    }]
  }
)

راجع الرؤية والملفات.

معاملات البوابة

تمرر الجوهرة parameters كما هي، لذا تعمل حقول البوابة مباشرة:

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

الأخطاء

تُطلق أخطاء HTTP بوصفها Faraday::Error، ويحمل hash الاستجابة الحالة والترويسات والجسم بصيغة OpenAI:

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

راجع الأخطاء لكل الرموز.

إعادة المحاولة مع التراجع

لا تعيد ruby-openai المحاولة افتراضيًا. غلاف صغير يعيد محاولة rate_limited وأخطاء 5xx والمهلات، ويترك daily_limit_reached وinsufficient_balance كما هما:

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" }] }) }

راجع حدود الطلبات.

كل القدرات

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);