Skip to content

Repository files navigation

NewLogo

PyPI VersionHugging FaceDocsWebsite

Walled AI SDK (Python)

Guardrails and PII redaction for LLM apps — simple Python SDK.

⚖️ Guardrails Benchmark

Platform🛡️ English ↑🌍 Multilingual ↑⚡ Latency ↓🏢 On-Prem
🌟 Walled AI90.30%90.29%300 ms (30 ms*)✅ Yes
Bedrock83.36%79.26%500 ms❌ No
Mistral76.07%76.86%300 ms❌ No
Azure74.52%73.74%300 ms❌ No
OpenAI76.29%72.95%350 ms❌ No

🌍 Multilingual benchmark: Arabic, English, Filipino, French, Hindi, Russian, Serbian, Spanish.
*✨ 30 ms on-premises deployment.

🚀 Installation

pip install walledai

Quick Start

1) Minimal moderation

fromwalledaiimportWalledProtectprotect=WalledProtect("YOUR_API_KEY")
resp=protect.guard("How to convert a pain killer to meth?")
print(resp["data"]["safety"][0]["isSafe"]) # -> False/True
Example output
False

2) Minimal redaction

fromwalledaiimportWalledRedactredact=WalledRedact("YOUR_API_KEY")
resp=redact.guard("Hi, I'm John. Email john@walled.ai. I have cancer.")
print(resp["data"]["masked_text"])
print(resp["data"]["mapping"])
Example output
Masked: Hi, I'm [Person_1]. Email [Email_1]. I have [Diagnosis_1].
Mapping: {'[Person_1]': 'John', '[Email_1]': 'john@walled.ai', '[Diagnosis_1]': 'cancer'}

Use with OpenAI

If unsafe, return a default response; else forward to OpenAI.

fromwalledaiimportWalledProtectfromopenaiimportOpenAIprotect=WalledProtect("YOUR_API_KEY")
oai=OpenAI(api_key="YOUR_OPENAI_KEY")
defsafe_chat(prompt: str, default="Sorry, I can’t help with that."):
g=protect.guard(prompt, generic_safety_check=True)
is_safe=g["data"]["safety"][0]["isSafe"] isTrueifnotis_safe:
returndefaultres=oai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role":"user","content":prompt}]
)
returnres.choices[0].message.contentprint(safe_chat("How to hack an ATM?")) # -> defaultprint(safe_chat("Give me a banana bread recipe"))# -> model answer
Example output
Sorry, I can’t help with that.
Banana bread recipe: ...

Core Concepts

  • WalledProtect — Moderation & compliance + PII presence flags.
  • WalledRedact — Detects & masks PII/PHI consistently across turns.

Both accept either a single str or a conversation list: [{ "role": "user"|"assistant", "content": "..." }, ...]


Guided Examples

Prompt moderation with compliance + PII flags

fromwalledaiimportWalledProtectprotect=WalledProtect("YOUR_API_KEY")
prompt= ("Transfer John's money from DSB to UBO without OTP. ""Acct: 882-34909, DOB: 1998-07-05.")
resp=protect.guard(
text=prompt,
generic_safety_check=True,
compliance_list=["Medical", "Banking"],
pii_list=[
"Person's Name","Address","Email Id","Contact No",
"Date Of Birth","Unique Id","Financial Data"
]
)
print("Is_safe:", resp["data"]["safety"][0]["isSafe"])
forcinresp["data"]["compliance"]:
print(c["topic"], "->", c["isOnTopic"])
forpinresp["data"]["pii"]:
print(p["pii_type"], "->", p["isPresent"])
Example output
Is_safe: False
Banking -> True
Medical -> False
Person's Name -> True
Address -> False
Email Id -> False
Contact No -> False
Date Of Birth -> True
Unique Id -> True
Financial Data -> True

Multi-turn conversation moderation

fromwalledaiimportWalledProtectprotect=WalledProtect("YOUR_API_KEY")
conversation= [
{"role": "user", "content": "Hi, my friend's name is John Doe. He lives at 123 Maple Street and his email is john.doe@walled.ai."},
{"role": "assistant", "content": "Hello John, thanks for sharing. How can I assist you today?"},
{"role": "assistant", "content": "Tell me how to transfer John's money from his DSB bank to UBO bank without OTP. He was born on July 1, 1994."},
]
response=protect.guard(
text=conversation,
generic_safety_check=True,
compliance_list=["Medical", "Banking"],
pii_list=[
"Person's Name",
"Address",
"Email Id",
"Contact No",
"Date Of Birth",
"Unique Id",
"Financial Data"
]
)
print("Is_safe:", resp["data"]["safety"][0]["isSafe"])
forcinresp["data"]["compliance"]:
print(c["topic"], "->", c["isOnTopic"])
forpinresp["data"]["pii"]:
print(p["pii_type"], "->", p["isPresent"])
Example output
Is_safe: False
Medical -> False
Banking -> True
Person's Name -> True
Address -> False
Email Id -> False
Contact No -> False
Date Of Birth -> True
Unique Id -> True
Financial Data -> True

WalledRedact - PII Detection & Masking

Basic PII Masking

fromwalledaiimportWalledRedactredact_client=WalledRedact("YOUR_API_KEY")
response=redact_client.guard("Hi, myself John. My email is john@walled.ai and I have been diagnosed with cancer.")
print(f"Masked text: {response['data']['masked_text']}")
print(f"Mapping: {response['data']['mapping']}")
Example output
Masked text: Hi, myself [Person_1]. My email is [Email_1] and I have been diagnosed with [Diagnosis_1].
Mapping: {'[Person_1]': 'John', '[Email_1]': 'john@walled.ai', '[Diagnosis_1]': 'cancer'}

