你的约束怎么写的?模型怎么知道它只能用你传进去的文档,不能用自己的知识
P1 · rag · 🏢 京东
🏷 标签:rag, prompt-engineering, constraint, citation, hallucination
1️⃣ 考察意图
面试官想看你是否理解RAG中“约束”不是一句软话,而是一套可执行的机制。考察类型是工程取舍+系统设计。刁钻点在于:候选人往往只写“请参考文档”,但模型本质是概率生成,没有硬性“禁止使用知识”的开关。答好了能展示你对prompt工程、引用强制、解码策略的底层理解,以及如何用系统级设计(如约束解码、输出验证)把“软约束”变成“硬约束”。
2️⃣ 标准答
核心思路:约束不是靠“请求”,而是靠“强制”。模型没有“禁用知识”的开关,但可以通过以下三层机制,让模型不得不依赖文档。
第一层:Prompt工程——用“引用”锁死输出
- 强约束语句:必须用强制性动词,如“你只能使用参考文档中明确提到的信息。如果文档未提及,必须回答‘根据提供文档,无法回答该问题’。禁止使用你预训练的知识。”
- 引用格式强制:要求模型在每句回答后标注来源,如
[来源:文档名称-段落X]。这迫使模型在生成时先定位原文,否则无法生成引用。 - 对比弱约束:弱约束(“请参考以上文档”)的幻觉率在通用测试中可达30%+,而强约束+引用强制可降至5%以下【通用知识】。
- 工程取舍:引用强制会增加token消耗(约20-30%),且对长文档的定位精度要求高。但这是用成本换忠实度,在金融、医疗等场景值得。
第二层:解码策略——用“logit屏蔽”做硬约束
- 原理:在模型生成时,动态屏蔽那些与文档内容无关的token。例如,如果文档只提到“苹果公司”,模型生成“香蕉”的概率应被压低。
- 实现:使用约束解码(如
guidance库或outlines库),定义输出格式为“只能从文档中抽取句子”。具体做法:将文档切分为chunk,生成时只允许模型从这些chunk的token集合中采样。 - 实际落地的坑:约束解码会显著降低生成速度(约2-3倍),且对长文档(>10k tokens)的chunk索引构建有内存压力。解法:只对关键事实性输出(如实体、数字)做约束,对流畅性部分(如连接词)放开。
第三层:系统设计——用“验证-重试”完整流程
- 输出验证:在模型输出后,用NLI模型(如
DeBERTa-v3微调的忠实度分类器)或规则引擎(检查引用是否真实存在)做后处理。 - 重试机制:如果验证失败(如引用不存在或内容矛盾),则不返回结果,而是重新生成或返回“无法回答”。
- 工程取舍:验证会增加延迟(约100-200ms),但能拦截90%以上的幻觉。关键:验证阈值要调优,过高会导致拒答率上升(如从5%升到15%),需根据业务容忍度平衡。
总结:模型“知道”自己只能用文档,是因为你通过prompt强制引用、解码屏蔽无关token、验证重试完整流程,让它不得不这么做。单靠一句“请参考文档”是无效的。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,Prompt工程层面,用‘只能使用文档信息’的强约束语句,并强制模型标注引用来源,迫使其先定位原文;第二,解码策略层面,用约束解码屏蔽与文档无关的token,从生成源头限制;第三,系统设计层面,用NLI模型验证输出忠实度,失败则重试或拒答。总结一句:约束不是靠请求,而是靠引用强制、解码屏蔽、验证完整流程这三层机制,让模型不得不依赖文档。”
4️⃣ 高频追问 & 应对
追问 1:如果用户问“文档里没有的信息,但你知道答案,你怎么处理?”
应对策略:这是测试你对“拒答”的理解。标准做法是:强制返回“根据提供文档,无法回答该问题”,并给出建议(如“请补充相关文档”)。但要注意:如果模型预训练知识很强(如GPT-4),它可能“忍不住”回答。解法:在prompt中加“如果模型使用预训练知识,将受到惩罚”的元指令,或使用logit抑制,将“我知道”类token的概率压低。实际项目中,我们曾遇到模型在拒答后仍输出“但根据常识……”,后通过输出后处理(正则匹配“但”“不过”等转折词)拦截。
追问 2:如果文档内容有矛盾,模型怎么处理?
应对策略:这是测试你对冲突消解的理解。做法:在prompt中指定优先级规则,如“如果文档间有矛盾,以最新文档为准”或“以权威来源为准”。工程实现:在检索阶段,对文档打时间戳或权威度标签,生成时只允许模型引用最高优先级的文档。坑:模型可能自行“调和”矛盾(如“A说X,B说Y,所以可能是Z”),这属于幻觉。解法:在prompt中明确“禁止自行推断,只陈述文档原文”。
追问 3:约束解码在长文档场景下性能太差,你怎么优化?
应对策略:这是测试工程取舍。解法:分而治之——只对关键事实(如实体、数字、日期)做约束解码,对非关键部分(如连接词、修饰语)放开。具体:用NER模型先提取文档中的实体,生成时只屏蔽这些实体之外的token。trade-off:这会增加NER步骤的延迟(约50ms),但能减少约束解码的搜索空间(从全词表降到实体集),整体速度提升2-3倍。另一个方案:用KV-cache预计算,对文档的chunk提前计算注意力,生成时只允许模型访问这些chunk的KV-cache。
5️⃣ 避坑 · 常见错误答法
- ❌ 说“在prompt里写‘请参考以上文档’就行” → ✅ 正确切入:必须用“只能”“必须”“禁止”等强制性动词,并配合引用格式,否则模型会忽略。
- ❌ 说“模型有内置的‘只使用文档’开关” → ✅ 正确切入:模型没有这种开关,必须通过prompt工程、解码策略、系统设计三层机制实现。
- ❌ 说“用RAG就自动不会用知识了” → ✅ 正确切入:RAG只是检索+生成,模型仍会混合预训练知识,必须用约束强制。
6️⃣ 简历呼应
- 如果你有RAG项目:从“我在XX项目中,通过引用强制+输出验证,将忠实度从70%提升到95%”切入,展示你踩过“模型自行推断”的坑。
- 如果你只做过传统NLP:用“类比:就像文本分类任务中,用logit屏蔽非法类别一样,RAG中也要屏蔽与文档无关的token”迁移,展示你对解码策略的理解。
- 如果你是校招无项目:聚焦“我复现过约束解码(guidance库)的demo,对比了弱约束和强约束的幻觉率差异”,展示你对前沿技术的动手能力。
- 《RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture》
- 《Faithful Reasoning Using Large Language Models》—— 引用强制方法
- 《Guidance: A Guidance Language for Controlling Large Language Models》—— 约束解码库
- 《DeBERTa: Decoding-enhanced BERT with Disentangled Attention》—— NLI验证模型
- 《Lost in the Middle: How Language Models Use Long Contexts》—— 长文档约束挑战