تعمق في مصنفات السلامة

تكييف التصنيف المخصص

3 دقيقة للقراءة

تستخدم مصنفات السلامة المدربة مسبقاً تصنيفات عامة قد لا تناسب مجالك المحدد. يغطي هذا الدرس تكييف وتوسيع فئات السلامة للمتطلبات الخاصة بالمجال.

متى تخصص

خصص تصنيفك عندما:

  • محتوى خاص بالصناعة: النصائح المالية، المعلومات الطبية، التوجيه القانوني
  • السياق الثقافي: معايير المحتوى الإقليمية، الفروق الدقيقة الخاصة باللغة
  • قواعد العمل: سلامة العلامة التجارية، ذكر المنافسين، قيود الموضوع
  • حالة الاستخدام: دعم العملاء مقابل الكتابة الإبداعية مقابل توليد الكود

توسيع تصنيف LlamaGuard

from typing import Dict, List
import json

# تصنيف LlamaGuard 3 الأساسي
LLAMAGUARD_BASE = {
    "S1": "الجرائم العنيفة",
    "S2": "الجرائم غير العنيفة",
    # ... S3-S14
}

# امتدادات مخصصة للخدمات المالية
FINANCIAL_TAXONOMY = {
    **LLAMAGUARD_BASE,
    "F1": "نصيحة استثمارية",
    "F2": "توجيه ضريبي",
    "F3": "توصيات تأمين",
    "F4": "انتهاكات تنظيمية",
    "F5": "ذكر المنافسين"
}

class CustomTaxonomyClassifier:
    """مصنف مع امتدادات تصنيف مخصصة."""

    def __init__(self, base_classifier, custom_rules: Dict[str, callable]):
        self.base = base_classifier
        self.custom_rules = custom_rules
        self.taxonomy = FINANCIAL_TAXONOMY

    def classify(self, content: str) -> Dict:
        """التصنيف مع القواعد الأساسية + المخصصة."""
        # تشغيل التصنيف الأساسي
        base_decision, base_categories = self.base.classify(content)

        # تشغيل فحوصات القواعد المخصصة
        custom_violations = []
        for code, rule_fn in self.custom_rules.items():
            if rule_fn(content):
                custom_violations.append(code)

        # دمج النتائج
        all_categories = base_categories + custom_violations
        final_decision = "unsafe" if all_categories else "safe"

        return {
            "decision": final_decision,
            "categories": all_categories,
            "base_result": base_decision,
            "custom_violations": custom_violations
        }

# تعريف القواعد المخصصة
def check_investment_advice(text: str) -> bool:
    """التحقق من النصيحة الاستثمارية غير المصرح بها."""
    investment_patterns = [
        r"you should (buy|sell|invest)",
        r"guaranteed returns",
        r"risk-free investment",
        r"I recommend (buying|selling)"
    ]
    import re
    return any(re.search(p, text.lower()) for p in investment_patterns)

def check_competitor_mention(text: str) -> bool:
    """التحقق من ذكر العلامات التجارية المنافسة."""
    competitors = ["competitor_a", "competitor_b", "other_bank"]
    return any(comp in text.lower() for comp in competitors)

# الاستخدام
custom_rules = {
    "F1": check_investment_advice,
    "F5": check_competitor_mention
}

classifier = CustomTaxonomyClassifier(
    base_classifier=LlamaGuard3Classifier(model_size="1B"),
    custom_rules=custom_rules
)

ضبط مصنفات السلامة

للفئات المخصصة المستمرة، اضبط مصنفاً:

from transformers import (
    AutoTokenizer,
    AutoModelForSequenceClassification,
    TrainingArguments,
    Trainer
)
from datasets import Dataset
import torch

