Skip to main content

A Semantic Type System for AI outputs — validate intent, not just shape.

Project description

semantix-ai

Validate what your LLM outputs mean, not just their shape.

PyPI version Python versions License Downloads


pip install semantix-ai
from semantix.testing import assert_semantic

def test_chatbot_is_polite():
    response = my_chatbot("handle angry customer")
    assert_semantic(response, "polite and professional")

Runs locally. ~15ms. No API key. Works in pytest, unittest, or any test runner.

On failure:

AssertionError: Semantic check failed (score=0.12)
  Intent:  polite and professional
  Output:  "You're an idiot for asking that."
  Reason:  Text contains aggressive language

What It Does

semantix validates that LLM outputs mean the right thing — using a local NLI model, not string matching or another LLM call.

from semantix import Intent, validate_intent

class ProfessionalDecline(Intent):
    """The text must politely decline an invitation without being rude."""

@validate_intent
def decline_invite(event: str) -> ProfessionalDecline:
    return call_my_llm(event)

result = decline_invite("the company retreat")
# Returns a validated ProfessionalDecline — or raises SemanticIntentError

Key properties:

  • Local inference — NLI model runs on CPU, no data leaves your machine
  • ~15ms per check — negligible overhead on any LLM call
  • Zero API cost — no tokens burned for validation
  • 212 tests — well-tested, MIT licensed

Compliance with Negation

Block what your model must NOT say — PII, medical advice, competitor mentions:

from semantix import Intent, Not

class MedicalAdvice(Intent):
    """The text provides medical diagnoses or treatment recommendations."""

Safe = ~MedicalAdvice  # or Not(MedicalAdvice)

@validate_intent
def chatbot(msg: str) -> Safe:
    return call_my_llm(msg)

Compose with & (all must pass) and | (any must pass):

SafeAndPolite = Polite & ~MedicalAdvice & ~LegalAdvice

Self-Healing Retries

On failure, semantix injects structured feedback so the LLM knows what went wrong:

from typing import Optional

@validate_intent(retries=2)
def decline(event: str, semantix_feedback: Optional[str] = None) -> ProfessionalDecline:
    prompt = f"Decline this invite: {event}"
    if semantix_feedback:
        prompt += f"\n\n{semantix_feedback}"
    return call_llm(prompt)

First call: semantix_feedback is None. On retry: it receives a Markdown report with the score, reason, and rejected output. Reliability improves from 21% to 70% across 3 intent categories.


Framework Integrations

Drop into your existing stack — retries are handled natively by each framework.

Guardrails AI

from guardrails import Guard
from semantix.integrations.guardrails import SemanticIntent

guard = Guard().use(SemanticIntent("must be polite and professional"))
result = guard.validate("Thank you for your patience.")

Instructor

from semantix.integrations.instructor import SemanticStr
from pydantic import BaseModel

class Response(BaseModel):
    reply: SemanticStr["must be polite and professional", 0.85]

Pydantic AI

from pydantic_ai import Agent
from semantix.integrations.pydantic_ai import semantix_validator

agent = Agent("openai:gpt-4o", output_type=str)
agent.output_validator(semantix_validator(Polite))

LangChain

from semantix.integrations.langchain import SemanticValidator

validator = SemanticValidator(Polite)
chain = prompt | llm | StrOutputParser() | validator

DSPy

import dspy
from semantix.integrations.dspy import semantic_reward

qa = dspy.ChainOfThought("question -> answer")
refined = dspy.Refine(module=qa, N=3, reward_fn=semantic_reward(Polite))

Install extras: pip install "semantix-ai[instructor]", "semantix-ai[pydantic-ai]", "semantix-ai[langchain]", "semantix-ai[guardrails]", "semantix-ai[dspy]"


Self-Training Flywheel

Every retry produces labeled training data — rejected output, reason, corrected output:

from semantix.training import TrainingCollector
from semantix.training.exporters import export_openai

collector = TrainingCollector("training_data.jsonl")

