Çerez kullanıyoruz. Çerezler ve tarayıcı depolaması oturumunu açık tutar ve tercihlerini hatırlar. İzin verirsen sitenin nasıl kullanıldığını da ölçeriz. İstediğin zaman . Ayrıntılar için çerez politikamıza bak.

Rust

SDK rehberleri

Rust

async-openai kütüphanesini OpenAIConfig::with_api_base ile api14'e bağlayın; Rust'ta sohbet, streaming, araç çağırma, structured output ve hata yönetimi.

api14 ile async-openai kullanın. API tabanını OpenAIConfig::with_api_base ile yapılandırın ve openai/gpt-5-mini gibi model kimlikleri geçin.

Kurulum

cargo add async-openai futures serde_json
cargo add tokio --features full
export API14_API_KEY="sk-api14-..."

Yapılandırma

use async_openai::{config::OpenAIConfig, Client};

let config = OpenAIConfig::new()
    .with_api_base("https://api14.com/api/v1")
    .with_api_key(std::env::var("API14_API_KEY")?);
let client = Client::with_config(config);

Anahtarı sabit kodlamak yerine yukarıdaki gibi ortamdan okuyun. Staging ve production arasında geçiş yapmak için base URL'i de aynı şekilde okuyun, örneğin std::env::var("API14_BASE_URL").unwrap_or("https://api14.com/api/v1".into()).

Sohbet

use async_openai::{
    config::OpenAIConfig,
    types::{ChatCompletionRequestUserMessageArgs, CreateChatCompletionRequestArgs},
    Client,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = OpenAIConfig::new()
        .with_api_base("https://api14.com/api/v1")
        .with_api_key(std::env::var("API14_API_KEY")?);
    let client = Client::with_config(config);

    let request = CreateChatCompletionRequestArgs::default()
        .model("openai/gpt-5-mini")
        .messages([ChatCompletionRequestUserMessageArgs::default()
            .content("Explain vector databases in two sentences.")
            .build()?
            .into()])
        .build()?;

    let response = client.chat().create(request).await?;
    if let Some(content) = &response.choices[0].message.content {
        println!("{content}");
    }
    Ok(())
}

Streaming

use futures::StreamExt;

let request = CreateChatCompletionRequestArgs::default()
    .model("anthropic/claude-sonnet-4.5")
    .messages([ChatCompletionRequestUserMessageArgs::default()
        .content("Write a haiku about APIs.")
        .build()?
        .into()])
    .build()?;

let mut stream = client.chat().create_stream(request).await?;
while let Some(result) = stream.next().await {
    match result {
        Ok(chunk) => {
            for choice in chunk.choices {
                if let Some(text) = choice.delta.content {
                    print!("{text}");
                }
            }
        }
        Err(err) => eprintln!("stream error: {err}"),
    }
}

Bkz. Streaming.

Tool calling

use async_openai::types::{
    ChatCompletionRequestAssistantMessageArgs, ChatCompletionRequestMessage,
    ChatCompletionRequestToolMessageArgs, ChatCompletionToolArgs, ChatCompletionToolType,
    FunctionObjectArgs,
};
use serde_json::{json, Value};

let tools = vec![ChatCompletionToolArgs::default()
    .r#type(ChatCompletionToolType::Function)
    .function(FunctionObjectArgs::default()
        .name("get_weather")
        .description("Current weather for a city")
        .parameters(json!({
            "type": "object",
            "properties": { "city": { "type": "string" } },
            "required": ["city"]
        }))
        .build()?)
    .build()?];

let mut messages: Vec<ChatCompletionRequestMessage> = vec![ChatCompletionRequestUserMessageArgs::default()
    .content("What's the weather in Istanbul?")
    .build()?
    .into()];

loop {
    let request = CreateChatCompletionRequestArgs::default()
        .model("openai/gpt-5-mini")
        .messages(messages.clone())
        .tools(tools.clone())
        .build()?;
    let message = client.chat().create(request).await?.choices.remove(0).message;

    let Some(calls) = message.tool_calls else {
        println!("{}", message.content.unwrap_or_default());
        break;
    };
    messages.push(ChatCompletionRequestAssistantMessageArgs::default()
        .tool_calls(calls.clone())
        .build()?
        .into());
    for call in calls {
        let args: Value = serde_json::from_str(&call.function.arguments)?;
        let result = get_weather(args["city"].as_str().unwrap_or_default()); // your function
        messages.push(ChatCompletionRequestToolMessageArgs::default()
            .tool_call_id(call.id)
            .content(result)
            .build()?
            .into());
    }
}

