Skip to content

Reference

Providers

Sigil needs two things from a provider: an LLM for classification, extraction, AUDM decisions, and synthesis; and an embedder for vectors. They’re configured independently — you can mix a local embedder with a hosted LLM, or the reverse.

ProviderKeyNotes
OpenRouterOPENROUTER_API_KEYOne key, namespaced models across Anthropic / OpenAI / Google / Meta. Default: google/gemini-flash-latest.
AnthropicANTHROPIC_API_KEYDirect Claude access
OpenAIOPENAI_API_KEYCheapest API option — gpt-4o-mini
OllamanoneFully local. Default qwen2.5:7b.
Claude Code (claude-cli)noneUses your existing Claude Code subscription
Codex CLI (codex)noneUses your existing Codex subscription

Not chat. Four structured jobs, in descending order of how much model quality matters:

JobCalledMatters because
AUDM decisionsPer ambiguous candidateGetting these wrong compounds over every future write
Fact extractionPer chunkHigh volume — this is where cost lives
SynthesisPer synthesized searchProse quality is visible
Classification / routingPer message, per querySmall labelling tasks; almost any model is fine

That asymmetry is why per-task routing exists.

At current OpenRouter pricing it’s the best all-rounder for Sigil’s call shapes: $0.0005/$0.003 per 1M tokens, 1M context, strong JSON output, ~500ms typical latency. It beats Claude Haiku roughly 2× on cost and 5× on context while matching reasoning and JSON reliability for extraction, AUDM, classification, routing, and synthesis.

claude-cli shells out to the claude binary and uses your existing subscription — no API key, no per-token cost.

Two caveats. It’s slower than an API call, because it boots a CLI per invocation. And under launchd or systemd the daemon may run with a stripped PATH that can’t see ~/.local/bin or your nvm bin directory:

llm.cliPath = /Users/you/.local/bin/claude

The optional managed-session engine keeps warm workers in tmux to amortize that boot cost across many calls.


ProviderKeyDefault modelNotes
OpenAIOPENAI_API_KEYtext-embedding-3-largeBest quality/cost. 1024 via Matryoshka truncation.
VoyageVOYAGE_API_KEYvoyage-3-largeMTEB ~76, Anthropic-recommended
OpenRouterOPENROUTER_API_KEYnamespacedOne key for both LLM and embeddings
Ollamanonemxbai-embed-largeFree, local, native 1024

Every embedding Sigil stores is exactly 1024 dimensions. The database’s vector(N) columns and every provider are pinned to it.

This is a build-time constant, not configuration. A model that can’t natively emit — or Matryoshka-truncate to — 1024 is rejected at setup rather than failing deep in the pipeline with a dimension-mismatch error that looks like “db not supporting / model not supporting”. Changing it is a schema break.


When you don’t pick explicitly, Sigil walks a waterfall.

LLM: configured provider → OpenRouter key → Anthropic key → OpenAI key → Ollama reachable → claude CLI installed

Embeddings: configured provider → Voyage key → Ollama reachable → OpenAI key

Detection only fills a gap. Once onboarding saves a provider, that’s what’s used — no environment variable can override it, which was a real failure mode under the old .env design.


Send different work to different models with provider:model syntax:

llm.extractionModel = openrouter:qwen/qwen3.5-flash
llm.decisionModel = openrouter:anthropic/claude-sonnet-latest
llm.entityModel = (provider default)
search.synthesizeModel = openrouter:anthropic/claude-sonnet-latest

Cheap model for the high-volume per-chunk extraction; smart model for the per-decision AUDM judgement. OpenRouter’s init flow offers this split as an opt-in “Advanced overrides” step with sensible defaults pre-filled.

Set them in Settings → Advanced.


Zero costOllama + Ollama. Fully local, no key, nothing leaves. Noisier extraction and weaker AUDM. See Fully local.
No new accountClaude Code + Ollama. Reuses a subscription you already pay for; embeddings stay local.
Best valueOpenRouter (Gemini Flash) + OpenAI embeddings. One key covers most models; strong retrieval.
Best qualityOpenRouter with a Sonnet decisionModel + Voyage embeddings.
Privacy-weightedHosted LLM + Ollama embeddings. Embeddings see every chunk of every document; the LLM sees a chunk at a time.

Sees what
DatabaseEverything — but it’s yours
Embedding providerEvery chunk of every ingested document, and every search query
LLM providerChunks during extraction, fact pairs during AUDM, your message during classification
SigilNothing. No telemetry, no account, no phone-home except the GitHub update check.

Disable the update check with preferences.noUpdateCheck (Settings → General).


Settings → Change provider re-runs the same tested step from setup: pick, enter a key, live-test, apply, restart. Or from the terminal, sigil init — it’s idempotent and preserves what you don’t change.

Terminal window
sigil doctor # confirms which providers are live, with a real call

SettingDefaultApplies to
llm.requestTimeout60000Network providers — OpenAI, OpenRouter, Voyage
llm.cliTimeout120000CLI providers and local Ollama generation
llm.maxRetries3All providers
llm.maxClaudeProcs4Concurrent claude processes

Local generation legitimately runs longer than an API call, which is why Ollama uses the CLI timeout. The maxClaudeProcs semaphore exists because an unbounded ingest fan-out once produced 1600+ live sessions.