Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
ll-core
Hybrid semantic search engine. SQLite-backed, on-device ONNX inference, no external services.
- Embedding trait — model-agnostic interface for ONNX-backed embedders (BGE, mE5, etc.)
- Hybrid scoring — BM25 (FTS5) + vector cosine fused via RRF, with configurable FTS table schema
- Graph scoring — personalized PageRank over pre-loaded edges, for link/citation/participant graphs
- Cross-encoder reranker — ms-marco-MiniLM-L-6-v2 bundled via
include_bytes!, no runtime download - Embedding store — in-memory cache with O(n) cosine over all vectors
- Rocchio PRF — pseudo-relevance feedback for query expansion
Built for local-first tools that need search over SQLite data without shipping a vector database or hitting an API.
Projects using ll-core
learning-loop — A Claude Code plugin that turns your Obsidian vault into a queryable knowledge graph. ll-core powers semantic search, link-graph traversal, and note clustering across thousands of atomic notes. Runs entirely on your machine.
Usage
use EmbeddingProvider;
use ;
use EmbeddingStore;
// Implement EmbeddingProvider for your model, then:
let store = from_data;
// `messages_fts` is an FTS5 table whose rowid is `messages.id`. The content
// table must be a real table (not the FTS table itself), and `id_column` must
// equal the FTS rowid. One bm25 weight per FTS column.
let fts_config = new;
let hits = fts_bm25_query;
// Fuse with vector search via RRF:
let mut rrf_scores = new;
add_ranked_rrf;
let results = finalize_rrf;
Features
bge (off by default) adds models::bge_small: a pinned, SHA-256-verified
bge-small-en-v1.5 loader. models::bge_small::load() locates ONNX Runtime,
downloads the model and tokenizer on first use into ~/.learning-loop/models
(override with LL_MODELS_DIR), and returns a boxed EmbeddingProvider. The
first download shells out to curl, so it must be on PATH.
BgeSmallProvider::from_files_with_threads(model, tokenizer, Some(n)) caps
ONNX Runtime's intra-op threads at n; from_files keeps ORT's default of
every core.
Why another search library?
Existing Rust search crates either ship a full vector database (heavyweight) or are pure algorithms with no SQLite integration (too low-level). ll-core sits in between: enough infrastructure to build a real search experience, thin enough to embed in a sidecar or CLI.
The design came from learning-loop's need to search an Obsidian vault with BM25 + embeddings + wikilink graph + reranking, all running on a laptop.
Releasing
ll-core is maintained in omit's private monorepo at crates/ll-core; the
source of every release is on crates.io.
- On a branch, bump
versionincrates/ll-core/Cargo.toml. Both of these must pass:cargo semver-checks check-release -p ll-core --baseline-version <last>andcargo publish -p ll-core --dry-run --allow-dirty. Merge to main with a merge commit. - From a clean checkout of main, run
cargo publish -p ll-core. It needs the crates.io token in the publishing user's~/.cargo/credentials.toml. - Then tag
ll-core-v<version>on that commit and push the tag.
The tag comes after the publish so that a failed publish leaves no tag behind. learning-loop's old checklist tagged first.
License
MIT. See LICENSE.