input validation
**Input Validation for LLM Applications**
**Why Validate Inputs?**
Prevent attacks, ensure quality, and maintain system stability.
**Validation Types**
| Type | Purpose | Example |
|------|---------|---------|
| Length limits | Prevent abuse | Max 10,000 chars |
| Content filtering | Block harmful | Regex patterns |
| Format validation | Ensure structure | JSON schema |
| Rate limiting | Prevent abuse | 60 req/min |
| Encoding | Prevent injection | Unicode normalization |
**Implementation**
**Length and Format**
```python
from pydantic import BaseModel, validator
class LLMRequest(BaseModel):
prompt: str
max_tokens: int = 1000
@validator("prompt")
def validate_prompt(cls, v):
if len(v) > 50000:
raise ValueError("Prompt too long")
if len(v) < 1:
raise ValueError("Prompt cannot be empty")
return v
@validator("max_tokens")
def validate_tokens(cls, v):
if v < 1 or v > 4096:
raise ValueError("Invalid max_tokens")
return v
```
**Content Filtering**
```python
class ContentFilter:
def __init__(self):
self.blocklist = load_blocklist()
self.patterns = [
r"\b(password|api.key|secret)\b",
r"\b(hack|exploit|pwn)\b",
]
def filter(self, text):
# Check blocklist
lower_text = text.lower()
for word in self.blocklist:
if word in lower_text:
return False, f"Blocked word: {word}"
# Check patterns
for pattern in self.patterns:
if re.search(pattern, text, re.IGNORECASE):
return False, f"Matched pattern: {pattern}"
return True, None
```
**Unicode Normalization**
```python
import unicodedata
def normalize_input(text):
# Normalize unicode
normalized = unicodedata.normalize("NFKC", text)
# Remove zero-width characters (can hide attacks)
zero_width = ["\u200b", "\u200c", "\u200d", "\ufeff"]
for char in zero_width:
normalized = normalized.replace(char, "")
return normalized
```
**API Moderation**
```python
from openai import OpenAI
client = OpenAI()
def check_moderation(text):
response = client.moderations.create(input=text)
result = response.results[0]
if result.flagged:
categories = [k for k, v in result.categories.dict().items() if v]
return False, categories
return True, None
```
**Validation Pipeline**
```python
class InputValidator:
def validate(self, request):
# 1. Normalize
text = normalize_input(request.prompt)
# 2. Length check
if len(text) > MAX_LENGTH:
raise ValidationError("Too long")
# 3. Content filter
is_safe, reason = self.content_filter.filter(text)
if not is_safe:
raise ValidationError(reason)
# 4. Moderation API
is_allowed, categories = check_moderation(text)
if not is_allowed:
raise ValidationError(f"Content policy: {categories}")
return text
```
**Best Practices**
- Validate early in request pipeline
- Use allowlists when possible
- Log validation failures
- Return clear error messages
- Combine multiple validation methods