""" NLI 幻觉检测原理详解 cross-encoder/nli-deberta-v3-xsmall 模型如何检测 RAG 中的幻觉 """ print("=" * 80) print("NLI 幻觉检测原理 - 从零开始理解") print("=" * 80) # ============================================================================ # Part 1: 什么是 NLI (Natural Language Inference)? # ============================================================================ print("\n" + "=" * 80) print("📚 Part 1: 什么是 NLI (自然语言推理)?") print("=" * 80) print(""" NLI 的核心任务: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 给定两段文本: - Premise (前提): 已知的事实/文档 - Hypothesis (假设): 待验证的陈述 判断它们之间的关系: 1️⃣ Entailment (蕴含): Hypothesis 可以从 Premise 推导出来 2️⃣ Contradiction (矛盾): Hypothesis 与 Premise 矛盾 3️⃣ Neutral (中立): 无法确定,文档中没有足够信息 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 例子 1: Entailment (蕴含) ✅ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Premise: "小明今年 18 岁,正在清华大学读计算机专业。" Hypothesis: "小明是一名大学生。" 关系: Entailment ✅ 解释: 从"正在清华大学读计算机专业"可以推导出"是大学生" 例子 2: Contradiction (矛盾) ❌ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Premise: "小明今年 18 岁,正在清华大学读计算机专业。" Hypothesis: "小明已经 30 岁了。" 关系: Contradiction ❌ 解释: "18岁" 与 "30岁" 矛盾 例子 3: Neutral (中立) ⚪ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Premise: "小明今年 18 岁,正在清华大学读计算机专业。" Hypothesis: "小明喜欢打篮球。" 关系: Neutral ⚪ 解释: 文档中没有提到小明是否喜欢打篮球,无法判断 """) # ============================================================================ # Part 2: NLI 如何用于幻觉检测? # ============================================================================ print("\n" + "=" * 80) print("🔍 Part 2: NLI 如何检测幻觉?") print("=" * 80) print(""" 核心思想: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 将 RAG 的幻觉检测转化为 NLI 任务: Premise (前提) = 检索到的文档 (Documents) Hypothesis (假设) = LLM 生成的答案 (Generation) 判断逻辑: - Entailment → 答案基于文档 → ✅ 无幻觉 - Contradiction → 答案与文档矛盾 → ❌ 有幻觉 - Neutral → 答案文档中没有 → ⚠️ 可能是幻觉 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ RAG 场景示例: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 用户问题: "AlphaCodium 论文讲的是什么?" 检索到的文档 (Premise): "AlphaCodium 是一种基于代码生成的新方法,通过迭代改进 提升 LLM 的代码能力。该方法在 CodeContests 数据集上 达到了 state-of-the-art 的性能。" LLM 生成的答案 (Hypothesis): "AlphaCodium 是一种改进 LLM 代码生成能力的迭代方法。" NLI 判断: Premise + Hypothesis → NLI 模型 → Entailment ✅ → 答案基于文档,无幻觉 反例 - 有幻觉的情况: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 检索到的文档 (Premise): "AlphaCodium 是一种基于代码生成的新方法..." LLM 生成的答案 (Hypothesis): "AlphaCodium 是 Google 在 2024 年发布的..." ↑ 文档中没有提到 Google 和 2024 NLI 判断: Premise + Hypothesis → NLI 模型 → Neutral/Contradiction ⚠️ → 答案包含文档中没有的信息,可能是幻觉 """) # ============================================================================ # Part 3: cross-encoder/nli-deberta-v3-xsmall 模型架构 # ============================================================================ print("\n" + "=" * 80) print("🤖 Part 3: cross-encoder/nli-deberta-v3-xsmall 模型架构") print("=" * 80) print(""" 模型信息: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 名称: cross-encoder/nli-deberta-v3-xsmall 基础模型: DeBERTa-v3 (Decoding-enhanced BERT with disentangled attention) 大小: 40MB (超轻量级) 参数量: 22M 训练数据: SNLI + MultiNLI (百万级句子对) 输出: 3 个类别的概率 [Entailment, Neutral, Contradiction] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 架构图: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 输入文本: Premise: "AlphaCodium 是一种代码生成方法..." Hypothesis: "AlphaCodium 是 Google 发布的..." ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 1: 输入拼接 │ │ ─────────────────────────────────────────────────────── │ │ [CLS] Premise [SEP] Hypothesis [SEP] │ │ │ │ 实际: [CLS] AlphaCodium 是一种代码生成方法 [SEP] │ │ AlphaCodium 是 Google 发布的 [SEP] │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 2: Tokenization │ │ ─────────────────────────────────────────────────────── │ │ 分词并转换为 Token IDs │ │ [101, 2945, 3421, ..., 4532, 102, 2945, 3421, ...] │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 3: DeBERTa Encoder (12 层) │ │ ─────────────────────────────────────────────────────── │ │ │ │ Layer 1-12: Disentangled Attention │ │ - Content-to-Content Attention │ │ - Content-to-Position Attention │ │ - Position-to-Content Attention │ │ │ │ 特点:位置信息和内容信息分离处理 │ │ 比 BERT 更好地理解长距离依赖 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 4: [CLS] Token 的向量表示 │ │ ─────────────────────────────────────────────────────── │ │ [CLS] 的向量包含了整个输入对的语义信息 │ │ Vector: [0.234, -0.567, 0.890, ..., 0.123] (768维) │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 5: 分类头 (Classification Head) │ │ ─────────────────────────────────────────────────────── │ │ 全连接层: 768 → 3 │ │ │ │ Logits: [2.3, -1.5, 0.8] │ │ ↑ ↑ ↑ │ │ Entail Neutral Contra │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 6: Softmax 归一化 │ │ ─────────────────────────────────────────────────────── │ │ Probabilities: │ │ Entailment: 0.15 (15%) │ │ Neutral: 0.05 (5%) │ │ Contradiction: 0.80 (80%) ← 最高! │ └─────────────────────────────────────────────────────────┘ ↓ 最终输出: Label: "Contradiction" Score: 0.80 解释: 模型认为答案与文档矛盾,置信度 80% → 检测到幻觉! """) # ============================================================================ # Part 4: 你的项目中的实际检测流程 # ============================================================================ print("\n" + "=" * 80) print("💻 Part 4: 你的项目中的实际检测流程") print("=" * 80) print(""" 完整检测流程(hallucination_detector.py): ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 输入: - generation: LLM 生成的完整答案 - documents: 检索到的文档 ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 1: 句子分割 │ │ ─────────────────────────────────────────────────────── │ │ 将 LLM 生成的答案分割成多个句子 │ │ │ │ 例如: │ │ "AlphaCodium 是一种代码生成方法。它由 Google 开发。" │ │ ↓ │ │ ["AlphaCodium 是一种代码生成方法。", │ │ "它由 Google 开发。"] │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 2: 逐句 NLI 检测 │ │ ─────────────────────────────────────────────────────── │ │ │ │ for 每个句子 in 答案: │ │ result = nli_model( │ │ premise=documents[:500], # 文档(截断到500字符)│ │ hypothesis=sentence # 当前句子 │ │ ) │ │ │ │ if "contradiction" in result.label: │ │ contradiction_count += 1 │ │ elif "neutral" in result.label: │ │ neutral_count += 1 │ │ elif "entailment" in result.label: │ │ entailment_count += 1 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 3: 统计分析 │ │ ─────────────────────────────────────────────────────── │ │ │ │ 假设检测了 10 个句子: │ │ - Entailment: 7 个 (70%) │ │ - Neutral: 2 个 (20%) │ │ - Contradiction: 1 个 (10%) │ │ │ │ total_sentences = 10 │ │ contradiction_ratio = 1/10 = 0.1 (10%) │ │ neutral_ratio = 2/10 = 0.2 (20%) │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Step 4: 判断是否有幻觉 │ │ ─────────────────────────────────────────────────────── │ │ │ │ 你的项目配置: (已优化) │ │ │ │ has_hallucination = ( │ │ contradiction_ratio > 0.3 OR # 矛盾超过 30% │ │ neutral_ratio > 0.8 # 中立超过 80% │ │ ) │ │ │ │ 上例中: │ │ contradiction_ratio = 0.1 (10%) ✅ < 30% │ │ neutral_ratio = 0.2 (20%) ✅ < 80% │ │ → has_hallucination = False ✅ │ │ → 未检测到幻觉 │ └─────────────────────────────────────────────────────────┘ ↓ 输出结果: { "has_hallucination": False, "contradiction_count": 1, "neutral_count": 2, "entailment_count": 7, "problematic_sentences": [] # 只包含矛盾的句子 } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 实际代码(hallucination_detector.py 第 187-241 行): ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ for sentence in sentences: if len(sentence) < 10: continue try: # Cross-encoder 格式 result = self.nli_model( f"{documents[:500]} [SEP] {sentence}", truncation=True, max_length=512 ) label = result[0]['label'].lower() if 'contradiction' in label: contradiction_count += 1 problematic_sentences.append(sentence) elif 'neutral' in label: neutral_count += 1 elif 'entailment' in label: entailment_count += 1 except Exception as e: print(f"⚠️ NLI 检测句子失败: {str(e)[:100]}") # 判断逻辑 total_sentences = contradiction_count + neutral_count + entailment_count if total_sentences > 0: contradiction_ratio = contradiction_count / total_sentences neutral_ratio = neutral_count / total_sentences has_hallucination = (contradiction_ratio > 0.3) or (neutral_ratio > 0.8) """) # ============================================================================ # Part 5: 为什么这个方法有效? # ============================================================================ print("\n" + "=" * 80) print("🎯 Part 5: 为什么 NLI 检测幻觉有效?") print("=" * 80) print(""" 核心优势: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1️⃣ 专门训练的任务对齐 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ NLI 模型在百万级句子对上训练,专门学习判断逻辑关系: - 训练数据: SNLI (570K) + MultiNLI (433K) - 任务: 判断 Premise 是否支持 Hypothesis - 这正是幻觉检测需要的能力! 传统 LLM: "请判断这个答案是否基于文档..." → LLM 需要理解指令、推理、生成答案 → 容易出错,不够专注 NLI 模型: Input: [Premise, Hypothesis] → 直接输出概率: [Entail, Neutral, Contra] → 专注且准确 2️⃣ 细粒度的句子级检测 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 逐句检测可以精准定位问题: 整体检测(LLM): "整个答案是否基于文档?" → 难以判断哪部分有问题 句子级检测(NLI): 句子1: "AlphaCodium 是代码生成方法" → Entailment ✅ 句子2: "由 Google 开发" → Contradiction ❌ ← 精准定位! 句子3: "在 CodeContests 上表现好" → Entailment ✅ 3️⃣ 速度和成本优势 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 模型对比: 传统 LLM (如 GPT-3.5): - 推理时间: 500-1000ms - 成本: 每次检测约 $0.001 - 参数量: 175B NLI 模型 (cross-encoder/nli-deberta-v3-xsmall): - 推理时间: 50-100ms ← 快 10 倍! - 成本: 本地运行,接近 $0 ← 省 100 倍! - 参数量: 22M ← 小 7900 倍! 4️⃣ 可解释性 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ NLI 输出清晰的概率分布: 输出示例: { "label": "Contradiction", "scores": { "entailment": 0.05, "neutral": 0.15, "contradiction": 0.80 ← 80% 确定是矛盾 } } vs LLM 输出: "我认为这个答案可能有些问题..." ← 模糊不清 """) # ============================================================================ # Part 6: DeBERTa vs BERT 的关键改进 # ============================================================================ print("\n" + "=" * 80) print("⚡ Part 6: DeBERTa vs BERT - 为什么选 DeBERTa?") print("=" * 80) print(""" DeBERTa 的核心创新:Disentangled Attention ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BERT 的问题: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 在 BERT 中,每个 token 的表示 = 内容 embedding + 位置 embedding 例如: "AlphaCodium" 在位置 5: Token Embedding = Content + Position = [0.1, 0.2, ...] + [0.3, 0.4, ...] = [0.4, 0.6, ...] 问题:内容和位置混在一起,模型难以区分: - "是" 在位置 3 的重要性 - "是" 这个词本身的语义 DeBERTa 的解决方案:分离注意力 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 将注意力分解为 3 个部分: 1. Content-to-Content Attention 词 i 的内容 关注 词 j 的内容 "AlphaCodium" 关注 "代码生成" 2. Content-to-Position Attention 词 i 的内容 关注 词 j 的位置 "是" 关注 位置 10 (上下文) 3. Position-to-Content Attention 词 i 的位置 关注 词 j 的内容 位置 5 关注 "方法" 这个词 公式: Attention(Q, K, V) = softmax( Q_c × K_c^T / √d + # Content-to-Content Q_c × K_p^T / √d + # Content-to-Position Q_p × K_c^T / √d # Position-to-Content ) × V 优势: ✅ 更好地理解长距离依赖 ✅ 更准确的语义理解 ✅ NLI 任务上性能提升 2-3% ✅ 同样参数下效果更好 模型对比: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BERT-base: - 参数: 110M - MNLI 准确率: 84.6% DeBERTa-v3-xsmall: - 参数: 22M ← 小 5 倍 - MNLI 准确率: 82.1% ← 只降低 2.5% - 推理速度: 快 3 倍 性价比最高!这就是为什么你的项目选择它 """) # ============================================================================ # Part 7: 实际案例演示 # ============================================================================ print("\n" + "=" * 80) print("📝 Part 7: 实际案例演示") print("=" * 80) print(""" 案例 1: 正常答案(无幻觉) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 文档 (Premise): "Prompt Engineering 是一种通过优化输入提示来引导 语言模型行为的方法,无需修改模型权重。" LLM 生成 (Hypothesis): "Prompt Engineering 是一种优化输入提示的方法, 用于引导语言模型的行为。" NLI 检测过程: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 句子 1: "Prompt Engineering 是一种优化输入提示的方法" → NLI: Entailment (0.92) ✅ → 文档中有:"通过优化输入提示" 句子 2: "用于引导语言模型的行为" → NLI: Entailment (0.88) ✅ → 文档中有:"引导语言模型行为" 统计: Entailment: 2/2 = 100% Neutral: 0/2 = 0% Contradiction: 0/2 = 0% 判断: contradiction_ratio = 0% < 30% ✅ neutral_ratio = 0% < 80% ✅ → 无幻觉 ✅ 案例 2: 包含幻觉的答案 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 文档 (Premise): "AlphaCodium 是一种代码生成方法,通过迭代改进 提升 LLM 的代码能力。" LLM 生成 (Hypothesis): "AlphaCodium 是 Google 在 2024 年发布的代码生成工具。 它使用强化学习来训练模型。" NLI 检测过程: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 句子 1: "AlphaCodium 是 Google 在 2024 年发布的代码生成工具" → NLI: Neutral (0.75) ⚠️ → 文档中没有提到 Google 和 2024 句子 2: "它使用强化学习来训练模型" → NLI: Neutral (0.68) ⚠️ → 文档中没有提到强化学习 统计: Entailment: 0/2 = 0% Neutral: 2/2 = 100% Contradiction: 0/2 = 0% 判断: contradiction_ratio = 0% < 30% ✅ neutral_ratio = 100% > 80% ❌ ← 触发! → 检测到幻觉 ⚠️ 案例 3: 明显矛盾 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 文档 (Premise): "这篇论文发表于 2023 年。" LLM 生成 (Hypothesis): "这篇论文是 2021 年发表的。" NLI 检测: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 句子 1: "这篇论文是 2021 年发表的" → NLI: Contradiction (0.95) ❌ → 2023 ≠ 2021,明显矛盾! 统计: Entailment: 0/1 = 0% Neutral: 0/1 = 0% Contradiction: 1/1 = 100% 判断: contradiction_ratio = 100% > 30% ❌ ← 触发! → 检测到幻觉 ❌ """) # ============================================================================ # Part 8: 优缺点分析 # ============================================================================ print("\n" + "=" * 80) print("⚖️ Part 8: NLI 幻觉检测的优缺点") print("=" * 80) print(""" 优点 ✅ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 准确率高 - 专门训练的 NLI 模型,在逻辑推理上准确率 85-95% - 比通用 LLM 判断准确 15-20% 2. 速度快 - 轻量级模型 (22M 参数) - 推理时间 50-100ms - 比 LLM 快 10 倍 3. 成本低 - 本地运行,无需 API 调用 - 成本接近 0 - 比 LLM 省 100 倍 4. 可解释性强 - 输出清晰的概率分布 - 可以定位具体问题句子 - 方便调试和优化 5. 细粒度控制 - 逐句检测 - 可自定义阈值 (30%, 80%) - 灵活调整严格程度 缺点 ❌ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 对 Neutral 的判断不够精准 - Neutral 既可能是幻觉,也可能是合理推理 - 需要设置合理的阈值(你的项目设为 80%) 2. 依赖句子分割质量 - 分割错误会影响检测 - 例如:"Mr. Smith went to U.S.A." 可能被错误分割 3. 上下文理解有限 - 只看 500 字符的文档 - 可能错过长文档中的相关信息 4. 语言依赖 - 主要在英文数据上训练 - 中文效果可能略差(但 DeBERTa-v3 对多语言支持较好) 5. 无法检测隐性幻觉 - 只能检测显式的矛盾或缺失 - 无法检测推理错误或逻辑漏洞 改进建议 💡 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 结合多种方法 你的项目已经做了:Vectara + NLI 混合检测 ✅ 2. 动态调整阈值 根据应用场景调整 contradiction/neutral 阈值 3. 增加文档长度 从 500 字符增加到 1000 字符(需要更多计算) 4. 使用更大的模型 如果准确率不够,可升级到 cross-encoder/nli-deberta-v3-base """) # ============================================================================ # Part 9: 总结 # ============================================================================ print("\n" + "=" * 80) print("📚 Part 9: 核心要点总结") print("=" * 80) print(""" NLI 幻觉检测原理: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 核心思想 将幻觉检测转化为 NLI 任务: Premise (文档) + Hypothesis (答案) → Entailment/Neutral/Contradiction 2. 模型架构 cross-encoder/nli-deberta-v3-xsmall (22M 参数, 40MB) - DeBERTa-v3: 分离注意力机制 - Cross-Encoder: 联合编码 Premise 和 Hypothesis - 3 分类头: Entailment/Neutral/Contradiction 3. 检测流程 Step 1: 分句 Step 2: 逐句 NLI 判断 Step 3: 统计 Entailment/Neutral/Contradiction 比例 Step 4: 根据阈值判断是否有幻觉 - contradiction > 30% → 幻觉 - neutral > 80% → 幻觉 4. 关键优势 ✅ 准确率: 85-95% (比 LLM 高 15-20%) ✅ 速度: 50-100ms (比 LLM 快 10 倍) ✅ 成本: 本地运行 (比 LLM 省 100 倍) ✅ 可解释: 输出清晰概率分布 5. 你的项目配置 ✅ 模型: cross-encoder/nli-deberta-v3-xsmall ✅ 阈值: contradiction > 30% or neutral > 80% ✅ 混合检测: Vectara + NLI ✅ 优化: 自动降级、错误处理、method_used 一致性 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 你的项目使用了业界最佳实践!🏆 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ """) print("\n" + "=" * 80) print("✅ NLI 幻觉检测原理讲解完毕!") print("=" * 80) print()