Local AI inference for C#, Go, Rust and the command line
Embeddings, classification, semantic search, reranking, chat, transcription, summarization and translation. One native library, running inside your process. Your text stays on your machine. Reads from stdin, writes JSON, pipes like any UNIX tool.
Hybrid search with reranking, semantic + BM25

Text classification, running entirely on this machine

Embeddings and similarity

dotnet add package Kjarni
npm i kjarni-wasm
go get github.com/olafurjohannsson/kjarni-go@latest
curl -fsSL https://kjarni.ai/install.sh | sh
irm https://kjarni.ai/install.ps1 | iex
Encoders, decoders and seq2seq, from one dependency-free package. Every capability is available on the command line; the badges show where else it runs today.
Measure how close two pieces of text are in meaning. Powers related articles, duplicate detection, and matching a question to the right FAQ entry.
Sort text into categories without training anything. Route support tickets by tone, flag abusive comments before they post, track how customers feel about a release.
Find the right document when the user did not use your words for it. Point it at a directory and query by keyword, by meaning, or both. The index is a folder on disk.
Your search returns twenty results and the right one sits at position eleven. A cross-encoder rescores the shortlist and lifts it to the top.
Add an assistant feature to software that has to keep working without a network, or where the text cannot leave the building. Streaming tokens, multi-turn, sampling control.
Turn recorded audio into searchable text: meetings, calls, interviews. Word-level timestamps and token streaming when you need them.
Condense long documents into something a person will actually read. Works from a purpose-built model or an instruct model of your choice.
Translate content between languages on your own hardware, which matters when the text is under contract or regulation and cannot be sent to a translation service.
You shouldn't need a PhD to classify an email.
One install, nothing else. A single native library that loads into your process, on CPU, offline after the first run. Models download on first use and cache locally.
dotnet add package Kjarnicargo install kjarni-cliYou get Classifier, not BertForSequenceClassification. Kjarni hides tokenizers, attention masks, and pooling strategies.
The CLI reads from stdin, writes to stdout, and outputs JSON. Pipe it to jq, grep, or into your scripts. It's a tool, not a framework.
cat reviews.txt | kjarni classifykjarni classify --format json | jqSame capabilities in C#, Go, or the terminal.
using Kjarni;
var clf = new Classifier("distilbert-sentiment");
var result = clf.Classify("Best purchase I've ever made!");
Console.WriteLine($"{result.Label}: {result.Score:P}");
// POSITIVE: 100.0%
import "github.com/olafurjohannsson/kjarni-go"
c, _ := kjarni.NewClassifier("distilbert-sentiment")
defer c.Close()
result, _ := c.Classify("Best purchase I've ever made!")
fmt.Printf("%s: %.1f%%\n", result.Label, result.Score*100)
// POSITIVE: 100.0%
$ kjarni classify "Best purchase I've ever made!"
✓ POSITIVE ████████████████████ 100.0%
NEGATIVE ░░░░░░░░░░░░░░░░░░░░ 0.0%
# Pipe from stdin
$ echo "Terrible quality" | kjarni classify
✓ NEGATIVE ████████████████████ 100.0%
POSITIVE ░░░░░░░░░░░░░░░░░░░░ 0.0%
var clf = new Classifier("toxic-bert");
var result = clf.Classify(userMessage);
if (result.Label == "toxic" && result.Score > 0.8f)
{
// flag for moderation
}
// Multi-label: toxic, insult, obscene, threat, ...
c, _ := kjarni.NewClassifier("toxic-bert")
defer c.Close()
result, _ := c.Classify(userMessage)
if result.Label == "toxic" && result.Score > 0.8 {
// flag for moderation
}
// Multi-label: toxic, insult, obscene, threat, ...
$ kjarni classify "You are the worst cook ever" --model toxic-bert
✓ toxic ███████████████████░ 92.8%
insult ██████████████░░░░░░ 72.3%
obscene ██░░░░░░░░░░░░░░░░░░ 7.6%
identity_hate ░░░░░░░░░░░░░░░░░░░░ 0.5%
severe_toxic ░░░░░░░░░░░░░░░░░░░░ 0.3%
var emb = new Embedder("minilm-l6-v2");
float sim = emb.Similarity("doctor", "physician");
Console.WriteLine($"Similarity: {sim:P}");
// Similarity: 86.0%
e, _ := kjarni.NewEmbedder("minilm-l6-v2")
defer e.Close()
sim, _ := e.Similarity("doctor", "physician")
fmt.Printf("Similarity: %.1f%%\n", sim*100)
// Similarity: 86.0%
$ kjarni similarity "doctor" "physician"
█████████████████░░░ 86.0% highly similar
$ kjarni similarity "doctor" "banana"
███████░░░░░░░░░░░░░ 33.8% somewhat related
var indexer = new Indexer("minilm-l6-v2");
indexer.Create("./my-index", new[] { "./docs" });
var searcher = new Searcher("minilm-l6-v2", "");
var results = searcher.Search("./my-index", "query");
foreach (var r in results)
Console.WriteLine($"{r.Score:F3}: {r.Text}");
idx, _ := kjarni.NewIndexer("minilm-l6-v2")
defer idx.Close()
idx.Create("./my-index", []string{"./docs"})
s, _ := kjarni.NewSearcher("minilm-l6-v2", "")
defer s.Close()
results, _ := s.Search("./my-index", "query", kjarni.Hybrid)
for _, r := range results {
fmt.Printf("%.3f: %s\n", r.Score, r.Text)
}
# Index a folder of documents
$ kjarni index create my-docs docs/*
✓ Indexed 15 documents (39.52 KB)
# Search with hybrid retrieval
$ kjarni search my-docs "keeping data safe" --top-k 3
1. cryptocraphy.txt
████████████████████ 100.0%
2. tcpip.txt
██████████░░░░░░░░░░ 49.2%
3. neuralnetworks.txt
░░░░░░░░░░░░░░░░░░░░ 0.0%
Native binaries for every major platform
x64
x64