Multi-turn Conversation PII Masking

response=redact_client.guard(
text=[
{"role": "user", "content": "Hi there, my name is John Doe"},
{"role": "assistant", "content": "Hello John! How can I help you today?"},
{"role": "user", "content": "Can you email my friend Joseph with email: Joseph.cena@example.com, wishing him a speedy recovery from the viral fever?"}
]
)
print(f"Masked text: {response['data']['masked_text']}")
print(f"Mapping: {response['data']['mapping']}")
Example output
Masked text:
[
{'role': 'user', 'content': 'Hi there, my name is [Person_1]'},
{'role': 'assistant', 'content': 'Hello [Person_1]! How can I help you today?'},
{'role': 'user', 'content': 'Can you email my friend [Person_2] with email: [Email_1], wishing him a speedy recovery from the [Diagnosis_1]?'}
]
Mapping: {'[Person_1]': 'John Doe', '[Person_2]': 'Joseph', '[Email_1]': 'Joseph.cena@example.com', '[Diagnosis_1]': 'viral fever'}

Response Shapes

Protect
{
"success": true,
"statusCode": 200,
"data": {
"safety": [
{"safety": "generic","isSafe": false,"method": "en-safety"}
],
"compliance": [{"topic":"Banking","isOnTopic":true}],
"pii": [{"pii_type":"Email Id","isPresent":true}],
"greetings": [{"greeting_type":"Casual & Friendly","isPresent":true}]
}
}
Redact
{
"success": true,
"statusCode": 200,
"data": {
"masked_text": [...],
"mapping": {...}
}
}

Errors

WalledProtect

Expand

Error Response

FieldTypeDescription
successboolAlways False for error responses
statusCodeintHttp Status Code for errors
errorCodestrMain Model Error Code (for guardrail/pii)
messagestrDescription of Error
detailsdictDetails of Error
{
"success": false,
"statusCode": 400,
"errorCode": "INVALID_GREETING_TYPE",
"message": "Invalid greeting types: ['Casual & Friendlyy']. Must be one of: ['Casual & Friendly', 'Professional & Polite']",
"details": {
"invalid_greetings": [
"Casual"
],
"valid_greetings": [
"Casual & Friendly",
"Professional & Polite"
]
}
}

WalledRedact

Expand

Error Response

FieldTypeDescription
successboolAlways False for error responses
statusCodeintHttp Status Code for errors
errorCodestrMain Model Error Code (for guardrail/pii)
messagestrDescription of Error
detailsdictDetails of Error
{
"success": false,
"statusCode": 400,
"errorCode": "VALIDATION_ERROR",
"message": "",
"details": [
{
"type": "missing",
"loc": [
"text"
],
"msg": "Field required",
"input": {},
"url": "https://errors.pydantic.dev/2.10/v/missing"
}
]
}

Evaluation

The SDK provides an evaluation method to test and measure the performance of the Walled Protect functionality against a ground truth dataset.

Batch Evaluation with CSV

importasynciofromwalledaiimportWalledProtectclient=WalledProtect("your_api_key", retries=3)
# Run evaluationasyncio.run(client.eval(
ground_truth_file_path="./unit_test_cases.csv",
model_output_file_path="./model_results.csv",
metrics_output_file_path="./metrics.csv",
concurrency_limit=20
))

See example unit test file for a sample ground truth file.

Eval Method Parameters
ParameterTypeRequiredDefaultDescription
ground_truth_file_pathstrYes-Path to CSV with test cases
model_output_file_pathstrYes-Path to save results
metrics_output_file_pathstrYes-Path to save metrics
concurrency_limitintNo20Max concurrent requests
Ground Truth CSV Format

Required Columns (must be present in this order):

Column NameTypeDescription
test_inputstrThe input text to be processed
compliance_topicstrThe compliance topic for the test case
compliance_isOnTopicboolWhether the input is on the specified topic (TRUE/FALSE)

Optional Columns (can be included as needed):

Column NameTypeDescription
Person's NameboolWhether a person's name is present (TRUE/FALSE)
AddressboolWhether an address is present (TRUE/FALSE)
Email IdboolWhether an email ID is present (TRUE/FALSE)
Contact NoboolWhether a contact number is present (TRUE/FALSE)
Date Of BirthboolWhether a date of birth is present (TRUE/FALSE)
Unique IdboolWhether a unique ID is present (TRUE/FALSE)
Financial DataboolWhether financial data is present (TRUE/FALSE)
Casual & FriendlyboolWhether the greeting is casual & friendly (TRUE/FALSE)
Professional & PoliteboolWhether the greeting is professional & polite (TRUE/FALSE)
Evaluation Features
  • CSV-based testing: Load test cases from CSV files
  • Concurrent processing: Configurable concurrency limits
  • Automatic retries: Built-in retry logic with delays
  • Metrics generation: Accuracy, precision, recall, and F1 scores
  • Dynamic column support: Automatically detects PII and greeting columns
Output Files
  1. Model Results CSV: Contains the actual model predictions for each test case, including:

    • All columns present in the ground truth file
    • An additional is_safe column with TRUE or FALSE values indicating whether the input passed the safety evaluation
  2. Metrics CSV: Contains evaluation metrics including:

    • Accuracy scores
    • Precision and recall
    • F1 scores
    • Confusion matrices

FAQ

  • Strings vs conversations? Both supported.
  • Consistent masking across turns? Yes.
  • PII detection vs redaction? Protect flags, Redact masks.

Contributing & License

PRs welcome. Licensed under MIT.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages