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 Docs


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.

pytest plugin: pip install pytest-semantix for fixtures, markers, and CI reporting. See pytest-semantix.

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
  • 248 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]"

GitHub Actions

- uses: labrat-akhona/semantic-test-action@v1
  with:
    test-path: tests/

Posts a semantic test report as a PR comment. See semantic-test-action.


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.12.tar.gz (131.6 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.12-py3-none-any.whl (71.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: semantix_ai-0.1.12.tar.gz
  • Upload date:
  • Size: 131.6 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.12.tar.gz
Algorithm Hash digest
SHA256 4de072af08389dbd8c55a5d2039e9c3b1aacf32887c9e27b3b6c170734f80e9b
MD5 e55c66df2cb5639333c8853041f65243
BLAKE2b-256 78bdeb92e7084168d2fe5afdca2ac97ced7dc34e15736a48bc8727efef9e4256

See more details on using hashes here.

File details

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

File metadata

  • Download URL: semantix_ai-0.1.12-py3-none-any.whl
  • Upload date:
  • Size: 71.7 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.12-py3-none-any.whl
Algorithm Hash digest
SHA256 f3803b6ed6a2f481b1a8e29128c0b74d14bb8bca694004dd0074ed7d1e9f3900
MD5 3002593271d521a42969a3fbf005bbf8
BLAKE2b-256 240ef76701ae6f1a2b6702ad0e189c8e02c3c457c8325712c499d7c1f2d932bf

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