Skip to content
Get Started

Build a CLI chatbot

cli_chatbot is a helper in rig that turns any type implementing the Chat trait into an interactive terminal REPL. It reads user input from stdin, keeps a running conversation history so each turn has context, forwards the prompt to your agent, and prints the reply — a fast way to try an agent locally without writing your own input loop.

Build an agent and hand it to cli_chatbot. Because the function takes any Chat-trait value, a plain agent works out of the box:

use rig::client::{CompletionClient, ProviderClient};
use rig::integrations::cli_chatbot::ChatBotBuilder;
use rig::providers::openai;
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// A provider client is required — build the agent from a client instance.
let agent = openai::Client::from_env()?
.agent("gpt-5.5")
.preamble("You are a helpful assistant.")
.build();
// Start the interactive REPL. Type "exit" to quit.
ChatBotBuilder::new().agent(agent).build().run().await?;
Ok(())
}

Run it, and you get a > prompt. Each message you type is appended to the chat history before being sent, so the agent can refer back to earlier turns in the conversation.

  • An interactive REPL with a > prompt reading from stdin.
  • Conversation history maintained across turns and passed to the agent on every prompt.
  • An exit command to leave the loop cleanly.
  • Error handling for I/O and chat failures.
  • Tracing spans for debugging when a subscriber is installed.

cli_chatbot is generic over the Chat trait, so anything that can hold a conversation works — including a RAG agent that fetches context from a vector store on each turn:

use rig::client::{CompletionClient, EmbeddingsClient, ProviderClient};
use rig::integrations::cli_chatbot::ChatBotBuilder;
use rig::providers::openai;
use rig::vector_store::in_memory_store::InMemoryVectorStore;
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let client = openai::Client::from_env()?;
// `index` is an existing VectorStoreIndex built from your embeddings.
let store = InMemoryVectorStore::<serde_json::Value>::default();
let index = store.index(client.embedding_model("text-embedding-3-small"));
let agent = client
.agent("gpt-5.5")
.preamble("Answer using the retrieved context.")
.dynamic_context(2, index)
.build();
ChatBotBuilder::new().agent(agent).build().run().await?;
Ok(())
}

See Vector Stores & RAG for how to populate the store and build the index.