Vi använder cookies. Cookies och webbläsarlagring håller dig inloggad och kommer ihåg dina preferenser. Med ditt tillstånd mäter vi också hur webbplatsen används. Du kan när som helst. Läs vår cookiepolicy.

Rust

SDK-guider

Rust

Använd async-openai med api14 genom att sätta API-basen med OpenAIConfig::with_api_base, med exempel för chat, streaming, verktyg och återförsök.

Använd async-openai med api14. Konfigurera API-basen med OpenAIConfig::with_api_base och ange modell-id som openai/gpt-5-mini.

Installera

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

Konfigurera

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

Läs nyckeln från miljön som ovan i stället för att hårdkoda den. För att växla mellan staging och produktion, läs base-URL:en på samma sätt, till exempel std::env::var("API14_BASE_URL").unwrap_or("https://api14.com/api/v1".into()).

Chat

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

Se Streaming.

Verktygsanrop

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()); // din funktion
        messages.push(ChatCompletionRequestToolMessageArgs::default()
            .tool_call_id(call.id)
            .content(result)
            .build()?
            .into());
    }
}

Se Verktygsanrop.

Strukturerad utdata

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("{}"))?;

Se Strukturerade utdata.

Bild som indata

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

Skicka den med google/gemini-2.5-flash eller en annan modell med image som indata. Se Vision och filer.

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

Endpoints som craten saknar typer för (videojobb, rerank) kan anropas med reqwest, se HTTP-exemplen i kodblocket nedan.

Fel

Gatewayens fel tolkas till OpenAIError::ApiError. Förgrena på den maskinläsbara code:

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

Se Fel.

Tidsgränser och återförsök

async-openai backar redan av och försöker igen vid 429 rate_limited. Standardbackoffen fortsätter försöka i upp till 15 minuter, vilket är för länge för de flesta appar och meningslöst vid daily_limit_reached. Begränsa den och ge HTTP-klienten en tidsgräns (cargo add backoff reqwest, med samma versioner som async-openai använder):

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

Se Hastighetsgränser.

Alla funktioner

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