class SafetyClassifierFineTuner:
    """ضبط مصنفات السلامة للتصنيف المخصص."""

    def __init__(self, base_model: str = "martin-ha/toxic-comment-model"):
        self.tokenizer = AutoTokenizer.from_pretrained(base_model)
        self.model = AutoModelForSequenceClassification.from_pretrained(
            base_model,
            num_labels=2  # آمن/غير آمن
        )

    def prepare_dataset(
        self,
        examples: List[Dict],
        custom_category: str
    ) -> Dataset:
        """
        إعداد بيانات التدريب للفئة المخصصة.

        تنسيق الأمثلة:
        [{"text": "...", "label": 0/1}, ...]
        """
        def tokenize(batch):
            return self.tokenizer(
                batch["text"],
                truncation=True,
                max_length=512,
                padding="max_length"
            )

        dataset = Dataset.from_list(examples)
        dataset = dataset.map(tokenize, batched=True)
        return dataset

    def fine_tune(
        self,
        train_dataset: Dataset,
        eval_dataset: Dataset = None,
        output_dir: str = "./custom_classifier",
        epochs: int = 3
    ):
        """ضبط المصنف."""
        training_args = TrainingArguments(
            output_dir=output_dir,
            num_train_epochs=epochs,
            per_device_train_batch_size=16,
            per_device_eval_batch_size=16,
            warmup_steps=100,
            weight_decay=0.01,
            logging_steps=50,
            evaluation_strategy="epoch" if eval_dataset else "no",
            save_strategy="epoch",
            load_best_model_at_end=True if eval_dataset else False,
        )

        trainer = Trainer(
            model=self.model,
            args=training_args,
            train_dataset=train_dataset,
            eval_dataset=eval_dataset,
        )

        trainer.train()
        trainer.save_model(output_dir)
        self.tokenizer.save_pretrained(output_dir)

        return trainer

# مثال: ضبط لاكتشاف النصيحة المالية
training_data = [
    {"text": "يجب عليك بالتأكيد شراء سهم AAPL", "label": 1},
    {"text": "إليك كيف تعمل أسواق الأسهم بشكل عام", "label": 0},
    {"text": "أضمن عوائد 20% على هذا الاستثمار", "label": 1},
    {"text": "الاستثمارات تحمل مخاطر الخسارة", "label": 0},
    # ... المزيد من الأمثلة
]

finetuner = SafetyClassifierFineTuner()
train_ds = finetuner.prepare_dataset(training_data, "investment_advice")
finetuner.fine_tune(train_ds, output_dir="./investment_advice_classifier")

التصنيف المبني على المحثات مع LLMs

للتصنيف المرن بدون ضبط:

from openai import OpenAI

class PromptBasedClassifier:
    """مصنف مبني على LLM مع تصنيف ديناميكي."""

    def __init__(self, api_key: str):
        self.client = OpenAI(api_key=api_key)
        self.taxonomy = {}

    def add_category(
        self,
        code: str,
        name: str,
        description: str,
        examples: List[str] = None
    ):
        """إضافة فئة مخصصة للتصنيف."""
        self.taxonomy[code] = {
            "name": name,
            "description": description,
            "examples": examples or []
        }

    def classify(self, content: str) -> Dict:
        """تصنيف المحتوى ضد التصنيف المخصص."""
        taxonomy_prompt = self._build_taxonomy_prompt()

        response = self.client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {
                    "role": "system",
                    "content": f"""أنت مصنف سلامة محتوى.

صنف محتوى المستخدم ضد هذه الفئات:

{taxonomy_prompt}

أجب بتنسيق JSON:
{{"decision": "safe" أو "unsafe", "categories": ["code1", "code2"], "reasoning": "..."}}"""
                },
                {"role": "user", "content": content}
            ],
            response_format={"type": "json_object"}
        )

        return json.loads(response.choices[0].message.content)

    def _build_taxonomy_prompt(self) -> str:
        """بناء وصف التصنيف للمحث."""
        lines = []
        for code, info in self.taxonomy.items():
            line = f"- {code}: {info['name']}\n  الوصف: {info['description']}"
            if info['examples']:
                line += f"\n  أمثلة: {', '.join(info['examples'][:3])}"
            lines.append(line)
        return "\n".join(lines)

# الاستخدام لروبوت دردشة الرعاية الصحية
classifier = PromptBasedClassifier(api_key="...")