Bkz. Tool calling.

Structured output

use async_openai::types::{ResponseFormat, ResponseFormatJsonSchema};

let request = CreateChatCompletionRequestArgs::default()
    .model("openai/gpt-5-mini")
    .messages([ChatCompletionRequestUserMessageArgs::default()
        .content("Extract: Ada Lovelace, born 1815.")
        .build()?
        .into()])
    .response_format(ResponseFormat::JsonSchema {
        json_schema: ResponseFormatJsonSchema {
            name: "person".into(),
            description: None,
            strict: Some(true),
            schema: Some(json!({
                "type": "object",
                "properties": { "name": { "type": "string" }, "born": { "type": "integer" } },
                "required": ["name", "born"],
                "additionalProperties": false
            })),
        },
    })
    .build()?;

let response = client.chat().create(request).await?;
let person: Value = serde_json::from_str(response.choices[0].message.content.as_deref().unwrap_or("{}"))?;

Bkz. Structured outputs.

Görsel girdisi

use async_openai::types::{
    ChatCompletionRequestMessageContentPartImageArgs, ChatCompletionRequestMessageContentPartTextArgs,
    ImageUrlArgs,
};

let message = ChatCompletionRequestUserMessageArgs::default()
    .content(vec![
        ChatCompletionRequestMessageContentPartTextArgs::default()
            .text("What is in this picture?")
            .build()?
            .into(),
        ChatCompletionRequestMessageContentPartImageArgs::default()
            .image_url(ImageUrlArgs::default().url("https://example.com/photo.jpg").build()?)
            .build()?
            .into(),
    ])
    .build()?;

google/gemini-2.5-flash veya image girdisi olan başka bir modelle gönderin. Bkz. Görsel ve dosyalar.

Embeddings

use async_openai::types::CreateEmbeddingRequestArgs;

let request = CreateEmbeddingRequestArgs::default()
    .model("openai/text-embedding-3-small")
    .input(["The quick brown fox", "Lorem ipsum"])
    .build()?;
let response = client.embeddings().create(request).await?;
println!("{}", response.data[0].embedding.len());

Crate'in türü olmayan uç noktalar (video işleri, rerank) reqwest ile çağrılabilir; aşağıdaki kod bloğundaki HTTP örneklerine bakın.

Hatalar

Ağ geçidi hataları OpenAIError::ApiError olarak ayrıştırılır; makine code değerine göre dallanın:

use async_openai::error::OpenAIError;

match client.chat().create(request).await {
    Ok(response) => println!("{:?}", response.choices[0].message.content),
    Err(OpenAIError::ApiError(err)) => match err.code.as_deref() {
        Some("insufficient_balance") => eprintln!("Balance too low, add funds"),
        Some("rate_limited") | Some("daily_limit_reached") => eprintln!("Slow down: {}", err.message),
        _ => eprintln!("API error: {}", err.message),
    },
    Err(other) => eprintln!("{other}"),
}

Bkz. Hatalar.

Zaman aşımları ve yeniden denemeler

async-openai 429 rate_limited yanıtlarında zaten geri çekilir ve yeniden dener. Varsayılan geri çekilmesi 15 dakikaya kadar denemeye devam eder; bu çoğu uygulama için çok uzundur ve daily_limit_reached için anlamsızdır. Sınırlayın ve HTTP istemcisine bir zaman aşımı verin (cargo add backoff reqwest, async-openai'ın kullandığı sürümlerle eşleşecek şekilde):

use std::time::Duration;

let http = reqwest::Client::builder()
    .timeout(Duration::from_secs(120))
    .build()?;

let client = Client::with_config(config)
    .with_http_client(http)
    .with_backoff(backoff::ExponentialBackoffBuilder::new()
        .with_max_elapsed_time(Some(Duration::from_secs(90)))
        .build());

Bkz. Hız limitleri.

Tüm yetenekler

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