@validate_intent(retries=2, collector=collector)
def decline(event: str) -> ProfessionalDecline:
    return call_my_llm(event)

# Export to OpenAI fine-tuning format
export_openai("training_data.jsonl", "finetune.jsonl")

Your guardrail becomes your training pipeline:

Validate → Fail → Correct → Capture → Fine-tune → Validate (fewer failures)

Pluggable Judges

Choose the right speed/accuracy tradeoff:

from semantix import NLIJudge, EmbeddingJudge, LLMJudge, CachingJudge

# Default — local NLI entailment (no API key, ~15ms)
@validate_intent(judge=NLIJudge())

# Fast — local cosine similarity (~5ms)
@validate_intent(judge=EmbeddingJudge())

# Accurate — GPT-4o-mini with 0-1 scoring + reason
@validate_intent(judge=LLMJudge(model="gpt-4o-mini"))

# Cached — wraps any judge with LRU cache
@validate_intent(judge=CachingJudge(NLIJudge(), maxsize=256))

Quantized mode for minimal footprint (~25MB vs ~500MB for PyTorch):

pip install "semantix-ai[turbo]"
# Automatically uses QuantizedNLIJudge (INT8 ONNX, no PyTorch)

Advanced Features

Forensic analysis — token-level attribution on failure:

from semantix import ForensicJudge, QuantizedNLIJudge
judge = ForensicJudge(QuantizedNLIJudge())
# Verdict.reason: "Suspect Tokens: [indemnify, forfeit, waive]"

Streaming — validate once the full stream is assembled:

from semantix import StreamCollector
for chunk in StreamCollector(Polite, judge=my_judge).wrap(llm_stream()):
    print(chunk, end="")

Audit trail — hash-chained JSON-LD certificates:

from semantix.audit.engine import AuditEngine
engine = AuditEngine()
engine.verify_chain()  # True if no tampering

MCP server — any AI agent can validate intents as a tool:

pip install "semantix-ai[mcp,nli]"
mcp run semantix/mcp/server.py

Async — works transparently with async def.


Installation

pip install semantix-ai                    # Core (default NLI judge)
pip install "semantix-ai[turbo]"           # Quantized ONNX (smallest footprint)
pip install "semantix-ai[openai]"          # LLM judge (GPT-4o-mini)
pip install "semantix-ai[instructor]"      # Instructor integration
pip install "semantix-ai[pydantic-ai]"     # Pydantic AI integration
pip install "semantix-ai[langchain]"       # LangChain integration
pip install "semantix-ai[guardrails]"      # Guardrails AI integration
pip install "semantix-ai[dspy]"            # DSPy integration
pip install "semantix-ai[all]"             # Everything

The package name on PyPI is semantix-ai. The import is from semantix import ....


Contributing

See CONTRIBUTING.md for dev setup, testing, and submission guidelines.

License

MIT — see LICENSE for details.


Built by Akhona Eland in South Africa

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

semantix_ai-0.1.11.tar.gz (107.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

semantix_ai-0.1.11-py3-none-any.whl (68.3 kB view details)

Uploaded Python 3

File details

Details for the file semantix_ai-0.1.11.tar.gz.

File metadata

  • Download URL: semantix_ai-0.1.11.tar.gz
  • Upload date:
  • Size: 107.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for semantix_ai-0.1.11.tar.gz
Algorithm Hash digest
SHA256 ee19295bb580676932b3277ccc37e78e23ff0e19d7c165c0163a573fc83fa471
MD5 af6776e81e60bca00765cf5ba463972e
BLAKE2b-256 ef22e03026fedb80de8a825a81b1382df26c46792174362188be5c1fe588d86b

See more details on using hashes here.

File details

Details for the file semantix_ai-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: semantix_ai-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 68.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for semantix_ai-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 58feb3c1c21157308d12f99164f110736ea87b64cbd67549deac1a74c5cfd95d
MD5 ffe2ce36d401c9052439f6ae88572fd3
BLAKE2b-256 4d9fa143de389d8444b7b793a2d8545c46c1a6b1908c131a2dfa8d35a15028f9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page