Skip to content

Architecture

Rig separates portable contracts (what a provider, model, tool, or vector store is) from orchestration (the agent loop that drives them). The rig crate is a facade over both, so most applications depend on rig alone and never name the crates underneath. This page is the map.

flowchart TB
App["Your app"]
subgraph Facade["rig (facade)"]
direction TB
Agent["rig-agent<br/>AgentBuilder · agent loop · hooks<br/>extraction · steppable runs"]
Core["rig-core<br/>Model · DynModel · providers · messages<br/>tools · embeddings · memory · vector-store traits"]
Integrations["feature-gated integrations<br/>rig::qdrant · rig::lancedb · rig::bedrock<br/>rig::tool::rmcp · rig::cassette · ..."]
end
Transport["Transport<br/>reqwest (default) · your own HTTP client"]
APIs["Provider APIs and databases"]
App --> Facade
Agent --> Core
Integrations --> Core
Core --> Transport
Transport --> APIs

rig is the facade. It re-exports rig-core at familiar paths (rig::completion, rig::providers, rig::embeddings, rig::vector_store, …), adds the agent runtime under rig::agent and the prelude, and exposes each integration as a module behind a cargo feature of the same name.

rig-core holds the portable contracts that every other crate builds on:

  • provider clients and the models they build (Model, DynModel)
  • messages, completion requests and responses, typed generation options
  • tool definitions and the Tool trait
  • embeddings, conversation-memory traits, and vector-store traits, with an in-memory vector store
  • streaming events, error types, telemetry, and file loaders

rig-agent is the classic agent runtime, enabled by default through the facade’s agent feature: AgentBuilder and Agent, the tool-calling loop, typed hooks, the live tool registry, extraction, and AgentRun, the serializable state machine that makes every decision of the loop without doing any I/O.

Companion crates add integrations that carry heavy dependencies: vector stores (rig-qdrant, rig-lancedb, rig-mongodb, …), extra providers (rig-bedrock, rig-vertexai, rig-gemini-grpc, rig-candle), local embeddings (rig-fastembed), MCP tools (rig-rmcp), memory policies (rig-memory), and recording/replay (rig-cassette). Through the facade you reach each one as rig::<name>:

[dependencies]
rig = { version = "0.44.0", features = ["qdrant", "rmcp"] }

See Installation for every feature, and Integrations for what each one does.

The building blocks compose from the bottom up: a provider client builds a model, an agent wraps it, and your code drives the agent. The Quickstart shows that stack as a complete program.

Each provider has a client type (OpenAI, Anthropic, Gemini, Ollama, …) holding its configuration (credentials, base URL) and a transport. Create one with from_env() or new(api_key). Providers that speak another provider’s format, such as DeepSeek or Groq on OpenAI’s format, have module-level constructors like deepseek::from_env().

See Providers & Clients.

A client builds models: client.completion(id), client.embedding(id, None), and, where the provider supports them, transcription, image-generation, and audio-generation models. A Model pairs a wire (how to encode the request and decode the reply for one provider endpoint) with a transport (how the bytes travel). Its call method sends one request and returns a normalized response; stream returns the reply as it arrives. DynModel is the same model with its provider type erased, for code that stores models of different providers side by side.

See Completions and Embeddings.

An Agent bundles a model with a preamble, tools, dynamic context, memory, and hooks, and runs the loop for you: call the model, run the tools it asks for, feed the results back, and repeat until it answers or hits its turn budget. Every prompt returns an AgentRunner you can configure per run (history, turn budget, hooks, model choice) before awaiting it or calling .stream().

Underneath, the loop’s decisions live in AgentRun, which you can also step yourself, persist between steps, and resume elsewhere.

See Agents, AgentRunner, Hooks, Tools, and Durable runs.

Retrieval goes through two traits: InsertDocuments adds embedded documents, and VectorStoreIndex runs similarity search. The in-memory store ships with rig-core; the companion crates implement the same traits over external databases. Any index can back an agent’s dynamic context or be exposed as a tool.

See Vector Stores & RAG and Vector Stores.

Compose models, agents, and tools into multi-step flows with plain Rust: call steps in sequence, run them concurrently with futures::join!, or branch with match. There’s no workflow DSL.

See Workflows.

Provider clients don’t own an HTTP library. With the default reqwest feature, a client created with from_env() or new(..) sends through one shared reqwest client. To change timeouts, proxies, or headers, or to add middleware, pass any HTTP client to with_http(..):

use rig::http_client::{DynHttpClient, ReqwestClient};
let http = DynHttpClient::new(ReqwestClient::default());
let client = OpenAI::from_env()?.with_http(http);

Anything implementing rig::http_client::HttpClientExt works, which is also how tests swap in a fake transport. The optional websocket feature adds a websocket backend for OpenAI’s Responses WebSocket sessions.

TargetStatus
Native (Linux, macOS, Windows; x86_64 and aarch64)Full support, all features
wasm32-unknown-unknown (browser)Supported with no feature flags; MCP (rmcp) and the bundled websocket backend are unavailable
WASI (wasm32-wasip1, wasm32-wasip2)Not supported