Configuration
haiku.rag reads its configuration from a YAML file. Every setting has a default, so a file sets only what differs.
Note
The embedding model in the configuration must match the one a database was built with. See Operational constraints for what a mismatch does and how to reconcile it.
Getting started
Generate a configuration file with defaults:
This writes haiku.rag.yaml in the current directory with every setting and its default. haiku-rag settings prints the configuration in effect.
Configuration file locations
haiku.rag searches for configuration files in this order:
- Path specified via
--configflag:haiku-rag --config /path/to/config.yaml <command>, or theHAIKU_RAG_CONFIG_PATHenvironment variable, which library use reads too. A path that does not exist is an error. ./haiku.rag.yaml(current directory)- Platform-specific user directory:
- Linux:
~/.local/share/haiku.rag/haiku.rag.yaml - macOS:
~/Library/Application Support/haiku.rag/haiku.rag.yaml - Windows:
C:/Users/<USER>/AppData/Roaming/haiku.rag/haiku.rag.yaml
- Linux:
Environment variables
Any string value can reference an environment variable, so secrets stay out of the file and one config can serve multiple deployments:
ingester:
queue:
dburi: postgresql+asyncpg://haiku:${POSTGRES_PASSWORD}@db:5432/haiku_rag
namespace: ${SOURCE}
${VAR}is replaced with the value ofVAR. IfVARis unset or empty, loading fails with an error naming the variable.${VAR:-default}usesdefaultwhenVARis unset or empty.$$produces a literal$.${HAIKU_RAG_CONFIG_DIR}is the absolute directory of the config file, so${HAIKU_RAG_CONFIG_DIR}/papers.lancedbplaces a database next to it. The environment cannot override it.
Substitution happens after the YAML is parsed, so a value containing :, @, or # fills the string verbatim and never changes the document structure.
Database fragments
databases_include names a directory of files that each add databases, so a provisioner can own one file per database and leave the main file alone:
# databases.d/notes.yaml
lancedb:
databases:
notes: ${HAIKU_RAG_CONFIG_DIR}/notes.lancedb
ingester:
databases:
notes:
sources:
- type: fs
root: /uploads/notes
- A relative directory is relative to the main file's directory. A missing or empty directory adds nothing.
- Every
*.yamlfile in it loads in name order. Dotfiles and other extensions are skipped. - A fragment may set only
lancedb.databasesandingester.databases. Any other key fails loading with an error naming the file. - A database name defined twice, in two fragments or in a fragment and the main file, fails loading with an error naming both files.
- Environment variables and
${file:path}expand in a fragment as in the main file, and${HAIKU_RAG_CONFIG_DIR}is the main file's directory. - The ingester's reload reads the directory again, so adding or deleting a fragment adds or removes its database.
Only configuration loaded from a file reads fragments. A host that builds AppConfig itself places no fragment databases.
File-based secrets
Use ${file:path} in any string value to read a mounted secret:
ingester:
queue:
dburi: postgresql+asyncpg://haiku:${file:/run/secrets/db_password}@db:5432/haiku_rag
api:
auth_token: ${file:/run/secrets/ingester_token}
Paths may be absolute or relative to the YAML configuration file's directory. ${file:-x} is the environment variable file with default x, so write a relative path starting with - as ${file:./-x}. Files must contain UTF-8 text. Trailing \r and \n characters are removed. Spaces and internal line endings are preserved. Missing, unreadable, invalid UTF-8 and empty files fail configuration loading with an error naming the path.
File contents are substituted literally after YAML parsing, without expanding references inside them. $${file:path} produces the literal ${file:path}. Files are read on each configuration load and are not watched for changes. An ingester reload rereads them, but it refuses a changed value outside lancedb.databases and ingester.databases, so a rotated queue password or API token needs a restart.
Interpolation does not URL-encode values. A password embedded in a connection URL must already be percent-encoded where required. Alternatively, store the complete connection URL in a file and use dburi: ${file:/run/secrets/dburi}.
Environment
environment defaults to production. In the CLI, any value other than development silences Python warnings and Logfire console output.
Minimal configuration
A minimal configuration file with defaults. These qa.model values are the defaults only when the qa section is omitted. Once you write a qa.model block, each field you leave out takes the ModelConfig default: vision: false, and no thinking, temperature or max_tokens. The same holds for processing.title_model and processing.conversion_options.picture_description.model.
# haiku.rag.yaml
environment: production
embeddings:
model:
provider: ollama
name: qwen3-embedding:4b
vector_dim: 2560
qa:
model:
provider: ollama
name: qwen3.8
thinking: true
Programmatic configuration
When using haiku.rag as a Python library, you can pass configuration directly to the HaikuRAG client:
from haiku.rag.config import AppConfig
from haiku.rag.config.models import EmbeddingModelConfig, ModelConfig, QAConfig, EmbeddingsConfig
from haiku.rag.client import HaikuRAG
# Create custom configuration
custom_config = AppConfig(
qa=QAConfig(
model=ModelConfig(
provider="openai",
name="gpt-4o",
temperature=0.3
)
),
embeddings=EmbeddingsConfig(
model=EmbeddingModelConfig(
provider="ollama",
name="qwen3-embedding:4b",
vector_dim=2560
)
),
processing={"chunk_size": 512}
)
# Pass configuration to the client
async with HaikuRAG(config=custom_config) as client:
...
Without config, the client uses the configuration loaded from the YAML file, or the defaults. Clients in one process can each take a different configuration.
Configuration topics
- Providers: models, embedders and rerankers
- Search and question answering: search, context expansion, QA budgets, sandbox limits
- Document processing: conversion and chunking
- Storage: database placement, remote storage, vacuum, vector indexing
- Multiple databases: searching several databases together
- Prompts: domain context and the picture-description prompt
- Ingester: continuous ingestion sources, workers and queue