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 --> APIsThe crates
Section titled “The crates”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
Tooltrait - 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.
Core abstractions
Section titled “Core abstractions”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.
Provider clients
Section titled “Provider clients”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.
Models
Section titled “Models”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.
Agents
Section titled “Agents”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.
Vector stores
Section titled “Vector stores”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.
Workflows
Section titled “Workflows”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.
Transports
Section titled “Transports”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.
Targets
Section titled “Targets”| Target | Status |
|---|---|
| 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 |
See also
Section titled “See also”- Core Concepts: the full concept hub.
- Quickstart: build your first agent.
- Installation: features, TLS, and WebAssembly.
