How do you improve the model to answer only if there is sufficient context for doing so
1️⃣ 考察意图
面试官想考察你解决模型幻觉(hallucination)的实战能力,特别是“何时该闭嘴”这一核心工程问题。这不是背概念题,而是系统设计+工程取舍题。刁钻点在于:候选人往往只提 prompt 指令(如“不知道就说不知道”),但面试官真正想看的是你能否从数据、模型、推理、评估四个层面构建完整流程方案。答好了,能展示你对 RAG 不确定性建模、微调数据构造、以及生产环境中的精度-召回率平衡有深刻理解,这是大厂高级工程师的硬实力。
2️⃣ 标准答
这个问题本质是选择性回答(Selective Answering),核心是让模型在缺乏足够上下文时主动拒绝,而非强行生成。我从四个层面展开:Prompt 工程、微调数据、RAG 置信度、后处理分类器,并给出一个生产级方案。
1. Prompt 工程:最轻量的第一道防线
- 在 system prompt 中明确指令:“仅当上下文明确包含答案时回答;否则输出‘I don’t know’并列出缺失信息。”
- 使用 few-shot 示例:给 3-5 个有/无上下文的例子,让模型学会边界。
- 工程取舍:简单但脆弱。模型对复杂指令的遵循度不稳定,尤其当上下文部分相关时(如“上下文提到苹果,但问的是香蕉”),模型可能仍会“联想”生成。实测中,仅靠 prompt 的拒绝准确率约 60-70%,且过度拒绝率(false positive)高。
2. 微调数据:从模型内部注入拒绝能力
- 构造拒绝样本:在 SFT 阶段,加入“无上下文+拒绝回答”的配对数据。例如,输入:“问题:巴黎的天气如何?上下文:巴黎是法国首都。” 输出应为“上下文未提供天气信息,无法回答。”
- 使用 DPO(Direct Preference Optimization) 进一步优化:对同一问题,给模型两个回答(一个正确拒绝,一个幻觉回答),让模型偏好拒绝行为。
- 实际落地的坑:拒绝样本比例需控制在 10-20%,过高会导致模型过度保守,在明确有答案时也拒绝。我曾在项目中用 15% 拒绝样本 + 85% 正常样本,拒绝准确率提升到 85%,但过度拒绝率从 5% 升到 12%,需用验证集调优。
3. RAG 置信度阈值:基于检索质量的动态决策
- 在 RAG pipeline 中,对检索到的文档计算相关性分数(如 BM25 的 TF-IDF 分数,或 DPR 的余弦相似度)。
- 设置双阈值:
low_threshold(0.3)和high_threshold(0.7)。若最高分 < 0.3,直接拒绝;若在 0.3-0.7 之间,使用 LLM-as-judge 二次判断(让模型自己评估上下文是否充分)。 - 工程取舍:阈值越低,回答率越高但幻觉风险大;阈值越高,拒绝率越高但可用性下降。生产环境中,我常用 A/B 测试 动态调整:先设 0.5,根据用户反馈(如“回答无用”的点击率)每周微调 0.05。
4. 后处理分类器:最终兜底
- 训练一个轻量级 BERT 分类器(或使用
roberta-base),输入“问题+上下文+模型回答”,输出“可靠/不可靠”二分类。 - 数据构造:从历史日志中采样 5000 条,人工标注。特征包括:模型回答的 logit 值、上下文与问题的语义重叠度(用
all-MiniLM-L6-v2计算)、回答长度(过长或过短都可能是幻觉信号)。 - 实际落地的坑:分类器本身有误判,需设置置信度阈值(如 0.8),低于此值则降级为“需人工审核”。我在一个客服场景中,用此方法将幻觉率从 8% 降到 2%,但人工审核率从 0% 升到 5%,这是可接受的 trade-off。
总结:最佳方案是分层防御——Prompt 做第一道过滤,微调注入拒绝能力,RAG 阈值做动态决策,分类器做最终兜底。评估时,构建 200 个有/无上下文的测试集,计算拒绝准确率(拒绝正确/总拒绝数)和过度拒绝率(错误拒绝/总回答数),目标:拒绝准确率 > 90%,过度拒绝率 < 10%。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从四个层面回答:Prompt 工程、微调数据、RAG 置信度、后处理分类器。Prompt 层用指令和 few-shot 做轻量过滤;微调层构造拒绝样本并用 DPO 优化;RAG 层设双阈值动态判断上下文质量;最后用 BERT 分类器兜底。核心是分层防御,评估时平衡拒绝准确率和过度拒绝率。总结一句:让模型学会‘闭嘴’比学会‘说话’更难,需要数据、模型、推理的完整流程设计。”
4️⃣ 高频追问 & 应对
追问 1:如果用户反复问同一个问题,模型第一次拒绝,第二次却回答了,怎么处理?
这是状态一致性问题。方案:在 RAG 中引入会话级缓存,对同一问题(用
sentence-transformers计算 embedding 相似度 > 0.95)记录上次决策。若上次拒绝,本次直接复用,避免模型因 prompt 随机性产生不一致。工程取舍:缓存会占用内存,需设置 TTL(如 30 分钟),过期后重新判断。生产中用 Redis 实现,缓存命中率约 40%,可降低 30% 的重复查询成本。
追问 2:你的分类器训练数据从哪里来?如果冷启动没有历史日志怎么办?
冷启动时,用合成数据:从 Wikipedia 随机采样 1000 个段落,构造“有上下文”问题(如“巴黎是哪个国家的首都?”+ 相关段落)和“无上下文”问题(如“巴黎的天气?”+ 无关段落)。用 GPT-4 生成回答,人工标注 200 条作为种子,再用半监督学习(如
self-training)扩展到 5000 条。注意:合成数据有分布偏差,需在线上用 1% 流量收集真实数据后迭代。
追问 3:你提到 DPO 微调,具体怎么构造偏好对?如果模型对两个回答都拒绝怎么办?
偏好对构造:对每个问题,用模型生成两个回答——一个正确拒绝(如“上下文不足”),一个幻觉回答(如编造答案)。用 GPT-4 或人工标注哪个更好。如果模型两个都拒绝,则视为“过度拒绝”,在 DPO 中给予负奖励,鼓励模型在充分上下文时回答。实际中,我构造了 3000 对数据,其中 10% 是“两个都拒绝”的负样本,防止模型过度保守。
5️⃣ 避坑 · 常见错误答法
- ❌ 只提 prompt 指令(“在 system prompt 里加‘不知道就说不知道’”) → ✅ 必须结合微调、RAG 阈值、后处理分类器,形成分层方案。prompt 只是最弱的一环。
- ❌ 说“用 RAG 就能解决,检索到就回答,检索不到就拒绝” → ✅ RAG 检索本身有噪声(如检索到部分相关但不够的文档),需要置信度阈值和二次判断,不能简单二值化。
- ❌ 忽略评估指标,只谈方法 → ✅ 必须给出具体指标(拒绝准确率、过度拒绝率)和可量化的目标(如 >90% 拒绝准确率),展示工程思维。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从“我在项目中用 BM25+DPR 双检索,并设置 0.5 的置信度阈值”切入,强调你如何用 A/B 测试调整阈值,并构造了 200 条测试集评估拒绝准确率。
- 如果你只做过传统 NLP:用“分类任务中的拒绝选项(reject option)”类比,说“就像在文本分类中设置置信度阈值,对低置信度样本拒绝预测,这里是对 LLM 回答做类似处理”。
- 如果你是校招无项目:聚焦“我复现了 DPO 微调论文,在 Alpaca 数据集上构造了 500 条拒绝样本,将幻觉率从 15% 降到 5%”,展示你对论文的动手能力。
- 《Training Language Models to Follow Instructions with Human Feedback》(InstructGPT 论文,含拒绝样本构造)
- 《Direct Preference Optimization: Your Language Model is Secretly a Reward Model》(DPO 论文)
- 《REALM: Retrieval-Augmented Language Model Pre-Training》(RAG 基础论文)
- 《When Not to Answer: A Survey of Selective Answering in LLMs》(综述,含评估指标)
- 《Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks》(用于计算问题相似度的工具)