Skip to content

chakkritte/axiom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Axiom

Axiom is a deterministic Decision Contract Runtime for Python 3.11+.

It sits between an application and a Language Model, guaranteeing that AI decisions are structured, validated, inspectable, and enforceable before execution. It converts raw, untrusted LLM text generation into completely structured and verifiable system decisions.

Axiom treats AI as non-deterministic hardware. The model never has execution authority. The Axiom runtime always owns authority.

Note: Axiom is infrastructure only. It is NOT an AI agent framework and NOT a chatbot toolkit. It does not implement memory, RAG, tool calling, or chat UIs.


Core Concept

Instead of the traditional flow where an application blindly accepts raw string generation, Axiom forces the model into a rigid structure:

App → Axiom Runtime → LLM proposal → Decision Contract → Validation → Policy Enforcement → Execution Approval

All outputs must match a strict JSON schema. If the output deviates—whether via syntax errors or missing fields—Execution is instantly rejected. No natural language is permitted outside the JSON boundary.

The Decision Object Schema

All approved decisions conform strictly to this immutable schema:

{
  "goal": "string",
  "state": "string",
  "decision": "string",
  "constraints": ["string"],
  "confidence": 0.95,
  "explanation": "string (max 20 words)"
}

Installation

Currently, Axiom has zero external dependencies (other than a local LLM). Simply drop the axiom package into your Python project directory.

Requires Python 3.11+.

Axiom relies on an LLM inference server. Currently, an Ollama adapter is natively supported. Keep your Ollama daemon running in the background.


Usage Example

from axiom import Axiom

# Start the runtime
ax = Axiom(model="ollama:qwen3-vl:8b")

# Evaluate a prompt
result = ax.evaluate(
    prompt="Market volatility is high. Should we open a new position?",
    context={"current_portfolio_risk": "moderate"}
)

# Execution authority natively branches by status:
if result.status == "APPROVED":
    print("✅ Decision Approved by Runtime")
    
    # Access strictly typed variables (type: axiom.models.decision.Decision)
    decision = result.decision
    print(f"Goal: {decision.goal}")
    print(f"Confidence: {decision.confidence}")
    print(f"Action: {decision.decision}")
    
elif result.status == "REJECTED":
    print("❌ Execution Denied")
    print(f"Reason: {result.reason}")
    print(f"Raw Output: {result.raw_output}")

Advanced: Policy Engine

Axiom's schema prevents syntax hallucinations and field bounds violations, but the Policy Engine evaluates the content's safety based on your business logic before giving an app approval to execute.

You can inject custom rules using Axiom.policy_engine.add_rule():

from axiom import Axiom
from axiom.policy import PolicyDecision

def deny_low_confidence_trades(data):
    """Custom policy to prevent trades if AI confidence is below 85%"""
    confidence = float(data.get("confidence", 0.0))
    action = data.get("decision", "").lower()
    
    if "buy" in action and confidence < 0.85:
        return PolicyDecision.DENY
    return PolicyDecision.ALLOW

ax = Axiom(model="ollama:llama3")
ax.policy_engine.add_rule(deny_low_confidence_trades)

# If the LLM returns "buy" with 0.82 confidence, result.status will equal "REJECTED".

Real-World Examples

Axiom ships with examples of non-financial workflows to demonstrate safety logic routing out of the box:

  • IoT Smart Home Safety (examples/smart_home_iot.py): Tests strict override logic for edge computational home hardware (e.g. denying an LLM the ability to "ignore" issues when a water leak sensor or fire alarm triggers, or mandating high-confidence thresholds for emergency action).
  • Automated Content Moderation (examples/content_moderation.py): Demonstrates multi-tier boundary rules. For instance, allowing an AI to automatically "hide a post" at >= 75% confidence, but strictly requiring >= 90% confidence to execute a "hard ban."

Audit Logging

An application should be transparent. Axiom writes all approved decisions into an append-only, thread-safe JSONL file (axiom_audit.jsonl). Every execution contains an exact timestamp and a SHA-256 hash mathematically binding the exact state and output of that AI decision.

{"goal": "preserve capital", "state": "high volatility", "decision": "hold", "constraints": ["limit risk"], "confidence": 0.9, "explanation": "Too risky.", "timestamp": 1771556978.76, "decision_hash": "416b36390...a927a"}

Dynamic Custom Contracts

By default, Axiom uses a strict built-in Decision object to shape AI paths natively. But developers can inject completely dynamic constraints by passing any Python @dataclass. Axiom automatically interprets the types, generates a valid JSON schema prompt for the LLM, and forces validation.

from dataclasses import dataclass
from typing import List
from axiom import Axiom

@dataclass
class GridMove:
    action: str
    target_x: float
    target_y: float
    safeties_engaged: List[str]

# Evaluates against GridMove schema instead of default schema!
result = ax.evaluate(
    prompt="Pursue the target to the North.",
    context={"current_x": 0, "current_y": 0, "target": [0, 5]},
    contract_type=GridMove 
)

Auto-Correction (Self-Healing Retries)

When using smaller local models, they may sometimes hallucinate string literals when an integer is expected, or forget a required field. Rather than immediately rejecting the payload, Axiom contains a localized feedback loop.

If you pass retries=3 into the evaluator, Axiom will intercept parsing errors and gracefully prompt the model with its own exception:

"Your previous output threw an error: Field 'temperature' has incorrect type. Expected float. Rewrite your response perfectly matching the JSON schema."

result = ax.evaluate(
    prompt="...", 
    retries=3 
)

High-Throughput Async Execution

Because LLM generation is inherently I/O bound, calling .evaluate() in a production web framework (like FastAPI or Sanic) would block the main event loop. Axiom natively supports non-blocking asynchronous execution via the python standard library (asyncio.to_thread).

You can rapidly fire hundreds of distinct system state decisions concurrently:

import asyncio
from axiom import Axiom

ax = Axiom(model="ollama:qwen3-vl:8b")

async def evaluate_multiple_states():
    task1 = ax.evaluate_async(prompt="State Check 1")
    task2 = ax.evaluate_async(prompt="State Check 2")
    
    results = await asyncio.gather(task1, task2)
    # results = [ApprovedDecision, RejectedDecision]

Project Structure

  • axiom/runtime.py - Single entrypoint and orchestrator
  • axiom/contract.py - Exact-bounds JSON parser
  • axiom/validator.py - Strict schema assertions
  • axiom/policy.py - Safe evaluation rules
  • axiom/audit/logger.py - Append-only logging
  • axiom/models/ - Immutable dataclasses for Decisions and Exceptions
  • axiom/adapters/ - Provider backends (Ollama built-in)

About

A deterministic decision contract runtime for language models

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages