AI Agents · درس

تدقيق الحقائق ومنع الهلوسة

التحقق القائم على الإسناد: يجب أن يُربط كل ادعاء بمصدر مُسترجَع.

الدرس 4 من 413 خطوة

تدقيق الحقائق ومنع الهلوسة درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.

مشكلة الهلوسة في وكلاء البحث

يمكن لـ LLM إنشاء ادعاءات تبدو معقولة من دون أساس في المصادر المسترجعة. ويُعد ذلك خطيرًا بصفة خاصة في وكيل البحث، لأن المخرجات تبدو موثوقة وتُقدَّم مع استشهادات قد لا تدعم الادعاء فعليًا.

يجب أن تكون الوقاية من الهلوسة محورًا أساسيًا.

الإسناد: تتبّع كل ادعاء إلى مصدر

المبدأ الأساسي للإسناد إلى المصادر هو أن كل ادعاء واقعي في المخرَج النهائي يجب أن يكون قابلاً للتتبّع إلى مستند مسترجَع واحد على الأقل. أما الادعاءات التي لا يمكن تتبّعها فهي إما هلوسات أو ادعاءات غير مدعومة — وكلاهما غير مقبول في تقرير بحثي.

def check_grounding(claim: str, retrieved_docs: list[dict]) -> dict:
    doc_texts = '\n\n'.join(
        f'[DOC {i+1}] ({d["url"]})\n{d["text"][:800]}'
        for i, d in enumerate(retrieved_docs[:5])
    )
    return {
        'claim': claim,
        'docs':  doc_texts,
        'grounded': None   # to be filled by LLM verifier
    }

if __name__ == '__main__':
    docs = [{'url': 'https://example.com/geo', 'text': 'Paris is the capital of France.'}]
    result = check_grounding('Paris is the capital of France.', docs)
    print('Claim:', result['claim'])
    print('Supporting docs used:')
    print(result['docs'])

نمط LLM بوصفه أداة تحقق

استخدم استدعاءً منفصلاً لـ LLM — «أداة التحقق» — للحكم على ما إذا كان الادعاء مدعومًا بالمصادر المقدمة. ينشئ هذا آلية تحقق وتوازن يكون فيها المُنشئ وأداة التحقق استدعاءين مستقلين.

import openai, json

client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')

def verify_claim(claim: str, source_texts: list[str]) -> dict:
    sources_block = '\n---\n'.join(source_texts[:3])
    prompt = (
        f'Is the following claim directly supported by the provided sources?\n'
        f'Claim: "{claim}"\n\n'
        f'Sources:\n{sources_block}\n\n'
        f'Return JSON: {{\n'
        f'  "supported": true/false,\n'
        f'  "confidence": 0.0-1.0,\n'
        f'  "reason": "one sentence explanation"\n'
        f'}}'
    )
    resp = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

المخرَج المحكوم بدرجة الثقة

حدّد حدودًا لدرجة الثقة التي تمنحها أداة التحقق. تُنشر الادعاءات التي تتجاوز 0.85. أما الادعاءات بين 0.5 و0.85 فتُنشر مع إخلاء مسؤولية. وتُستبعد الادعاءات التي تقل عن 0.5.

INCLUDE_THRESHOLD  = 0.85
DISCLAIMER_THRESHOLD = 0.50

def gate_claim(claim: str, source_texts: list[str]) -> dict:
    result = verify_claim(claim, source_texts)
    conf = result.get('confidence', 0.0)
    supported = result.get('supported', False)

    if not supported or conf < DISCLAIMER_THRESHOLD:
        return {'action': 'exclude', 'claim': claim, 'reason': result.get('reason')}
    elif conf < INCLUDE_THRESHOLD:
        return {
            'action': 'include_with_disclaimer',
            'claim': f'[LOW CONFIDENCE] {claim}',
            'reason': result.get('reason')
        }
    else:
        return {'action': 'include', 'claim': claim}

اكتشاف أنماط محددة من الهلوسة

تُعد أنماط معينة من الادعاءات عالية الخطورة فيما يتعلق بالهلوسة، مثل الإحصاءات الدقيقة (النسب المئوية والمبالغ بالدولار)، والتواريخ المحددة، والأفراد المذكورين بالاسم، والعلاقات السببية. طبّق تدقيقًا إضافيًا على هذه الأنماط.

