Quick start
Install
Or with pip:
Development setup (includes docs, tests, linters):
NER / SpaCy (optional)
SpaCy pipelines are optional. Without them, regex, entropy, injection, and topic detectors still run; NER stays inactive.
| Extra | Installs |
|---|---|
ner-fr |
fr_core_news_md via PyPI (matches shipped profiles) |
ner-de, ner-en, ner-es, ner-it, ner-pt |
spacy only; then uv run python -m spacy download de_core_news_md (etc.) |
ner |
spacy only; use uv run python -m spacy download <model> for any pipeline |
ner-all |
fr_core_news_md wheel only |
uv add "colandix[ner-fr]"
# German example:
uv add "colandix[ner-de]" && uv run python -m spacy download de_core_news_md
Shipped profiles default to fr_core_news_md. For another language set extra.model and entities in your YAML (English uses PERSON, not PER).
Minimal example
from colandix import GuardPipeline
guard = GuardPipeline(profile="generique")
res_in = guard.scan_input("my prompt")
response = call_llm(res_in.sanitized_text)
res_out = guard.scan_output(response)
Replace call_llm with your client (OpenAI, Ollama, Mistral, etc.).
Tutorial notebook: notebooks/demo_colandix.ipynb.
Key concepts
- One guard, one profile.
GuardPipeline(profile="strict")loads a built-in YAML set of detectors. - Benign text returns
pass. Ordinary messages getAction.PASS. - Secrets return
block. Ansk-…key pattern yieldsAction.BLOCKwith a reason string (truncated in logs). - Branch on
action. Useif res.action == Action.BLOCK:(orres.blocked) before calling the LLM. sanitized_textis always computed. Even when not blocked, sensitive spans get typed tags like[EMAIL_REDACTED].- Profiles change behavior.
santeadds medical topic guardrails and NER (if SpaCy is installed).