تصفية المدخلات على نطاق واسع
بناء مدققات مدخلات مخصصة
3 دقيقة للقراءة
الحواجز العامة لا تغطي المتطلبات الخاصة بالمجال. يوضح هذا الدرس كيفية بناء مدققات مخصصة لقواعد السلامة والأعمال الفريدة لتطبيقك.
نمط تصميم المدقق
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
from typing import Optional, List
class ValidationResult(Enum):
PASS = "pass"
FAIL = "fail"
WARN = "warn"
@dataclass
class ValidatorOutput:
result: ValidationResult
message: str
details: Optional[dict] = None
class InputValidator(ABC):
"""الفئة الأساسية لمدققات المدخلات المخصصة."""
@property
@abstractmethod
def name(self) -> str:
"""معرف المدقق."""
pass
@abstractmethod
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
"""التحقق من نص المدخل."""
pass
class ValidatorChain:
"""سلسلة مدققات متعددة معاً."""
def __init__(self, validators: List[InputValidator]):
self.validators = validators
def validate(self, text: str, context: dict = None) -> List[ValidatorOutput]:
"""تشغيل جميع المدققات وإرجاع النتائج."""
return [v.validate(text, context) for v in self.validators]
def validate_all_pass(self, text: str, context: dict = None) -> bool:
"""إرجاع True فقط إذا نجحت جميع المدققات."""
results = self.validate(text, context)
return all(r.result == ValidationResult.PASS for r in results)
مدققات خاصة بالمجال
الخدمات المالية
import re
from typing import List
class FinancialAdviceValidator(InputValidator):
"""منع طلبات النصيحة المالية المحددة."""
@property
def name(self) -> str:
return "financial_advice"
PROHIBITED_PATTERNS = [
r"should i (buy|sell|invest)",
r"which (stock|crypto|fund) (should|to)",
r"(buy|sell) (now|today)",
r"guarantee.*return",
r"risk.free.*investment",
]
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
text_lower = text.lower()
for pattern in self.PROHIBITED_PATTERNS:
if re.search(pattern, text_lower):
return ValidatorOutput(
result=ValidationResult.FAIL,
message="الطلب يبدو أنه يسعى للحصول على نصيحة مالية محددة",
details={"matched_pattern": pattern}
)
return ValidatorOutput(
result=ValidationResult.PASS,
message="لم يتم اكتشاف أنماط نصيحة مالية"
)
class TransactionAmountValidator(InputValidator):
"""التحقق من طلبات مبالغ المعاملات."""
@property
def name(self) -> str:
return "transaction_amount"
def __init__(self, max_amount: float = 10000):
self.max_amount = max_amount
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
# استخراج مبالغ الدولار
amounts = re.findall(r'\$[\d,]+\.?\d*', text)
amounts += re.findall(r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:dollars?|USD)', text, re.I)
for amount_str in amounts:
# تحليل المبلغ
amount_str = amount_str.replace('$', '').replace(',', '')
try:
amount = float(amount_str)
if amount > self.max_amount:
return ValidatorOutput(
result=ValidationResult.FAIL,
message=f"مبلغ المعاملة ${amount:,.2f} يتجاوز الحد ${self.max_amount:,.2f}",
details={"amount": amount, "limit": self.max_amount}
)
except ValueError:
continue
return ValidatorOutput(
result=ValidationResult.PASS,
message="مبالغ المعاملات ضمن الحدود"
)
الرعاية الصحية
class MedicalAdviceValidator(InputValidator):
"""منع طلبات التشخيص الطبي أو العلاج."""
@property
def name(self) -> str:
return "medical_advice"
MEDICAL_TRIGGERS = [
r"(diagnose|diagnosis)",
r"(prescribe|prescription)",
r"should i (take|stop taking)",
r"(dosage|dose) of",
r"(cure|treat|treatment) for",
r"is it (safe|dangerous) to",
]
DISCLAIMER_REQUIRED = [
r"symptom",
r"medicine",
r"medication",
r"drug",
r"health",
r"medical",
]
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
text_lower = text.lower()
# التحقق من طلبات النصيحة الطبية المحظورة
for pattern in self.MEDICAL_TRIGGERS:
if re.search(pattern, text_lower):
return ValidatorOutput(
result=ValidationResult.FAIL,
message="الطلب يبدو أنه يسعى للحصول على نصيحة تشخيص أو علاج طبي",
details={"matched_pattern": pattern}
)
# تعليم المحتوى الذي يجب أن يتضمن إخلاء مسؤولية
for pattern in self.DISCLAIMER_REQUIRED:
if re.search(pattern, text_lower):
return ValidatorOutput(
result=ValidationResult.WARN,
message="تم اكتشاف مواضيع طبية - يجب أن يتضمن الرد إخلاء مسؤولية",
details={"topic": pattern}
)
return ValidatorOutput(
result=ValidationResult.PASS,
message="لم يتم اكتشاف أنماط نصيحة طبية"
)
التجارة الإلكترونية
class CompetitorMentionValidator(InputValidator):
"""اكتشاف ومعالجة ذكر المنافسين."""
@property
def name(self) -> str:
return "competitor_mention"
def __init__(self, competitors: List[str]):
self.competitors = [c.lower() for c in competitors]
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
text_lower = text.lower()
mentioned = []
for competitor in self.competitors:
if competitor in text_lower:
mentioned.append(competitor)
if mentioned:
return ValidatorOutput(
result=ValidationResult.WARN,
message="تم ذكر منافس - تأكد من الرد المحايد",
details={"competitors": mentioned}
)
return ValidatorOutput(
result=ValidationResult.PASS,
message="لا ذكر للمنافسين"
)
class ProductAvailabilityValidator(InputValidator):
"""التحقق من استفسارات المنتج مقابل المخزون."""
@property
def name(self) -> str:
return "product_availability"
def __init__(self, inventory_service):
self.inventory = inventory_service
def validate(self, text: str, context: dict = None) -> ValidatorOutput:
# استخراج ذكر المنتجات (مبسط)
product_ids = context.get("detected_products", []) if context else []
unavailable = []
for product_id in product_ids:
if not self.inventory.is_available(product_id):
unavailable.append(product_id)
if unavailable:
return ValidatorOutput(
result=ValidationResult.WARN,
message="بعض المنتجات غير متوفرة",
details={"unavailable_products": unavailable}
)
return ValidatorOutput(
result=ValidationResult.PASS,
message="جميع المنتجات متوفرة"
)
تركيب المدققات للإنتاج
class ProductionInputValidator:
"""التحقق الكامل من المدخلات لنشر الإنتاج."""
def __init__(self, domain: str):
self.validators = self._build_chain(domain)
def _build_chain(self, domain: str) -> ValidatorChain:
"""بناء سلسلة مدققات خاصة بالمجال."""
common_validators = [
LengthValidator(max_length=5000),
LanguageValidator(allowed=["en", "es", "fr"]),
]
domain_validators = {
"finance": [
FinancialAdviceValidator(),
TransactionAmountValidator(max_amount=50000),
],
"healthcare": [
MedicalAdviceValidator(),
],
"ecommerce": [
CompetitorMentionValidator(["competitor1", "competitor2"]),
],
}
validators = common_validators + domain_validators.get(domain, [])
return ValidatorChain(validators)
async def validate(self, text: str, context: dict = None) -> dict:
"""تشغيل التحقق وإرجاع نتيجة منظمة."""
results = self.validators.validate(text, context)
failed = [r for r in results if r.result == ValidationResult.FAIL]
warned = [r for r in results if r.result == ValidationResult.WARN]
return {
"valid": len(failed) == 0,
"blocked": len(failed) > 0,
"warnings": [w.message for w in warned],
"failures": [f.message for f in failed],
"all_results": [
{"validator": v.name, "result": r.result.value, "message": r.message}
for v, r in zip(self.validators.validators, results)
]
}
# الاستخدام
validator = ProductionInputValidator(domain="finance")
result = await validator.validate("Should I buy Tesla stock now?")
# يُرجع: {"valid": False, "blocked": True, "failures": ["الطلب يبدو أنه يسعى للحصول على نصيحة مالية محددة"]}
نقطة رئيسية: المدققات الخاصة بالمجال تُشفّر قواعد أعمالك في الكود. تُكمّل الحواجز العامة بفرض قيود خاصة بالتطبيق لا يمكن للأدوات الجاهزة توفيرها.
الوحدة التالية: تعمق في مصنفات السلامة مثل LlamaGuard 3 و ShieldGemma. :::