Oct 23, 20265 min read

Best Rust Framework for Building AI Agents in 2026

Rig and async-openai compared for Rust teams building agents, plus how Encore adds the database, queues and secrets the agent's Axum service needs, locally and in your own cloud.

Rust's agent ecosystem is small next to Python's, and most teams choose between Rig, a full framework, and async-openai, a typed client they build their own loop on.

Interest in Rust at work is growing, with the 2024 State of Rust Survey reporting that 38 percent of respondents use Rust for most of their coding at work. Whichever library you choose, the agent still runs inside a service that needs a database for runs, a queue for long tasks and somewhere for API keys outside the code.

What to weigh when choosing:

  • Whether you want a provider-agnostic interface or a direct client for one API.
  • How tools are declared and whether their schemas come from Rust types.
  • Whether retrieval and embeddings are part of the library.
  • Where state, queues and secrets live in each environment.

Rust agent libraries at a glance

OptionApproachBest fit
RigAgents, tools and retrieval over many model providersTeams that want a framework with batteries included
async-openaiTyped async client for OpenAI-compatible APIsTeams writing their own agent loop
Compare features across all two options
CapabilityRigasync-openai
RoleAgent frameworkAPI client
ProvidersMany, behind one traitOpenAI-compatible APIs
ToolsTool trait with typed argumentsRaw function schemas
StateYou store itYou store it
Background runsYou add a queueYou add a queue
Production infrastructureYou provision itYou provision it

Rig: a full agent framework

Rig

Rig provides agents, tool calling, embeddings and retrieval behind a common interface for many model providers, with vector store integrations as separate crates.

Key features

  • Provider clients share one completion and embedding interface.
  • Tools implement a trait with typed arguments and output.
  • Retrieval-augmented agents built from a vector store index.

Good to know

Rig is still on 0.x releases and its API changes between versions, so pin the version and expect migrations.

Try Rig →

async-openai: a typed client

async-openai

async-openai is a typed async client for the OpenAI API that also works against compatible endpoints, and many teams write a short agent loop around it.

Key features

  • Request builders for chat, responses, embeddings and more.
  • Streaming responses as async streams.
  • Configurable base URL for compatible providers.

Good to know

Tool schemas, the loop and retries are yours to write, which keeps control in your code at the cost of more of it.

Try async-openai →

Encore: infrastructure for the agent's service

Encore

Encore combines the Axum service running the agent with its infrastructure through an infrastructure SDK you add with the encore-dev crate, so Rig or async-openai runs the model loop while the service declares a Postgres database for runs, a topic for background work and a secret for the API key as static values. encore run starts Postgres locally with the topic, and a deploy provisions both in your own AWS or GCP account. Whichever option above you pick, Encore can add the database, topics and secrets to the same service.

use axum::{http::StatusCode, routing::post, Json, Router}; use encore::pubsub::{Message, Subscription, Topic}; use encore::secrets::Secret; use encore::storage::postgres::Database; use serde::{Deserialize, Serialize}; static DB: Database = Database::new("agent").migrations("./migrations"); static OPENAI_KEY: Secret = Secret::new("OpenAIKey"); static RUNS: Topic<RunRequested> = Topic::new("agent-runs"); #[derive(Debug, Clone, Serialize, Deserialize)] struct RunRequested { run_id: i64, prompt: String, } #[encore::pubsub::register] static EXECUTE: Subscription<RunRequested> = Subscription::new(&RUNS, "execute-run", execute).max_retries(3); async fn execute(msg: Message<RunRequested>) -> Result<(), encore::Error> { let key = OPENAI_KEY.value()?; // run_agent wraps your agent library, such as a Rig agent. let output = run_agent(&key, &msg.data.prompt).await; DB.write() .execute( "UPDATE runs SET output = $1, done = true WHERE id = $2", &[&output, &msg.data.run_id], ) .await?; Ok(()) } #[derive(Deserialize)] struct CreateRun { prompt: String, } async fn create_run(Json(req): Json<CreateRun>) -> Result<Json<i64>, StatusCode> { let row = DB .write() .query_one("INSERT INTO runs (prompt) VALUES ($1) RETURNING id", &[&req.prompt]) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; let run_id: i64 = row.get(0); RUNS.publish(&RunRequested { run_id, prompt: req.prompt }) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(Json(run_id)) } #[tokio::main] async fn main() { encore::initialize(); let app = Router::new().route("/runs", post(create_run)); let addr = std::env::var("ENCORE_LISTEN_ADDR").unwrap_or("0.0.0.0:8080".into()); let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); axum::serve(listener, app) .with_graceful_shutdown(encore::shutdown::signal()) .await .unwrap(); }
Axum takes the request, a subscription runs the agent, and the key is read from an Encore secret.

Key features

  • The API key is a declared secret, so it is not in the repository or an environment file.
  • Failed runs are retried by the subscription rather than lost with the request.
  • A deploy provisions the database and topic in your own AWS or GCP account.
  • Coding agents working on the service can read traces and query the runs table through the local MCP server, and its secret metadata tool does not expose secret values.

Good to know

Encore does not call models, so the library comparison below still decides how the agent is written. Plan for review of what the agent produces, since only 3 percent of developers in the 2025 Stack Overflow Developer Survey said they highly trust the output of AI tools. Cloud resources are created at deploy time, and the cloud access sits with Encore's IAM role, not the agent. Rust support is in beta, and you can sign up for access.

Try Encore →

How to choose

Anthropic's guide to building effective agents recommends starting with simple, composable patterns, which in Rust often means a typed client and a short loop.

  • Rig for a framework with many providers and retrieval.
  • async-openai for a direct client and your own loop.

See Encore's AI integration docs for how coding agents work with an Encore app. Rust support in Encore is in beta, and you can sign up for access.

Frequently asked questions

What is the best Rust framework for building AI agents?

Rig is the most complete Rust agent framework, with a common interface over many model providers, tool calling and retrieval. async-openai is a lower-level typed client for OpenAI-compatible APIs, suited to teams that write their own agent loop. Encore is not an agent framework but an infrastructure SDK you add to the Axum service running the agent, for its database, Pub/Sub topics and secrets.

Why build AI agents in Rust?

Rust suits agents that run many concurrent tool calls, sit on a latency-sensitive path, or ship as one small binary. The ecosystem is smaller than Python's, so expect to write more glue code.

How do I keep a model API key out of a Rust agent's code with Encore?

Declare a static Secret with Secret::new("OpenAIKey"), set its value per environment with the Encore CLI, and call .value() where the agent client is built. Locally the value comes from your own secrets, and in each environment from the value set for it.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders