Examples
This guide provides practical examples for common rlm-cli workflows.
Table of Contents
Section titled “Table of Contents”- Basic CLI Usage
- Chunking Strategies
- Search Workflows
- Claude Code Integration
- Agentic Workflows
- Rust Library Usage
- Advanced Patterns
Basic CLI Usage
Section titled “Basic CLI Usage”Initialize and Load a Document
Section titled “Initialize and Load a Document”# Initialize databaserlm-cli init
# Load a markdown file with semantic chunkingrlm-cli load README.md --name readme --chunker semantic
# Check statusrlm-cli status
# Output:# Database: .rlm/rlm-state.db (256 KB)# Buffers: 1# Total chunks: 47# Embedded chunks: 47 (100%)Search and Retrieve
Section titled “Search and Retrieve”# Hybrid search (semantic + BM25)rlm-cli search "installation instructions" --buffer readme --mode hybrid --top-k 5
# Output:# Chunk ID: 12 | Score: 0.89 | Buffer: readme# ## Installation## ### Via Cargo (Recommended)# cargo install rlm-cli# ...
# Retrieve specific chunk by IDrlm-cli chunk get 12
# Regex search for specific patternsrlm-cli grep readme "cargo install" --context 2Chunking Strategies
Section titled “Chunking Strategies”Semantic Chunking (Markdown/Documentation)
Section titled “Semantic Chunking (Markdown/Documentation)”Best for: Markdown, documentation, prose
# Load with semantic boundaries (headings, paragraphs)rlm-cli load docs/architecture.md \ --name architecture \ --chunker semantic \ --chunk-size 150000 \ --overlap 1000
# Chunk boundaries respect:# - Markdown headings (##, ###)# - Paragraph breaks# - Code blocks# - List boundariesTypical output:
- Chunk 1: Introduction section
- Chunk 2: Architecture Overview section
- Chunk 3: Module Structure section
Code-Aware Chunking (Source Files)
Section titled “Code-Aware Chunking (Source Files)”Best for: Source code (Rust, Python, JavaScript, etc.)
# Load Rust source with code-aware chunkingrlm-cli load src/main.rs \ --name main-source \ --chunker code
# Splits at function/struct/impl boundariesSupported languages:
- Rust, Python, JavaScript, TypeScript
- Go, Java, C/C++, Ruby, PHP
Example chunk boundaries:
// Chunk 1: Imports + struct definitionuse std::io;pub struct Config { ... }
// Chunk 2: First impl blockimpl Config { pub fn new() -> Self { ... }}
// Chunk 3: Second impl blockimpl Default for Config { ... }Fixed Chunking (Logs/Plain Text)
Section titled “Fixed Chunking (Logs/Plain Text)”Best for: Log files, plain text, structured data
# Fixed-size chunks with overlaprlm-cli load logs/server.log \ --name server-logs \ --chunker fixed \ --chunk-size 100000 \ --overlap 500
# Splits at exact byte boundaries# Overlap ensures no context loss at chunk edgesParallel Chunking (Large Files)
Section titled “Parallel Chunking (Large Files)”Best for: Large files (>10MB), multi-core systems
# Parallel chunking for speedrlm-cli load dataset.txt \ --name large-dataset \ --chunker parallel \ --chunk-size 200000
# Uses all CPU cores (Rayon thread pool)# Typically 3-5x faster than sequential chunkingPerformance example:
| File Size | Sequential | Parallel (8 cores) |
|---|---|---|
| 10 MB | 2.5s | 0.8s |
| 100 MB | 25s | 6s |
| 1 GB | 4m 10s | 1m 2s |
Search Workflows
Section titled “Search Workflows”Hybrid Search (Semantic + BM25)
Section titled “Hybrid Search (Semantic + BM25)”Combines semantic similarity and keyword matching using RRF (Reciprocal Rank Fusion):
# Hybrid search with RRF fusionrlm-cli search "error handling patterns" \ --buffer main-source \ --mode hybrid \ --top-k 10
# Scores combine:# - Semantic similarity (cosine distance)# - BM25 keyword relevance# - RRF fusion (k=60)Use cases:
- Finding conceptually similar content with keyword relevance
- Robust search when terminology varies
- Best balance of precision and recall
Semantic-Only Search
Section titled “Semantic-Only Search”Pure vector similarity search:
# Semantic search onlyrlm-cli search "how to configure the database" \ --buffer architecture \ --mode semantic \ --top-k 5
# Uses cosine similarity of BGE-M3 embeddings# Good for: conceptual matches, paraphrased queriesBM25-Only Search
Section titled “BM25-Only Search”Keyword-based full-text search:
# BM25 keyword searchrlm-cli search "SQLite initialization" \ --buffer architecture \ --mode bm25 \ --top-k 5
# Uses FTS5 full-text index# Good for: exact terms, technical jargon, code identifiersSearch with Filters
Section titled “Search with Filters”# Search specific bufferrlm-cli search "async" --buffer main-source
# List all chunks in a bufferrlm-cli chunk list --buffer main-source
# Get embedding statusrlm-cli chunk status --buffer main-sourceClaude Code Integration
Section titled “Claude Code Integration”Complete RLM Workflow
Section titled “Complete RLM Workflow”Scenario: Analyze a large codebase with Claude Code
Step 1: Load the codebase
# Initialize rlm-rsrlm-cli init
# Load each source directoryrlm-cli load src/ --name source-code --chunker coderlm-cli load tests/ --name test-code --chunker coderlm-cli load docs/ --name documentation --chunker semantic
# Check statusrlm-cli status# Output: 3 buffers, 542 chunks, 100% embeddedStep 2: Search and retrieve context
# Find error handling patternsrlm-cli search "error handling" \ --buffer source-code \ --mode hybrid \ --top-k 10 \ --format json > results.json
# Get specific chunks by IDrlm-cli chunk get 127 --format jsonStep 3: Dispatch to subagents
# Split chunks into batches for parallel analysisrlm-cli dispatch source-code \ --batch-size 5 \ --task "Analyze error handling patterns" \ --format json > batches.json
# Each batch contains chunk IDs for subagent processingStep 4: Aggregate results
# After subagent analysis, combine findingsrlm-cli aggregate \ --findings findings1.json findings2.json findings3.json \ --output summary.jsonUsing with Claude Code MCP Plugin
Section titled “Using with Claude Code MCP Plugin”Install the rlm-rs MCP plugin:
# Configure Claude Codecat > ~/.config/claude-code/mcp.json <<EOF{ "mcpServers": { "rlm": { "command": "rlm-mcp-server", "args": ["--db-path", ".rlm/rlm-state.db"] } }}EOF
# Start Claude Code - rlm-rs tools are now availableAvailable MCP tools:
rlm_load- Load files into buffersrlm_search- Hybrid searchrlm_chunk_get- Retrieve chunks by IDrlm_dispatch- Create subagent batches
Agentic Workflows
Section titled “Agentic Workflows”Orchestrator → Analyst → Synthesizer Pattern
Section titled “Orchestrator → Analyst → Synthesizer Pattern”Architecture:
┌──────────────┐│ Orchestrator │ Root LLM (Opus/Sonnet)└──────┬───────┘ │ dispatch ▼┌──────────────┐│ Analysts │ Sub-LLMs (Haiku) - Process batches│ (parallel) │└──────┬───────┘ │ findings ▼┌──────────────┐│ Synthesizer │ Root LLM - Aggregate results└──────────────┘Implementation:
# 1. Orchestrator: Create analysis batchesrlm-cli dispatch codebase \ --batch-size 10 \ --task "Find security vulnerabilities" \ --output batches.json
# batches.json:# [# {"batch_id": 1, "chunks": [1,2,3,4,5,6,7,8,9,10]},# {"batch_id": 2, "chunks": [11,12,13,14,15,16,17,18,19,20]},# ...# ]
# 2. Analyst: Process each batch (parallel)for batch in $(jq -r '.[] | @base64' batches.json); do BATCH_ID=$(echo $batch | base64 -d | jq -r '.batch_id') CHUNK_IDS=$(echo $batch | base64 -d | jq -r '.chunks[]')
# Retrieve chunks for chunk_id in $CHUNK_IDS; do rlm-cli chunk get $chunk_id >> "batch_${BATCH_ID}_content.txt" done
# Analyze with sub-LLM (Haiku) analyze_security "batch_${BATCH_ID}_content.txt" > "findings_${BATCH_ID}.json"done
# 3. Synthesizer: Aggregate findingsrlm-cli aggregate findings_*.json --output final_report.jsonPrompt Templates
Section titled “Prompt Templates”See docs/prompts/ for reference:
- rlm-orchestrator.md - Root LLM prompt for task decomposition
- rlm-analyst.md - Sub-LLM prompt for chunk analysis
- rlm-synthesizer.md - Root LLM prompt for result aggregation
Rust Library Usage
Section titled “Rust Library Usage”Basic Initialization
Section titled “Basic Initialization”use rlm_rs::{ storage::{SqliteStorage, Storage}, core::Buffer, chunking::{SemanticChunker, Chunker}, error::Result,};
fn main() -> Result<()> { // Initialize storage let mut storage = SqliteStorage::new(".rlm/rlm-state.db")?; storage.create_schema()?;
// Create buffer let content = std::fs::read_to_string("document.md")?; let buffer = Buffer::new("docs", content);
// Chunk content let chunker = SemanticChunker::new(150_000, 1000); let chunks = chunker.chunk(&buffer)?;
println!("Created {} chunks", chunks.len()); Ok(())}Embedding and Search
Section titled “Embedding and Search”use rlm_rs::{ embedding::{FastEmbedEmbedder, Embedder}, search::hybrid_search, storage::{SqliteStorage, Storage},};
fn search_example() -> Result<()> { let mut storage = SqliteStorage::new(".rlm/rlm-state.db")?;
// Initialize embedder (requires fastembed-embeddings feature) #[cfg(feature = "fastembed-embeddings")] { let embedder = FastEmbedEmbedder::new()?;
// Embed query let query_embedding = embedder.embed("error handling")?;
// Hybrid search let results = hybrid_search( &mut storage, "error handling", &query_embedding, "codebase", 10, // top-k )?;
for result in results { println!("Chunk {}: {:.2}", result.chunk_id, result.score); } }
Ok(())}Custom Chunking Strategy
Section titled “Custom Chunking Strategy”use rlm_rs::{ chunking::{Chunker, traits::ChunkerTrait}, core::{Buffer, Chunk}, error::Result,};
struct CustomChunker { delimiter: String,}
impl ChunkerTrait for CustomChunker { fn chunk(&self, buffer: &Buffer) -> Result<Vec<Chunk>> { let parts: Vec<&str> = buffer.content() .split(&self.delimiter) .collect();
let chunks = parts .into_iter() .enumerate() .map(|(idx, content)| { Chunk::new( idx as i64, buffer.name().to_string(), content.to_string(), idx * content.len(), ) }) .collect();
Ok(chunks) }}
fn main() -> Result<()> { let buffer = Buffer::new("data", "part1|||part2|||part3".to_string()); let chunker = CustomChunker { delimiter: "|||".to_string(), };
let chunks = chunker.chunk(&buffer)?; println!("Created {} chunks", chunks.len()); Ok(())}Advanced Patterns
Section titled “Advanced Patterns”Incremental Updates
Section titled “Incremental Updates”Update buffer content and re-embed only changed chunks:
# Initial loadrlm-cli load document.md --name docs
# Modify document.md externally# ...
# Update buffer (only re-embeds changed chunks)rlm-cli update-buffer docs document-updated.md
# Force re-embedding all chunksrlm-cli chunk embed --buffer docs --forceMulti-Buffer Workflows
Section titled “Multi-Buffer Workflows”Work with multiple document sources:
# Load multiple sourcesrlm-cli load api-docs.md --name api-docs --chunker semanticrlm-cli load source-code/ --name source --chunker coderlm-cli load tests/ --name tests --chunker code
# Search across all buffersrlm-cli search "authentication" --top-k 10
# Search specific bufferrlm-cli search "authentication" --buffer api-docs
# Export all buffersrlm-cli export-buffers --output all-buffers.jsonContext Variables
Section titled “Context Variables”Use variables for dynamic context management:
# Set context variablerlm-cli var set current_task "security-audit"
# Get variablerlm-cli var get current_task# Output: security-audit
# List all variablesrlm-cli var list
# Set global variable (persistent across sessions)rlm-cli global set project_name "rlm-rs"Regex Search with Context
Section titled “Regex Search with Context”# Search with context linesrlm-cli grep source-code "fn main" \ --context 5 \ --max-matches 10
# Output:# Buffer: source-code | Match: 1# ----# use std::io;# use clap::Parser;## fn main() {# let args = Cli::parse();# // ...# }# ----
# Case-insensitive searchrlm-cli grep docs "error" --ignore-caseJSON Output for Scripting
Section titled “JSON Output for Scripting”# JSON output for programmatic userlm-cli search "async" --buffer source --format json | jq '.results[0]'
# Output:# {# "chunk_id": 42,# "buffer_name": "source",# "score": 0.87,# "content": "async fn process_data() { ... }",# "start_offset": 12500# }
# Chain with other toolsrlm-cli chunk list --buffer source --format json \ | jq '.chunks | length'# Output: 127Peek at Buffer Content
Section titled “Peek at Buffer Content”# View first 3000 charactersrlm-cli peek docs --start 0 --end 3000
# View middle sectionrlm-cli peek docs --start 10000 --end 15000
# View from offset to endrlm-cli peek docs --start 50000Write Chunks to Files
Section titled “Write Chunks to Files”# Export each chunk to separate filesrlm-cli write-chunks source-code --output-dir ./chunks/
# Result:# chunks/# ├── chunk_0001.txt# ├── chunk_0002.txt# ├── chunk_0003.txt# ...Performance Tips
Section titled “Performance Tips”Chunking Performance
Section titled “Chunking Performance”# For large files, use parallel chunkingrlm-cli load large-file.txt \ --chunker parallel \ --chunk-size 100000
# Reduce chunk size for faster embeddingrlm-cli load docs.md \ --chunker semantic \ --chunk-size 50000 # Smaller chunks = faster embeddingSearch Performance
Section titled “Search Performance”# Use smaller top-k for faster resultsrlm-cli search "query" --top-k 5 # vs --top-k 100
# Use BM25-only for faster keyword searchrlm-cli search "exact term" --mode bm25
# Use semantic-only for concept searchrlm-cli search "general idea" --mode semanticMemory Management
Section titled “Memory Management”# For very large files, increase chunk size to reduce memoryrlm-cli load huge-file.txt \ --chunker parallel \ --chunk-size 500000 # Larger chunks = fewer in memory
# Export and delete old buffersrlm-cli export-buffers --output backup.jsonrlm-cli delete old-bufferTroubleshooting
Section titled “Troubleshooting”Slow Embedding Generation
Section titled “Slow Embedding Generation”Symptom: rlm-cli load takes minutes to complete
Solutions:
# 1. Use parallel chunkingrlm-cli load file.txt --chunker parallel
# 2. Increase chunk size (fewer chunks to embed)rlm-cli load file.txt --chunk-size 200000
# 3. Check CPU usage (should be 100% across all cores)top -p $(pgrep rlm-cli)Out of Memory Errors
Section titled “Out of Memory Errors”Symptom: rlm-cli search crashes with OOM
Solutions:
# 1. Reduce top-krlm-cli search "query" --top-k 5 # Instead of 100
# 2. Delete unused buffersrlm-cli listrlm-cli delete unused-buffer
# 3. Rebuild without HNSWcargo build --release --features fastembed-embeddingsMissing Embeddings
Section titled “Missing Embeddings”Symptom: Semantic search returns empty results
Solutions:
# 1. Check embedding statusrlm-cli chunk status --buffer docs
# 2. Generate embeddings if missingrlm-cli chunk embed --buffer docs
# 3. Force re-embeddingrlm-cli chunk embed --buffer docs --forceNext Steps
Section titled “Next Steps”- Features Guide - Learn about feature flags and optimization
- CLI Reference - Complete command documentation
- Architecture - Understand internal design
- Plugin Integration - Integrate with Claude Code and other tools