Welcome to the new Golem Cloud Docs! 👋
Adding LLM and AI Capabilities (Rust)

Adding LLM and AI Capabilities (Rust)

Overview

Golem provides the golem-ai library collection — a set of Rust crates from golemcloud/golem-ai (opens in a new tab) that provide unified, provider-agnostic APIs for AI capabilities. Each domain has a core crate (shared types and traits) plus provider crates (concrete backends). You add them as regular Cargo dependencies and call them directly from your agent code.

These crates are not on crates.io yet. Use git dependencies pointing to the v0.5.0-dev.2 tag.

Available Libraries

LLM (Chat Completions)

Core crate: golem-ai-llm — unified chat completion API with blocking and streaming responses, multi-turn conversation, tool calling, and multimodal image inputs.

Provider crates (pick one):

ProviderCrateRequired Env Vars
OpenAIgolem-ai-llm-openaiOPENAI_API_KEY
Anthropicgolem-ai-llm-anthropicANTHROPIC_API_KEY
Amazon Bedrockgolem-ai-llm-bedrockAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
xAI / Grokgolem-ai-llm-grokXAI_API_KEY
Ollamagolem-ai-llm-ollamaGOLEM_OLLAMA_BASE_URL (optional, defaults to http://localhost:11434)
OpenRoutergolem-ai-llm-openrouterOPENROUTER_API_KEY

Embeddings & Reranking

Core crate: golem-ai-embed — generate vector embeddings from text/images and rerank documents by relevance.

Provider crates:

ProviderCrateRequired Env Vars
OpenAIgolem-ai-embed-openaiOPENAI_API_KEY
Coheregolem-ai-embed-cohereCOHERE_API_KEY
Hugging Facegolem-ai-embed-hugging-faceHUGGING_FACE_API_KEY
VoyageAIgolem-ai-embed-voyageaiVOYAGEAI_API_KEY

Web Search

Core crate: golem-ai-web-search — unified web search with one-shot and paginated session modes.

Provider crates:

ProviderCrateRequired Env Vars
Bravegolem-ai-web-search-braveBRAVE_API_KEY
Googlegolem-ai-web-search-googleGOOGLE_API_KEY, GOOGLE_SEARCH_ENGINE_ID
Serpergolem-ai-web-search-serperSERPER_API_KEY
Tavilygolem-ai-web-search-tavilyTAVILY_API_KEY

Document Search

Core crate: golem-ai-search — full-text/document search with index management, document CRUD, faceted search.

Provider crates:

ProviderCrateRequired Env Vars
Algoliagolem-ai-search-algoliaALGOLIA_APPLICATION_ID, ALGOLIA_API_KEY
Elasticsearchgolem-ai-search-elasticsearchELASTICSEARCH_URL, credentials
Meilisearchgolem-ai-search-meilisearchMEILISEARCH_BASE_URL, MEILISEARCH_API_KEY
OpenSearchgolem-ai-search-opensearchOPENSEARCH_BASE_URL, credentials
Typesensegolem-ai-search-typesenseTYPESENSE_BASE_URL, TYPESENSE_API_KEY

Graph Databases

Core crate: golem-ai-graph — vertex/edge CRUD, traversal, path-finding, transactions, schema management.

Provider crates:

ProviderCrate
ArangoDBgolem-ai-graph-arangodb
JanusGraphgolem-ai-graph-janusgraph
Neo4jgolem-ai-graph-neo4j

Vector Databases

Core crate: golem-ai-vector — collection management, vector upsert/search, ANN queries, namespaces.

Provider crates:

ProviderCrate
Qdrantgolem-ai-vector-qdrant
Milvusgolem-ai-vector-milvus
PgVectorgolem-ai-vector-pgvector
Pineconegolem-ai-vector-pinecone

Video Generation

Core crate: golem-ai-video — text-to-video, image-to-video, async job polling.

Provider crates:

ProviderCrate
Google Veogolem-ai-video-veo
Stability AIgolem-ai-video-stability
Klinggolem-ai-video-kling
Runway MLgolem-ai-video-runway

Speech-to-Text

Core crate: golem-ai-stt — audio transcription with speaker diarization, word-level timing.

Provider crates:

ProviderCrate
OpenAI Whispergolem-ai-stt-whisper
Deepgramgolem-ai-stt-deepgram
AWS Transcribegolem-ai-stt-aws
Azure Speechgolem-ai-stt-azure
Google STTgolem-ai-stt-google

Text-to-Speech

Core crate: golem-ai-tts — voice discovery, batch/streaming synthesis, SSML support.

Provider crates:

ProviderCrate
AWS Pollygolem-ai-tts-aws
Deepgramgolem-ai-tts-deepgram
ElevenLabsgolem-ai-tts-elevenlabs
Google Cloud TTSgolem-ai-tts-google

Adding Dependencies

Add the core crate plus your chosen provider to the component's Cargo.toml:

[dependencies]
# LLM — core + provider
golem-ai-llm = { git = "https://github.com/golemcloud/golem-ai", tag = "v0.5.0-dev.2" }
golem-ai-llm-openai = { git = "https://github.com/golemcloud/golem-ai", tag = "v0.5.0-dev.2" }

Store the required API key as a secret using Golem's typed config system. See the golem-add-secret-rust skill for full details. In brief:

use golem_rust::ConfigSchema;
use golem_rust::agentic::{Config, Secret};
 
#[derive(ConfigSchema)]
pub struct MyAgentConfig {
    #[config_schema(secret)]
    pub api_key: Secret<String>,
}

Then manage the secret via the CLI:

golem agent-secret create api_key --secret-type String --secret-value "sk-..."

Usage: LLM Chat Completion

use golem_ai_llm::model::*;
use golem_ai_llm::LlmProvider;
 
// Pick a provider — type alias makes it easy to swap later
type Provider = golem_ai_llm_openai::DurableOpenAI;
 
let config = Config {
    model: "gpt-4o".to_string(),
    temperature: None,
    max_tokens: None,
    stop_sequences: None,
    tools: None,
    tool_choice: None,
    provider_options: None,
};
 
let events = vec![Event::Message(Message {
    role: Role::User,
    name: None,
    content: vec![ContentPart::Text("Hello!".to_string())],
})];
 
// Blocking request
let response = Provider::send(events, config).expect("LLM call failed");
 
// Extract text from response
let text: String = response
    .content
    .iter()
    .filter_map(|part| match part {
        ContentPart::Text(txt) => Some(txt.clone()),
        _ => None,
    })
    .collect::<Vec<_>>()
    .join("\n");

Usage: Multi-turn Conversation (Session)

use golem_ai_llm::model::*;
use golem_ai_llm::LlmProvider;
 
type Provider = golem_ai_llm_openai::DurableOpenAI;
 
// Keep events as agent state for multi-turn conversation
let mut events: Vec<Event> = vec![];
 
// Add system message
events.push(Event::Message(Message {
    role: Role::System,
    name: None,
    content: vec![ContentPart::Text("You are a helpful assistant.".to_string())],
}));
 
// Add user message
events.push(Event::Message(Message {
    role: Role::User,
    name: None,
    content: vec![ContentPart::Text("What is Golem?".to_string())],
}));
 
let config = Config {
    model: "gpt-4o".to_string(),
    temperature: None,
    max_tokens: None,
    stop_sequences: None,
    tools: None,
    tool_choice: None,
    provider_options: None,
};
 
// Send and record the response for next turn
let response = Provider::send(events.clone(), config.clone()).expect("LLM call failed");
events.push(Event::Response(response));

Usage: Web Search

use golem_ai_web_search::model::types;
use golem_ai_web_search::model::web_search;
 
type SearchProvider = golem_ai_web_search_google::DurableGoogleCustomSearch;
 
let session = SearchProvider::start_search(&web_search::SearchParams {
    query: "Golem distributed computing".to_string(),
    language: Some("lang_en".to_string()),
    safe_search: Some(types::SafeSearchLevel::Off),
    max_results: Some(10),
    time_range: None,
    include_domains: None,
    exclude_domains: None,
    include_images: None,
    include_html: None,
    advanced_answer: Some(true),
    region: None,
}).expect("Failed to start search");
 
let results = session.next_page().expect("Failed to get results");
for result in results {
    println!("{}: {}", result.title, result.url);
}

Switching Providers

To switch providers, change the type alias and dependency. The core API stays the same:

// Switch from OpenAI to Anthropic:
// 1. In Cargo.toml: replace golem-ai-llm-openai with golem-ai-llm-anthropic
// 2. In code:
type Provider = golem_ai_llm_anthropic::DurableAnthropic;
// All other code stays the same

Complete Agent Example

use golem_ai_llm::model::*;
use golem_ai_llm::LlmProvider;
use golem_rust::{agent_definition, agent_implementation, endpoint};
 
type Provider = golem_ai_llm_openai::DurableOpenAI;
 
#[agent_definition(mount = "/chats/{chat_name}")]
pub trait ChatAgent {
    fn new(chat_name: String) -> Self;
 
    #[endpoint(post = "/ask")]
    async fn ask(&mut self, question: String) -> String;
}
 
struct ChatAgentImpl {
    chat_name: String,
    events: Vec<Event>,
    config: Config,
}
 
#[agent_implementation]
impl ChatAgent for ChatAgentImpl {
    fn new(chat_name: String) -> Self {
        let config = Config {
            model: std::env::var("LLM_MODEL").unwrap_or_else(|_| "gpt-4o".to_string()),
            temperature: None,
            max_tokens: None,
            stop_sequences: None,
            tools: None,
            tool_choice: None,
            provider_options: None,
        };
        let events = vec![Event::Message(Message {
            role: Role::System,
            name: None,
            content: vec![ContentPart::Text(format!(
                "You are a helpful assistant for chat '{}'",
                chat_name
            ))],
        })];
        Self { chat_name, events, config }
    }
 
    async fn ask(&mut self, question: String) -> String {
        self.events.push(Event::Message(Message {
            role: Role::User,
            name: None,
            content: vec![ContentPart::Text(question)],
        }));
 
        let response = Provider::send(self.events.clone(), self.config.clone())
            .expect("LLM call failed");
        self.events.push(Event::Response(response.clone()));
 
        response
            .content
            .iter()
            .filter_map(|part| match part {
                ContentPart::Text(txt) => Some(txt.clone()),
                _ => None,
            })
            .collect::<Vec<_>>()
            .join("\n")
    }
}

Key Constraints

  • All golem-ai crates must be added as git dependencies from https://github.com/golemcloud/golem-ai with tag = "v0.5.0-dev.2" — they are not on crates.io yet
  • Always add both the core crate and a provider crate (e.g., golem-ai-llm + golem-ai-llm-openai)
  • Provider API keys should be stored as secrets using Golem's typed config system (See the golem-add-secret-rust guide)
  • The Durable* provider types (e.g., DurableOpenAI) automatically integrate with Golem's durable execution — responses are recorded in the oplog and replayed on recovery
  • To switch providers, change the type alias and Cargo dependency — the rest of the code stays the same
  • These crates target wasm32-wasip1 and work correctly in Golem's WebAssembly environment