Klix
Decoupled decision heads on a shared semantic backbone.
A text passes through the embedding model exactly once (dense + sparse), after which any number
of heads (Choice, Score, Flag) operate on the precomputed vectors — each in its own
mathematical space. No model training, no slot limits, fully offline and CPU-only.
Architecture
Text ──► HybridBackbone (FastEmbed dense + TF-IDF sparse, once, ~10 ms)
│
├──► Choice (routing/classification: max-similarity + keyword boost)
├──► Score (continuous axis: low/high anchors + sigmoid)
├──► Flag (boolean: 2/3-class softmax with temperature)
└──► custom heads (subclass BaseHead)
- Shared backbone: Each text is embedded and TF-IDF-transformed exactly once. Whether you register 3 heads or 50, the extraction cost stays the same.
- Decoupled heads: Adding options to one
Choicenever affectsScoreorFlagresults. Every head encapsulates its own logic. - Declarative: Define schemas with example sentences, call
compile(), done.
Installation
uv add klix-engine
# or
pip install klix-engine
On first use, FastEmbed downloads the paraphrase-multilingual-MiniLM-L12-v2 model
(~120 MB, one-time, then cached locally). Everything runs offline afterwards.
Quickstart
from klix import DecisionEngine, Choice, Score, Flag
engine = DecisionEngine()
engine.add_head(
Choice(
name="target",
options={
"it_ops": ["VPN down", "server unreachable", "laptop won't boot"],
"ot_plant": ["robot cell stopped", "PLC fault", "plc-34 error", "cycle time deviation"],
"finance": ["cost center over budget", "approve invoice"],
"facility": ["oil spill in hall 2", "heating broken"],
},
)
)
engine.add_head(
Score(
name="urgency",
low_anchors=["routine maintenance", "casual question"],
high_anchors=["emergency right now", "production line down", "acute danger"],
min_val=0.0,
max_val=3.0,
)
)
engine.add_head(
Flag(
name="is_security",
true_anchors=["hacker attack", "ransomware infection", "data exfiltration"],
false_anchors=["hardware broken", "ordinary IT problem", "network outage"],
neutral_anchors=["routine request", "general question", "other topic"],
threshold=0.5,
)
)
engine.compile()
res = engine.decide("plc-34 reports a fault, conveyor belt stopped immediately!")
print(res) # <DecisionResult (11 ms): target=ot_plant, urgency=2.9, is_security=False>
print(res.target) # 'ot_plant'
print(res.urgency) # 2.87
print(res.is_security) # False
print(res.details("is_security")) # {'value': False, 'probability': 0.03}
The heads are language-agnostic — the example uses English anchors, but German, French, or any other language works the same way (the backbone model is multilingual).
Custom Heads
Subclass BaseHead and implement evaluate(encoded):
import re
from klix import BaseHead
class RegExExtractionHead(BaseHead):
def __init__(self, name: str, pattern: str):
super().__init__(name)
self.re = re.compile(pattern)
def get_reference_texts(self) -> list[str]:
return [] # no reference texts needed
def fit(self, backbone) -> None:
pass
def evaluate(self, encoded) -> dict:
match = self.re.search(encoded.text)
return {"value": match.group(0) if match else None}
Development
uv sync # install dependencies
uv run pytest # run tests
uv run python examples/demo.py
Release chain (automated): bump the version in pyproject.toml and __init__.py,
commit, tag, push — GitHub Actions builds and publishes to PyPI automatically
(workflow publish.yml, secret PYPI_TOKEN):
git tag vX.Y.Z
git push origin main vX.Y.Z
License
MIT
Release files for klix-engine 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| klix_engine-0.1.3.tar.gz | 127.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| klix_engine-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 137.6 kB
Release files / klix_engine-0.1.3.tar.gz
| Download URL | klix_engine-0.1.3.tar.gz |
|---|---|
| Size | 127.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
21ad4ae5231a1b9a96ea45c84d6cd52adae5d06b73c7f6f40d5239b83c81f9fe
|
|
BLAKE2b-256 checksum How to use checksums |
3167a83c47b0604e83c00a0e46f568918223d6708c34a5d368fcb8b5eb055afc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / klix_engine-0.1.3-py3-none-any.whl
| Download URL | klix_engine-0.1.3-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ffe8b70a74227497cf1781c0048d118180beec4156ee868f0fac0ac755d2350
|
|
BLAKE2b-256 checksum How to use checksums |
790863edaf593cbffc26bda14baa25c55a1fcd0f255952537a60b7c008a9f321
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|