classifier.add_category(
    code="H1",
    name="التشخيص الطبي",
    description="محتوى يوفر تشخيصات طبية محددة أو يقترح حالات",
    examples=["لديك مرض السكري", "هذا يبدو مثل السرطان"]
)

classifier.add_category(
    code="H2",
    name="نصيحة الأدوية",
    description="توصيات لأدوية أو جرعات محددة",
    examples=["تناول 500 ملغ إيبوبروفين", "يجب أن تجرب هذا الدواء"]
)

classifier.add_category(
    code="H3",
    name="إعادة توجيه الطوارئ",
    description="مواقف تتطلب رعاية طبية فورية",
    examples=["ألم في الصدر", "صعوبة في التنفس", "نزيف حاد"]
)

result = classifier.classify("أعتقد أنك قد تكون مصاباً بالتهاب الزائدة الدودية بناءً على أعراضك")
# يُرجع: {"decision": "unsafe", "categories": ["H1"], "reasoning": "..."}

نهج المجموعة للإنتاج

from dataclasses import dataclass
from typing import List, Dict, Optional
from enum import Enum

class ViolationType(Enum):
    BASE_SAFETY = "base_safety"
    CUSTOM_RULE = "custom_rule"
    DOMAIN_SPECIFIC = "domain_specific"

@dataclass
class EnsembleResult:
    is_safe: bool
    violations: List[Dict]
    confidence: float

class EnsembleClassifier:
    """مجموعة إنتاج مع طبقات تصنيف متعددة."""

    def __init__(self):
        self.classifiers = []

    def add_classifier(
        self,
        name: str,
        classifier: callable,
        priority: int = 1,
        veto_power: bool = False
    ):
        """إضافة مصنف للمجموعة."""
        self.classifiers.append({
            "name": name,
            "fn": classifier,
            "priority": priority,
            "veto_power": veto_power
        })
        self.classifiers.sort(key=lambda x: x["priority"], reverse=True)

    def classify(self, content: str) -> EnsembleResult:
        """تشغيل جميع المصنفات وتجميع النتائج."""
        all_violations = []
        veto_triggered = False

        for clf in self.classifiers:
            result = clf["fn"](content)

            if result.get("violations"):
                for v in result["violations"]:
                    all_violations.append({
                        "source": clf["name"],
                        "category": v,
                        "priority": clf["priority"]
                    })

                if clf["veto_power"]:
                    veto_triggered = True

        # حساب الثقة بناءً على الاتفاق
        if not all_violations:
            confidence = 0.95
        elif veto_triggered:
            confidence = 0.99
        else:
            confidence = min(0.5 + (len(all_violations) * 0.15), 0.95)

        return EnsembleResult(
            is_safe=len(all_violations) == 0,
            violations=all_violations,
            confidence=confidence
        )

# إعداد الإنتاج
ensemble = EnsembleClassifier()

# السلامة الأساسية (أعلى أولوية، قوة النقض)
ensemble.add_classifier(
    name="llamaguard",
    classifier=lambda x: {"violations": LlamaGuard3Classifier().classify(x)[1]},
    priority=10,
    veto_power=True
)

# قواعد المجال
ensemble.add_classifier(
    name="financial_rules",
    classifier=lambda x: {
        "violations": ["F1"] if check_investment_advice(x) else []
    },
    priority=5
)

# سلامة العلامة التجارية
ensemble.add_classifier(
    name="brand_safety",
    classifier=lambda x: {
        "violations": ["B1"] if check_competitor_mention(x) else []
    },
    priority=3
)

أفضل ممارسة: ابدأ بمصنف سلامة أساسي (LlamaGuard/ShieldGemma) وأضف قواعد خاصة بالمجال فوقه. هذا يضمن عدم تفويت مشاكل السلامة العامة مع التقاط الانتهاكات الخاصة بالمجال.

التالي: التعمق في إطار عمل NVIDIA NeMo Guardrails. :::

اختبار

الوحدة 3: تعمق في مصنفات السلامة

خذ الاختبار
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.