Skip to main content

Responsible AI guardrails for LLM applications. Local-first, drop-in SDK.

Project description

lyzr-rai

Drop-in Responsible AI guardrails for LLM applications. Local-first Python SDK — no server, no API key, no telemetry.

from lyzr_rai import RAIClient, Check

client = RAIClient(checks=[
    Check.secrets(),
    Check.pii(),
    Check.keywords(rules=[{"keyword": "confidential", "action": "block"}]),
])

result = client.check_input("Email john@acme.com about the confidential project")
print(result.blocked)         # True — keyword 'confidential' triggered block
print(result.processed_text)  # "Email [RAI_EMAIL_ADDRESS_1] about the confidential project"

Install

# Core checks: secrets, pii, keywords, openapi, sql
pip install lyzr-rai

# Add ML-backed checks: topics, toxicity, prompt injection, nsfw, gibberish
pip install lyzr-rai[ml]
Check Install Notes
secrets core Regex (AWS, GitHub, OpenAI keys, etc.)
pii core Presidio — EMAIL, PHONE, SSN, CREDIT_CARD, etc.
keywords core Literal case-insensitive matching
valid_openapi core OpenAPI 3.x JSON/YAML validation
valid_sql core sqlglot syntax validation
banned_topics [ml] Zero-shot classifier (deberta-v3-large)
allowed_topics [ml] Same model; blocks if no allowed topic matches
toxicity [ml] XLM-Roberta (EthicalEye)
prompt_injection [ml] deberta-v3-base (ProtectAI). Input-direction only.
nsfw [ml] NSFW text classifier
gibberish [ml] Gibberish text detector

Without [ml], attempting to construct an ML check raises a clear ImportError with the install hint. Nothing is silently downloaded.

With [ml], model weights lazy-download from HuggingFace Hub on first use and cache to ~/.cache/huggingface/hub/. Override the cache directory via HF_HOME.

Concepts

Actions

Each detection check supports two actions: block (reject the input) and redact (replace the offending span with a token).

Tokens

Redacted spans are replaced with [RAI_<TYPE>_<N>]:

"Email me at john@acme.com" -> "Email me at [RAI_EMAIL_ADDRESS_1]"

The same value always reuses its token within a client's lifetime (deduplication):

r1 = client.check_input("john@acme.com")        # -> [RAI_EMAIL_ADDRESS_1]
r2 = client.check_input("john@acme.com again")  # -> [RAI_EMAIL_ADDRESS_1] again

Tokens are matched case-insensitively at unredact time — LLMs that "fix" casing don't break the round trip.

Pipeline

Checks run sequentially in registration order. Each check sees the text as mutated by upstream redaction. Results accumulate; the pipeline does not stop on the first block unless RAIClient(stop_on_block=True).

PII Redaction & De-redaction

The full round trip with an LLM:

from lyzr_rai import RAIClient, Check

client = RAIClient(checks=[Check.pii(), Check.secrets()])

# 1. Redact PII before sending to the LLM
user_msg = "Hi, I'm Alex Rivera. Email alex@example.com — my AWS key is AKIAIOSFODNN7EXAMPLE."
input_result = client.check_input(user_msg)
print(input_result.processed_text)
# "Hi, I'm [RAI_PERSON_1]. Email [RAI_EMAIL_ADDRESS_1] — my AWS key is [RAI_SECRET_AWS_KEY_1]."

# 2. Send the redacted text to the LLM
llm_response = call_my_llm(input_result.processed_text)
# "Sure, [RAI_PERSON_1]. I'll email [RAI_EMAIL_ADDRESS_1] with details."

# 3. Run output checks. Tokens are auto-restored at the end.
output_result = client.check_output(llm_response)
print(output_result.processed_text)
# "Sure, Alex Rivera. I'll email alex@example.com with details."

One client per conversation

Each RAIClient holds its own redaction state. Do not share clients across conversations — token [RAI_EMAIL_ADDRESS_1] from Alice's session would map back to Alice's email, even if Bob's session is the one calling check_output.

# Pattern A: new client per session
client = RAIClient(checks=[...])

# Pattern B: reset between sessions
shared_client.reset()

Manual unredact

If you bypass check_output (e.g. you don't need to scan the LLM output), call unredact() directly:

final = client.unredact(llm_response)

Unknown [RAI_*] tokens (LLM hallucinations) are left as-is.

Examples

Configure individual checks

client = RAIClient(checks=[
    Check.secrets(action="block"),
    Check.pii(
        entities=["EMAIL_ADDRESS", "PHONE_NUMBER", "PERSON"],
        actions={"PERSON": "block"},   # block on PERSON, redact others
        default_action="redact",
        custom=[
            {"label": "ACCT-12345", "action": "redact", "replacement": "[ACCOUNT]"},
        ],
    ),
    Check.keywords(rules=[
        {"keyword": "confidential", "action": "block"},
        {"keyword": "internal", "action": "redact", "replacement": "[INTERNAL]"},
    ]),
    Check.valid_sql(),
])

ML checks

client = RAIClient(checks=[
    Check.prompt_injection(threshold=0.85),
    Check.toxicity(threshold=0.9),
    Check.banned_topics(topics=["weapons", "self-harm"]),
    Check.nsfw(validation_method="sentence"),
])

Inspecting results

result = client.check_input("...")

result.blocked          # bool
result.block_reason     # str | None
result.processed_text   # str
result.warnings         # list[str]
result.detections       # dict[check_name, payload]
result.redaction_map    # dict[original_value, token]

for check in result.checks:
    print(check.name, check.duration_ms, check.detected, check.blocked)

License

Apache-2.0

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

lyzr_rai-0.1.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

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

lyzr_rai-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file lyzr_rai-0.1.0.tar.gz.

File metadata

  • Download URL: lyzr_rai-0.1.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lyzr_rai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3f1ab91ec1ca6148da46c52668f74bca31798f298383cd62af906e570ab7d523
MD5 c6eddb0793da1cb1f8210952cd56926c
BLAKE2b-256 7db8cfccfdfdf87b0c0cff124056dab306bbba7c42d0614ecc03a88bfdfeed62

See more details on using hashes here.

Provenance

The following attestation bundles were made for lyzr_rai-0.1.0.tar.gz:

Publisher: publish.yml on NeuralgoLyzr/studio-srs-apis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lyzr_rai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lyzr_rai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lyzr_rai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 32badac7f38d7bb43512a52843454bd125b2c17b389d52403d3b2aef2850fdb2
MD5 4c2ac5c1a3dc311135a94d014a94bfe7
BLAKE2b-256 375f758847424fbab2d7a96f3997795266c07a3b707886fbe851e490302fe703

See more details on using hashes here.

Provenance

The following attestation bundles were made for lyzr_rai-0.1.0-py3-none-any.whl:

Publisher: publish.yml on NeuralgoLyzr/studio-srs-apis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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