Local AI inference for C# and the command line
Classification, embeddings, semantic search, and reranking. One native library. No Python. No CUDA. No containers. Reads from stdin, writes JSON, pipes like any UNIX tool.

dotnet add package Kjarni
cargo install kjarni-cli
Four capabilities. Same API in C# and on the command line.
Sentiment, emotion, toxicity detection. Pass text in, get labels with confidence scores.
Dense vector representations for semantic similarity, clustering, and retrieval.
Index files from a directory. Keyword, semantic, and hybrid retrieval built in.
Cross-encoder scoring to reorder search results and improve retrieval quality.
You shouldn't need a PhD to classify an email.
One install, nothing else. No Python runtime, no CUDA toolkit, no Docker containers, no API keys. 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# or the terminal.
using Kjarni;
var clf = new Classifier("roberta-sentiment");
var result = clf.Classify("Best purchase I've ever made!");
Console.WriteLine($"{result.Label}: {result.Score:P}");
// positive: 99.98%
# Classify from argument
$ kjarni classify "Best purchase I've ever made!"
positive 99.98% ██████████████████████████████████████
# Pipe from stdin
$ echo "Terrible quality" | kjarni classify
negative 99.69% █████████████████████████████████████
# JSON output for scripting
$ echo "Great product" | kjarni classify --format json | jq '.label'
"positive"
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, ...
$ kjarni classify "you are an idiot" --model toxic-bert
toxic 98.61% ███████████████████████████████████████
insult 96.00% ██████████████████████████████████████
obscene 75.64% ██████████████████████████████████████
severe 4.56% █
identity 1.41%
threat 0.13%
var emb = new Embedder("minilm-l6-v2");
float sim = emb.Similarity("doctor", "physician");
Console.WriteLine($"Similarity: {sim:F4}");
// Similarity: 0.8598
# Semantic similarity
$ kjarni similarity "doctor" "physician"
0.8598
$ kjarni similarity "doctor" "banana"
0.3379
# Generate embedding vector
$ kjarni embed "hello world" --format json | jq '.dimensions'
384
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}");
# Index a folder of documents
$ kjarni index create my-docs --inputs ./docs/
✓ Indexed 51 documents (186 KB)
# Search with hybrid retrieval
$ kjarni search my-docs "password reset"
0.0325 account.txt To reset your password, click...
0.0159 faq.txt How do I change my login cred...
Native binaries for every major platform
x64
x64