Vapora/crates/vapora-rlm/examples/local_ollama.rs

103 lines
3.2 KiB
Rust
Raw Normal View History

2026-02-16 05:09:51 +00:00
// Local Development Setup with Ollama
// No API keys required - uses local Ollama for LLM and embeddings
use std::sync::Arc;
use surrealdb::engine::remote::ws::Ws;
use surrealdb::opt::auth::Root;
use surrealdb::Surreal;
use vapora_llm_router::providers::OllamaClient;
use vapora_rlm::chunking::{ChunkingConfig, ChunkingStrategy};
use vapora_rlm::embeddings::EmbeddingConfig;
use vapora_rlm::engine::RLMEngineConfig;
use vapora_rlm::search::bm25::BM25Index;
use vapora_rlm::storage::SurrealDBStorage;
use vapora_rlm::RLMEngine;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("🦙 Local RLM Setup with Ollama");
println!("Prerequisites:");
println!(" - SurrealDB: docker run -p 8000:8000 surrealdb/surrealdb:latest start");
println!(" - Ollama: brew install ollama && ollama serve");
println!(" - Model: ollama pull llama3.2\n");
// 1. Setup SurrealDB
let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;
db.signin(Root {
username: "root",
password: "root",
})
.await?;
db.use_ns("local").use_db("rlm").await?;
// 2. Setup Ollama client (local, no API key needed)
let llm_client = Arc::new(OllamaClient::new(
"http://localhost:11434".to_string(),
"llama3.2".to_string(),
4096, // max_tokens
0.7, // temperature
)?);
// 3. Create storage and BM25 index
let storage = Arc::new(SurrealDBStorage::new(db));
let bm25_index = Arc::new(BM25Index::new()?);
// 4. Configure RLM engine for local development
let rlm_config = RLMEngineConfig {
chunking: ChunkingConfig {
strategy: ChunkingStrategy::Fixed,
chunk_size: 500,
overlap: 100,
},
embedding: Some(EmbeddingConfig::ollama("llama3.2")),
auto_rebuild_bm25: true,
max_chunks_per_doc: 5_000,
};
// 5. Create RLM engine with Ollama client
let engine = RLMEngine::with_llm_client(storage, bm25_index, llm_client, Some(rlm_config))?;
println!("✓ RLM Engine configured with Ollama\n");
// 6. Example: Analyze Rust code
let doc_id = "rust-example";
let content = r#"
fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
// This recursive implementation has exponential time complexity.
// A better approach would use dynamic programming or iteration.
"#;
println!("📄 Loading Rust code...");
let chunk_count = engine.load_document(doc_id, content, None).await?;
println!("✓ Loaded {} chunks\n", chunk_count);
println!("🔍 Searching for 'complexity'...");
let results = engine.query(doc_id, "complexity", None, 3).await?;
println!("✓ Found {} results\n", results.len());
println!("🦙 Asking Ollama to explain the code...");
let response = engine
.dispatch_subtask(
doc_id,
"Explain this Rust code and suggest improvements",
None,
3,
)
.await?;
println!("✓ Ollama says:\n{}\n", response.text);
println!(
" (Used {} tokens)",
response.total_input_tokens + response.total_output_tokens
);
Ok(())
}