你在 RAG 系统里召回了一堆资料,模型却一本正经地把其中的过期内容当成最新事实回答给用户。你在模型前面塞了 50 页对话历史,结果它被前几轮用户自己编造的结论带偏。你甚至把系统提示写得很强,要求模型“只能依据上下文作答”,但当上下文本身自相矛盾时,模型依然不知道该怎么办。
这背后是一个经常被低估的问题:大模型不是缺上下文,而是缺“判断哪些上下文可以信任”的能力。传统做法是把信任决策留给推理阶段的过滤规则,或者指望偏好优化让模型“无脑跟随上下文”,但两条路都走不通。这篇文章要讨论的Selective Context Preference Optimization(选择性上下文偏好优化),就是把“何时信任上下文”这个决策直接嵌入模型训练过程,让模型学会在可信上下文中遵循证据,在不可信上下文中保持拒绝或不确定性。
读完这篇文章,你会理解这个方法要解决的问题、它和传统 DPO / RLHF 的差异、核心方法框架,以及一套可以照做的训练与评估流程。即使你不打算复现论文,这套“选择性信任”的思路也会直接改善你在 RAG、长对话、Agent 工具调用场景下的模型表现。
1. 这篇文章真正要解决的问题
先明确一个判断:模型对上下文的处理,不能是“全盘接受”,也不能是“一律怀疑”。真实业务场景里,上下文的质量是高度波动的,模型必须学会按可信度做条件化反应。
举三个非常常见的失败场景。
第一个是 RAG 检索噪声。检索器返回 Top-K 文档时,往往只有前几条是真正相关的,后几条可能是语义相似但事实错误的内容。如果模型对所有检索结果一视同仁,它就可能把无关文档里的信息混进答案。第二个是长对话历史污染。用户在多轮对话中可能表达过错误假设,后续模型会延续这个错误;如果上下文中同时存在“正确事实”和“用户错误表述”,模型需要识别哪种信息更可靠。第三个是系统指令与检索内容的冲突。系统提示说“不要编造”,但检索到的文档本身来历不明,模型很难判断该听谁的。
更麻烦的是,这些问题在推理阶段很难靠规则解决。你可以写一个关键词黑名单,但过滤不掉语义层面的误导;你可以做模型置信度判断,但模型对自己生成内容的置信度本身就不一定可靠。真正更合理的方式,是在训练阶段就让模型建立一种条件化行为:当上下文证据充分且一致时,遵循上下文;当上下文证据缺失或冲突时,拒绝作答或明确表达不确定性。
Selective Context Preference Optimization 的核心目标,就是把这种“选择性信任”变成模型的一种内在能力,而不是外部拼装的补丁。
这篇文章适合以下读者:
- 正在做 RAG 应用的工程师,被“检索结果误导模型”折磨过。
- 做 LLM 对齐、偏好优化、RLHF 的算法同学,想知道 DPO 这类方法还能怎么改进。
- 做 Agent 或长上下文应用的人,想减少模型对噪声上下文的过度依赖。
- 想理解“上下文选择”和“偏好优化”如何结合的进阶学习者。
读完你会得到三类收益:理解方法的设计逻辑;拿到一份可改的实验框架(含伪代码、数据格式、训练循环、评估脚本);知道在实际项目中哪些环节最容易踩坑。
2. LLM 上下文信任问题的现状
2.1 上下文不是越多越好
过去两年,模型的上下文窗口从 2K 一路卷到 200K、1M。很多人的第一反应是:窗口够大,问题就解决了。但事实恰好相反,上下文窗口变大,只是让更多“噪声”同时涌进模型,并没有告诉模型哪些内容更重要。
在没有可靠机制的情况下,长上下文中的无关信息会稀释有效信息。更糟糕的是,某些错误信息天然具有更强的“表面可信度”,例如格式工整、包含具体日期、引用了看起来正规的机构名称。模型很容易因为这些表面特征而被带偏。
这也是为什么业界开始强调上下文选择(Selective Context),而不是单纯追求上下文长度。关键不是“模型看了多少内容”,而是“模型看了什么、信任了什么、忽略了什么”。
2.2 关于上下文可信度的常见误区
很多人觉得,“只要把系统提示改成必须基于上下文作答,模型就会更听话”。实际效果往往有限。系统提示能改变模型的宏观倾向,但当模型需要在“上下文中存在两个互相矛盾的答案”之间做出选择时,它缺少一个显式的可信度信号。
另一个误区是,认为“检索质量足够高就不需要模型做信任判断”。但即使是 100% 精确的检索器,也需要面对对话历史污染、用户主观表达、多文档之间冲突的问题。换句话说,信任判断不应该完全外包给上游模块,模型自己也要具备“这条信息看起来不可信、我不要用它来回答”的能力。
2.3 几个核心概念:先把术语对齐
先解释几个后面会反复出现的术语,避免理解偏差。
Preference Optimization(偏好优化)是 RLHF 的替代或简化方案。思路是准备一组“更好的回答”和“更差的回答”,让模型学习提升好回答的概率、压低差回答的概率。DPO、KTO、IPO 都属于这类方法,它们不需要训练独立的奖励模型,而是直接用偏好对做优化。
Selective Context(选择性上下文)指的是模型在生成时不是无差别使用全部上下文,而是根据某种信号筛选或加权使用上下文。可以是训练阶段的加权,也可以是推理阶段的动态选择。
Selective Context Preference Optimization把两者合起来:在偏好优化训练中引入上下文可信度信号,让模型在可信上下文中学会“遵循”,在不可信上下文中学会“拒绝”。它的关键不是改变推理时的规则,而是改变模型的权重分配方式。
概念对比如下:
| 方法 | 对上下文的处理方式 | 训练信号 | 核心限制 |
|---|---|---|---|
| 传统 RLHF / DPO | 默认上下文可信,优化对好回答的偏好 | 回答质量差异 | 忽略上下文本身可能错误 |
| 推理期上下文过滤 | 用规则或模型过滤上下文后再生成 | 无训练信号 | 不能从源头改变模型行为 |
| Selective Context Preference Optimization | 训练时按上下文可信度选择偏好目标 | 回答质量差异 + 上下文可信度 | 需要高质量可信度标签或评估机制 |
3. 传统偏好优化为什么不够
3.1 DPO 的基本逻辑回顾
DPO(Direct Preference Optimization)的核心思路可以概括成一句话:如果模型本来就倾向于好回答,就不需要改动;如果模型倾向于差回答,就加大惩罚。它的损失函数在形式上可以理解为:
L = -log sigmoid(beta * (log(pi(y_w|x) / pi_ref(y_w|x)) - log(pi(y_l|x) / pi_ref(y_l|x))))其中 (y_w) 是好回答,(y_l) 是差回答,(x) 是输入。这个公式的含义是:让当前模型对好回答的相对概率,尽量高于参考模型对好回答的相对概率,同时压低对差回答的相对概率。
这个逻辑本身没有问题。问题出在 (x) 的定义上。在传统偏好优化中,(x) 往往被假定为“正确的输入”,因此模型被训练为“面对任意给定上下文,都偏向更好的回答”。
3.2 问题:当上下文本身是错的
设想一个偏好对:
上下文:某产品的发布时间是 2021 年 好回答:该产品发布于 2021 年 差回答:该产品发布于 2022 年如果“某产品发布时间是 2021 年”这一信息本身来自一篇过时文档,而真实发布时间是 2022 年,那么这个偏好对就在教模型“信任错误上下文”。模型学到的是:只要上下文中出现了某个事实,就应当采信并顺着它回答。
更隐蔽的问题是,当训练数据里同时存在“可信上下文 + 正确回答”和“不可信上下文 + 错误采信”的样本时,模型会做一种平均化处理。它既不会彻底相信上下文,也不会彻底抵抗上下文,最后生成一种“两头不靠”的模糊输出。这种输出在评估指标上可能不显著变差,但在真实业务中非常难用。
3.3 反思:信任应该是条件化的
传统偏好优化的本质假设是:给定输入,好回答永远比差回答更值得学习。但现实是,同一个回答好不好,取决于上下文是否可信。同一个“拒绝回答”,在面对高可信上下文时是坏行为,在面对低可信上下文时却是好行为。
Selective Context Preference Optimization 正是从这个观察出发:信任不是全局属性,而是条件属性。模型需要同时学习两件事:一是判断当前上下文可信与否;二是在可信条件下采取“遵循”策略,在不可信条件下采取“拒绝”策略。这两件事放在同一个偏好优化框架里联合学习,比分成两个独立模块更自然。
4. Selective Context Preference Optimization 方法框架
4.1 总体思路:把可信度信号带入偏好优化
整个方法可以拆成三层来看。
第一层是上下文评估。我们需要知道一个上下文的可信程度。这个信号可以是离散的(reliable / unreliable),也可以是连续的(0 到 1 的权重)。它可能来自人工标注,也可能来自一个单独的评估模型,甚至可以用规则做初始化。
第二层是偏好数据构造。针对一条输入,我们不仅区分好回答和差回答,还要区分“这条上下文是否值得信赖”。如果上下文不可信,那么正确的回答应该是拒绝或质疑,而不是顺着上下文作答。
第三层是优化目标设计。在传统的偏好损失上,加上一个可信度相关的权重或约束项,让模型只在合适的样本上学习“遵循”,并在不可信样本上学习“拒绝”。
4.2 上下文质量评估与样本选择
先说最现实的问题:上下文可信度标签从哪来?
最直接的方式是人工标注,但成本很高。更可行的方案是分层推进:
- 规则启发式:比如检测检索结果的得分、来源域名白名单、信息时效性、文档间是否冲突。这些规则不一定精确,但可以产生第一批弱标签。
- 模型打分:用一个较小的评判模型(可以是通用 LLM,也可以是微调过的分类器)对“上下文是否能支持问题回答”打分。
- 一致性校验:用多个检索通道得到多个文档,判断它们之间是否互相矛盾。矛盾越明显,可信度越低。
- 事后标注:基于模型的试运行结果,找人类标注“这个错误是否由上下文误导导致”,再反推上下文的可信度。
在这个阶段,不需要追求标签的绝对精确。偏好优化对噪声有一定的容忍度,而且“上下文很差”的样本往往更容易识别,模型学到的拒绝行为也更容易泛化。
4.3 构造选择性偏好对
构造数据时,需要区分四种组合:
| 上下文可信度 | 回答行为 | 是否应该被强化 |
|---|---|---|
| 高可信 | 遵循上下文,给出正确回答 | 应该强化 |
| 高可信 | 忽略上下文,给出错误回答 | 应该惩罚 |
| 低可信 | 正确识别并拒绝 / 指出不确定性 | 应该强化 |
| 低可信 | 盲目遵循,输出误导性回答 | 应该惩罚 |
这里最核心的设计是:不能让模型对所有“好回答”都做同样的强化。在低可信上下文下,模型输出的“我无法确认,这需要进一步核实”才应该是偏好对里的 chosen 回答,而不是一个看似信息完整但实际来自错误上下文的回答。
具体到一条训练样本,可以这样组织:
{ "context": "...检索到的资料片段...", "question": "该产品何时发布?", "context_quality": "low", "chosen": "根据现有资料无法确认发布日期,建议查看官方公告。", "rejected": "该产品发布于 2021 年 6 月。" }注意,这里的 chosen 回答并没有“顺着检索结果回答”,而是做了拒绝。这正是选择性上下文偏好的关键区别。
4.4 优化目标:带可信度加权的偏好损失
在数学上,可以把 Selective Context Preference Optimization 的损失函数理解为一个加权版本。假设我们有一个可信度信号 (s),对于 high-quality 上下文,(s) 更接近 1;对于 low-quality 上下文,(s) 更接近 0。
基本的损失形式可以用下面的伪代码表达:
L = weight * DPO_Loss(pi_theta, pi_ref, x, y_w, y_l) + (1 - weight) * Reject_Loss(pi_theta, x, y_reject, y_follow)其中:
weight来自上下文可信度。- 高可信样本上,主要训练模型“遵循正确上下文”的偏好。
- 低可信样本上,主要训练模型“拒绝错误上下文”的偏好。
- 为了让模型不彻底退化,可以在损失中加入一个相对参考模型的 KL 正则项。
这个设计的关键是:同一个偏好优化框架,在不同可信度条件下,优化方向并不相同。高可信时优化方向是“让模型更相信上下文”,低可信时优化方向是“让模型抵抗上下文”。两个方向用一个信号做平滑过渡。
5. 完整示例:训练流程与代码实现
下面给出一个最小可运行的实验框架。这部分代码以“可理解、可改造成自己项目”为目标,不代表任何官方实现。具体 API 请以使用的框架版本为准。
5.1 环境准备
建议环境:
- Python 3.9 以上。
- PyTorch 2.0 以上。
- Transformers 库,版本以实际项目为准。
- 一个用于加载训练数据的库,比如 datasets。
- 显存建议至少 24GB,如果资源紧张,可以先从 0.5B 或 1B 模型开始。
下面的命令是创建虚拟环境的一种方式:
python3 -m venv venv-scpo source venv-scpo/bin/activate pip install torch transformers datasets accelerate如果你打算用更完整的训练框架,可以再补充安装 TRL 或 peft。但为了讲清原理,这里先不依赖高级封装。
5.2 准备训练数据
训练数据采用 JSONL 格式。每一行包含一个输入样本、上下文可信度信号、chosen 回答和 rejected 回答。
下面是两个示例样本:
{"context": "来自官方文档的说明:系统 v2.0 于 2024 年 3 月正式发布。", "question": "v2.0 什么时候发布?", "context_quality": 0.9, "chosen": "v2.0 于 2024 年 3 月发布。", "rejected": "v2.0 于 2023 年发布。"} {"context": "某匿名博客声称:系统 v2.0 于 2025 年发布,来源不明。", "question": "v2.0 什么时候发布?", "context_quality": 0.1, "chosen": "当前资料无法确认发布时间,建议查询官方公告。", "rejected": "v2.0 于 2025 年发布。"}注意context_quality字段范围是 0 到 1。这个数字可以来自人工规则、评判模型或任何你觉得合适的信号。chosen不一定总是“完整答案”,在低可信上下文里,它可以是“拒绝作答”。
5.3 损失函数核心实现
下面是一段可运行的 PyTorch 风格的损失函数示意,用于理解核心逻辑。完整训练工程还需要补充数据加载、batch 组拼、分布式训练等细节。
import torch import torch.nn.functional as F def selective_context_dpo_loss( policy_logps_chosen, # 当前模型对 chosen 回答的 log 概率 policy_logps_rejected, # 当前模型对 rejected 回答的 log 概率 ref_logps_chosen, # 参考模型对 chosen 回答的 log 概率 ref_logps_rejected, # 参考模型对 rejected 回答的 log 概率 context_quality, # shape: (batch_size,),0~1 的可信度 beta=0.1, lambda_reject=0.5, kl_weight=0.05, ): # 当前模型相对于参考模型的奖励差 chosen_reward = (policy_logps_chosen - ref_logps_chosen) * beta rejected_reward = (policy_logps_rejected - ref_logps_rejected) * beta # 基础 DPO 损失:让模型偏向 chosen,远离 rejected dpo_loss = -F.logsigmoid(chosen_reward - rejected_reward) # 当前模型与参考模型的 KL 散度约束,防止策略偏移过大 kl_loss = F.kl_div( policy_logps_chosen, ref_logps_chosen, reduction="none", log_target=True, ).mean(dim=-1) # 选择性加权:高可信样本上强化 DPO 损失 # 低可信样本上强化“拒绝损失” # 这里用一个简单的加权策略:可信度越高,越偏向 DPO;可信度越低,越偏向拒绝行为。 dpo_weight = context_quality reject_weight = (1.0 - context_quality) * lambda_reject loss = (dpo_weight * dpo_loss).mean() + (reject_weight * dpo_loss).mean() loss = loss + kl_weight * (kl_loss * context_quality).mean() return loss这段代码的核心在于context_quality同时控制了两件事:一是高可信样本上模型应该学习“遵循上下文正确回答”;二是低可信样本上模型应该学习“拒绝错误上下文”。虽然真实论文里的损失函数会复杂很多,但理解这个加权逻辑就能把握整个方法的精髓。
5.4 一个最小训练循环示意
为了不让读者迷失在大型框架里,这里提供一个训练循环骨架。它不直接跑通所有依赖,但能表达完整流程:
import torch from transformers import AutoModelForCausalLM, AutoTokenizer def build_inputs(tokenizer, context, question, answer): # 将 context、question、answer 拼成模型输入 prompt = f"上下文:{context}\n问题:{question}\n" full_text = prompt + f"回答:{answer}" return prompt, full_text def compute_logps(model, tokenizer, prompt, answer, device): prompt_ids = tokenizer.encode(prompt, return_tensors="pt").to(device) answer_ids = tokenizer.encode(answer, return_tensors="pt").to(device) input_ids = torch.cat([prompt_ids, answer_ids], dim=-1) with torch.no_grad(): outputs = model(input_ids=input_ids, labels=input_ids) # 简化处理:用整个序列的交叉熵近似 log 概率 return -outputs.loss # 以上为骨架示例,实际训练还需要维护参考模型的 EMA 或固定副本真实项目中,建议直接基于成熟的 DPO 训练代码框架来改造,把context_quality作为额外字段传入损失函数即可。这样能大幅降低工程成本。
5.5 评估脚本
训练之后,需要对“选择性信任”做定向验证。最常见的方式是构建两组测试样本:
- 高可信组:上下文来自真实资料,模型应该给出基于上下文的正确答案。
- 低可信组:上下文包含错误或不可信信息,模型应该拒绝或表达不确定性。
可以用下面的伪代码统计两类指标:
def evaluate_trust_behavior(model, tokenizer, eval_samples): high_follow = 0 # 高可信样本中正确遵循上下文的比例 high_total = 0 low_reject = 0 # 低可信样本中合理拒绝的比例 low_total = 0 for sample in eval_samples: prompt, _ = build_inputs(tokenizer, sample["context"], sample["question"], "") output = model_generate(model, tokenizer, prompt, max_new_tokens=64) quality = sample["context_quality"] if quality >= 0.6: high_total += 1 if sample["expected_behavior"] == "follow" and is_similar(output, sample["expected_answer"]): high_follow += 1 else: low_total += 1 if sample["expected_behavior"] == "reject" and contains_refusal(output): low_reject += 1 return { "high_quality_follow_rate": high_follow / max(high_total, 1), "low_quality_reject_rate": low_reject / max(low_total, 1), }这里的is_similar和contains_refusal可以先用关键词匹配或简单语义相似度实现。关键是:不要只看传统的“问答正确率”,要分别统计“可信时是否跟随”和“不可信时是否拒绝”两个维度。如果模型两条指标都达到合理水平,说明它确实学到了选择性信任。
6. 运行结果与效果验证
6.1 离线评估维度
训练完成后,建议从以下维度看效果:
第一是“高可信跟随率”。在上下文信息充足且正确的场景中,模型应该比训练前更稳定地给出基于上下文的回答。如果这一指标反而下降,说明选择性训练可能过度压制了模型对上下文的利用。
第二是“低可信拒绝率”。在上下文信息冲突、明显过时或来源不可靠的场景中,模型应该出现更多“无法确认”“资料不足”“建议核实”之类的输出。这是验证 Selective Context 效果的核心指标。
第三是通用能力保持度。用一份不依赖上下文的通用评测集,观察模型在开放域问答、常识、代码等任务上是否退化。偏好优化类方法最常见的副作用是“为了对齐丢掉了基础能力”,选择性训练不应该更差。
6.2 人工抽查是关键
自动指标只能说明趋势,真实体验必须靠人工抽查。建议准备一组“对抗样例”,比如:
- 上下文 A 说答案是 X,上下文 B 说答案是 Y,模型应指出冲突而不是强行给一个答案。
- 上下文中包含一段看似权威但实际错误的信息,模型能不能识别底层矛盾。
- 上下文完全无关,模型会不会胡编。
你会发现,很多模型在自动指标上表现不错,但遇到这种人为构造的冲突时就会现出原形。
6.3 判断训练成功的基本标准
一个健康的选择性上下文模型,行为上应该呈现出明显的“条件化”:
- 同样的一个问题,在高可信上下文下给出具体答案,在低可信上下文下给出拒绝或不置可否。
- 训练后,模型对上下文质量的敏感度应显著高于训练前。
- 模型的拒绝并不是笼统的“我不会”,而是明确说明“当前资料不足”或“资料之间存在冲突”。
如果模型在低可信上下文下仍然给出看似自信的完整回答,说明选择性训练没有真正生效。
6.4 训练失败时先看哪里
如果效果不理想,按以下顺序排查:
- 训练数据中 context_quality 标签是否可靠,有没有大量错误的强标签。
- 低可信样本中 chosen 回答是否真的比 rejected 回答更好。
- 显存或 batch 大小是否导致梯度更新噪声过大。
- KL 正则是否过强,导致模型几乎没学到新行为。
- 参考模型是否保持固定,这是 DPO 类方法的常见坑。
7. 常见问题与排查思路
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 高可信上下文下模型仍然不跟随 | 训练数据中高可信样本不足或标签噪声过大 | 检查高可信样本占比与标注一致性 | 增加高可信样本,提高该部分样本权重 |
| 低可信上下文下模型依然采信错误信息 | 低可信样本的拒绝回答质量不高,模型学不到“拒绝”的信号 | 人工检查低可信样本的 chosen/rejected 对 | 重写拒绝回答,让 chosen 更自然具体 |
| 训练后通用能力明显下降 | KL 正则太弱,或训练步数过长 | 对比参考模型在通用评测集上的分数 | 增大 kl_weight,早停,或减小学习率 |
| 模型在冲突上下文下给出自信答案 | 训练数据缺少“多文档冲突”类样本 | 在测试集中加入冲突样本验证 | 构造冲突上下文训练样本,教模型指出冲突 |
| context_quality 标签质量不稳定 | 规则或模型打分器本身准确率有限 | 抽样校验打分结果 | 引入人工标注,或采用多模型投票方式 |
| 损失在训练后期震荡 | batch 内 quality 分布不均匀 | 打印每个 batch 的 quality 分布 | 按 quality 分组采样,保证每个 batch 包含两类样本 |
| 训练后模型过于保守,到处拒绝 | 低可信样本权重过高 | 检查 reject_weight 参数 | 降低权重,或把权重改成随训练步数衰减 |
实际项目中,最大的坑往往不是模型结构,而是训练数据中的“虚假拒绝”。如果你把低可信样本的拒绝回答写得太生硬,模型会学会一种通用的“我不确定”话术,在需要它给出答案时也闪烁其词。所以低可信样本的 chosen 回答一定要在表达不确定性的同时,尽量给出下一步建议,比如“建议查看官方文档”“建议确认数据来源”,这样模型学到的是“引导用户核实”,而不是“回避问题”。
8. 最佳实践与工程建议
8.1 从弱标签起步,不要一开始就追求完美
很多团队会在上下文质量评估上投入过多时间,总想用 99% 准确的评判模型。但偏好优化对标签噪声有一定容忍度。建议先用规则快速生成一批弱标签,跑通整个训练流水线,再看失败样本,逐步迭代标签质量。先让框架跑起来,比一开始就做精确评估更重要。
8.2 评测集必须有“冲突对”
在评估集中加入至少三类样本:
- 高可信且答案正确。
- 低可信但表面可信。
- 两个上下文互相信冲突。
第三种最容易暴露模型的真实能力。如果模型能在冲突信息中指出“资料之间存在矛盾”,说明它已经在做适当的信任判断,而不只是记住“拒绝话术”。
8.3 与 RAG 管线结合时,分清各层职责
在 RAG 系统里,检索层负责提高召回精度,重排层负责过滤明显噪声,而 Selective Context Preference Optimization 负责让生成层具备抗误导能力。不要期待只靠训练解决所有上游问题。检索阶段的强过滤依然必要,因为不管模型多会拒绝,从源头减少错误信息进入上下文,永远是最经济的手段。
8.4 安全边界:选择性信任不能替代安全过滤
低可信上下文里可能包含提示注入、钓鱼信息或恶意指令。模型即使学会了“不信任”这些上下文,也未必能完全防御恶意攻击。生产环境必须保留独立的输入过滤、来源白名单、人工审计等机制。选择性信任是一种增强,而不是兜底。
8.5 版本管理与回滚
如果你在业务模型上做 Selective Context Preference Optimization,建议保留训练前的模型权重和评估记录。每次训练后先跑 A/B 测试,观察“高可信跟随率”和“低可信拒绝率”是否同步改善,再灰度放量。遇到线上反馈变差,优先回滚到训练前版本,并检查训练数据中的标签分布是否出现偏差。
9. 总结与后续学习方向
这篇文章围绕“Learning When to Trust via Selective Context Preference Optimization”梳理了一个核心观点:模型处理上下文的能力,不应该只在推理阶段靠规则和提示来补救,而应该在偏好优化阶段就建立“选择性信任”的机制。它把上下文可信度当作训练信号的一部分,让模型学会在可信上下文中遵循证据,在不可信上下文中拒绝或指出不确定性。
如果你正在做 RAG 或长上下文应用,可以先造一个包含“高可信”和“低可信”样本的最小评估集,测一下当前模型在两类样本上的表现差异。你会发现,很多模型其实根本没有学会“不信任”这个动作。然后可以按本文第 5 节的流程,改造一份 DPO 训练代码,加入 context_quality 加权逻辑,跑一个小规模实验,看看损失和评估指标如何变化。
更深入的方向包括:如何用评判模型自动生成高质量的上下文可信度标签、如何在多文档冲突场景下做更细粒度的证据溯源、如何把“选择性信任”和推理时的解码策略结合。这些方向都值得继续探索,但前提是先理解今天这个最基本的问题:模型不是需要更多上下文,而是需要知道什么时候该信任它。