Skip to main content

Introduction

airules is a small, typed, declarative rules engine for Python.

You describe the shape of your input as a Fact, write rules as predicates over that fact, and let the KnowledgeEngine pick the first matching rule and run its action. Predicates are plain Python objects - they compose with & | ~, serialize to dictionaries, and reload cleanly - making rule sets easy to store, audit, and visualize.

Why a rules engine?

Most "if/elif" decision code in production is really a rule set in disguise: a list of conditions, each with an associated action, evaluated in priority order. Once that list grows past a handful of branches it gets hard to read, test, and reason about.

There is a second, practical reason: AI inference is expensive, and programmatic evaluation is not. Every LLM call adds latency and API cost. A rules engine running in-process costs microseconds and zero budget per decision.

The key insight is that most decisions are already known. If you can write down the right answer for a given input pattern, that knowledge belongs in a rule - deterministic, auditable, testable, and free to run. AI earns its cost on the genuinely unknown tail: inputs that fall outside every rule. The rules engine acts as a cheap first-pass filter; only unmatched facts escalate to a model.

Install

pip install ai-rules-engine

Python 3.11+ is required. The only runtime dependency is typing_extensions.

Minimal example

from airules import Fact, KnowledgeEngine, NumberField, Rule, Default

class Order(Fact):
total: NumberField[int]

class Discount(KnowledgeEngine[Order, str]):
@Rule(Order.total.ge(100))
def big(self, order: Order):
return "10% off"

@Default
def small(self, order: Order):
return "no discount"

Discount().run(Order(total=120)) # -> "10% off"
Discount().run(Order(total=20)) # -> "no discount"

The engine is Generic[FactType, ReturnType], so your editor and type checker know that run returns str | None here.