Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quickstart

Set a key

export OPENAI_API_KEY="sk-..."

Make a request

use rai_sdk::{ClientBuilder, Model};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ClientBuilder::new()
        .from_env()
        .model(Model::gpt4o_mini())
        .build()?;

    let response = client
        .request()
        .prompt("Explain Rust ownership in two sentences.")
        .generate()
        .await?;

    println!("{}", response.text());
    Ok(())
}

What each step does

ClientBuilder::new().from_env() reads credentials and settings from the environment. Anything you set explicitly on the builder afterwards takes precedence.

.model(Model::gpt4o_mini()) sets the default model. This also changes the builder’s type: only after a model is present does build() produce a client whose request() starts in a model-ready state. That is why the next step does not need to repeat the model.

.build()? constructs the HTTP client and validates configuration. It fails if the selected provider has no usable credentials.

.request().prompt(...) starts a request. prompt() accepts a &str, a String, a Message, or a full Prompt.

.generate().await? sends the request and, if tools are registered, runs the tool loop until the model produces a final answer. Use generate_once() for exactly one provider call with no tool execution.

response.text() concatenates the text content of the response.

Overriding the model per request

The client’s model is a default, not a constraint. Override it on a single request:

use rai_sdk::{ClientBuilder, Model};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ClientBuilder::new()
        .from_env()
        .model(Model::gpt4o_mini())
        .build()?;

    // Uses Anthropic for this one request; the client default is unchanged.
    let response = client
        .request()
        .model(Model::claude_sonnet_46())
        .prompt("Summarize the Rust borrow checker.")
        .generate()
        .await?;

    println!("{}", response.text());
    Ok(())
}

This requires credentials for whichever provider you name, so the example above needs ANTHROPIC_API_KEY in addition to OPENAI_API_KEY.

Tuning generation

Pass a GenerationConfig to control sampling and limits:

use rai_sdk::{ClientBuilder, GenerationConfig, Model};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ClientBuilder::new()
        .from_env()
        .model(Model::gpt4o_mini())
        .build()?;

    let response = client
        .request()
        .config(
            GenerationConfig::new()
                .with_temperature(0.2)
                .with_max_tokens(512),
        )
        .prompt("List three Rust testing tips.")
        .generate()
        .await?;

    println!("{}", response.text());
    Ok(())
}

Note that temperature and top_p are ignored for OpenAI reasoning (o-series) models, which do not accept them.

Next steps