import re

def is_high_risk_claim(claim: str) -> bool:
    patterns = [
        r'\d+\.?\d*\s*%',            # percentages: 9.1%
        r'\$\s*\d+',                  # dollar amounts
        r'\b(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{4}',  # dates
        r'\b[A-Z][a-z]+\s+[A-Z][a-z]+\s+(said|stated|argued|claimed)',  # named quotes
        r'(caused?|led to|resulted in)',                                  # causal claims
    ]
    return any(re.search(p, claim) for p in patterns)

print(is_high_risk_claim('Inflation hit 9.1% in June 2022'))  # True
print(is_high_risk_claim('Inflation was elevated'))            # False

حلقة التحقق المُجزّأة

بالنسبة إلى الأقسام الطويلة، جزّئ النص إلى ادعاءات فردية، وتحقق من كل ادعاء بشكل مستقل، ثم أعد بناء القسم باستخدام الادعاءات التي تم التحقق منها فقط.

def decompose_into_claims(section_text: str) -> list[str]:
    prompt = (
        f'Break this text into individual verifiable factual claims.\n'
        f'Each claim should be a single sentence containing exactly one fact.\n'
        f'Return JSON: {{"claims": ["..."]}}\n\n'
        f'TEXT:\n{section_text}'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content).get('claims', [])

إعادة بناء النص الذي تم التحقق منه

بعد تطبيق بوابة التحقق على كل ادعاء، أعد بناء قسم واضح ومترابط باستخدام الادعاءات التي تم التحقق منها فقط. استبعد الادعاءات منخفضة الثقة وأعد صياغة النص لتحسين سهولة قراءته.

def reconstruct_section(verified_claims: list[str],
                        section_name: str) -> str:
    claims_text = '\n'.join(f'- {c}' for c in verified_claims)
    prompt = (
        f'Rewrite these verified facts as a coherent {section_name} section.\n'
        f'Do NOT add any new information not present in the claims.\n'
        f'Only use the facts provided.\n\n'
        f'VERIFIED CLAIMS:\n{claims_text}'
    )
    resp = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return resp.choices[0].message.content

اكتشاف الانحراف الرقمي

تُغيّر نماذج LLM أحيانًا الأرقام الواردة في المصدر تغييرًا طفيفًا، مثل تحوّل 9.1% إلى 9.2%. استخرج الأرقام من الادعاء ومن نص المصدر، ثم قارن بينها صراحةً.

import re

def extract_numbers(text: str) -> list[float]:
    matches = re.findall(r'[-+]?\d*\.?\d+', text)
    return [float(m) for m in matches]

def check_numeric_drift(claim: str, source_text: str,
                        tolerance: float = 0.01) -> bool:
    claim_nums  = extract_numbers(claim)
    source_nums = extract_numbers(source_text)

    for cn in claim_nums:
        found_match = any(abs(cn - sn) <= tolerance for sn in source_nums)
        if not found_match:
            return True  # numeric drift detected
    return False

print(check_numeric_drift(
    'Inflation reached 9.2% in June 2022',
    'The CPI rose 9.1 percent in June 2022'
))  # True — 9.2 vs 9.1

تدقيق الإسناد

بعد إنشاء تقرير كامل، أجرِ تدقيقًا للإسناد: تحقّق لكل جملة في التقرير من إمكانية إسنادها إلى أحد المصادر. وأشِر إلى أي جملة لا يحتوي أي مصدر على مقتطف مطابق لها.

def attribution_audit(report_text: str, sources: list[dict]) -> list[str]:
    sentences = [s.strip() for s in report_text.split('.') if len(s.strip()) > 20]
    unattributed = []

    for sentence in sentences:
        found = False
        for src in sources:
            if any(word in src.get('text', '') for word in sentence.split()[:5]):
                found = True
                break
        if not found:
            unattributed.append(sentence)

    return unattributed

# Flag unattributed sentences for manual review or re-verification

if __name__ == '__main__':
    report = ("Water boils at 100 degrees Celsius at sea level. "
              "The moon is made primarily of green cheese according to this document.")
    sources = [{'text': 'Water boils at 100C (212F) at standard atmospheric pressure.'}]
    unattributed = attribution_audit(report, sources)
    print('Unattributed sentences (need manual review):')
    for s in unattributed:
        print(' -', s)

استخدام لغة التحفّظ مع الادعاءات غير المؤكدة

لا يمكن التحقق من كل شيء بدرجة ثقة عالية. وبدلًا من استبعاد الادعاءات الحدّية تمامًا، استخدم لغة التحفّظ، مثل: «يشير بعض المحللين إلى...»، و«وفقًا لـ X...»، و«أُفيد بأن...». يحافظ ذلك على المعلومات مع الإشارة إلى عدم اليقين.

def hedge_claim(claim: str, confidence: float) -> str:
    if confidence >= 0.85:
        return claim  # state as fact
    elif confidence >= 0.65:
        hedges = ['Some sources suggest', 'According to available evidence',
                  'Analysts have noted']
        return f'{hedges[hash(claim) % len(hedges)]}, {claim.lower()}'
    else:
        return f'It has been reported (with low confidence) that {claim.lower()}'

print(hedge_claim('Inflation peaked at 9.1%', 0.90))
print(hedge_claim('Supply chain disruptions contributed to inflation', 0.72))
print(hedge_claim('Specific policy caused inflation', 0.45))

مراقبة معدل الهلوسة

تتبّع معدل الهلوسة بمرور الوقت: ما النسبة المئوية من الادعاءات المُنشأة التي تفشل في التحقق؟ حدّد حدًا لإطلاق التنبيه. فإذا ارتفع المعدل فجأة، فهذا يعني أن هندسة التعليمات أو جودة الاسترجاع قد تراجعت.

verification_log = []  # In production: a database

def log_verification(claim: str, supported: bool, confidence: float):
    verification_log.append({
        'claim':      claim[:100],
        'supported':  supported,
        'confidence': confidence
    })

def hallucination_rate() -> float:
    if not verification_log:
        return 0.0
    failed = sum(1 for v in verification_log if not v['supported'])
    return failed / len(verification_log)

def check_hallucination_alert(threshold: float = 0.15):
    rate = hallucination_rate()
    if rate > threshold:
        print(f'ALERT: Hallucination rate {rate:.1%} exceeds threshold {threshold:.1%}')
    return rate

if __name__ == '__main__':
    log_verification('The sky is blue', True, 0.95)
    log_verification('The moon is made of cheese', False, 0.2)
    log_verification('Water boils at 100C at sea level', True, 0.99)
    rate = check_hallucination_alert(threshold=0.15)
    print(f'Hallucination rate so far: {rate:.1%}')

ما الغرض الأساسي من نمط «LLM بوصفه أداة تحقق»؟

يُعد نمط LLM بوصفه أداة تحقق نمطًا معماريًا أساسيًا للوقاية من الهلوسة. ومن الضروري فهم ما الذي يتحقق منه ولماذا يُنفّذ ذلك عبر استدعاء منفصل.

مراجعة الوقاية من الهلوسة

امنع الهلوسة من خلال: فحوصات الإسناد إلى المصادر (تتبّع كل ادعاء إلى مصدر)، ونمط LLM بوصفه أداة تحقق (استدعاء منفصل يحكم على الدعم)، وبوابة الثقة (استبعاد الادعاءات التي تقل عن الحد المحدد)، واكتشاف الانحراف الرقمي، ولغة التحفّظ للحالات الحدّية، ومراقبة معدل الهلوسة لاكتشاف التراجعات.

البدء مجانًا

تعلم AI Agents مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
60
الدروس
239

الأسئلة الشائعة

هل درس «تدقيق الحقائق ومنع الهلوسة» مجاني؟

نعم — نص درس «تدقيق الحقائق ومنع الهلوسة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.

ماذا ستتعلم في «تدقيق الحقائق ومنع الهلوسة»؟

التحقق القائم على الإسناد: يجب أن يُربط كل ادعاء بمصدر مُسترجَع. تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟

لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تدقيق الحقائق ومنع الهلوسة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟

نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تصميم حلقة البحث متعددة الخطوات
  2. التحقق من المصادر وإضافة الاستشهادات
  3. إنشاء التقارير المنظَّمة
  4. تدقيق الحقائق ومنع الهلوسة
← العودة إلى AI Agents