你的应用接了大模型,用户却总能问出它一本正经胡说八道的答案,客服和研发来回扯皮。这篇不讲原理,只给能当天动手改的东西:怎么让模型有据可依、怎么把回答框住、怎么在返回给用户之前拦一道。也会说清哪些手段在什么场景下不划算,别为了防幻觉把体验拖垮。
你的应用接了大模型,用户却总能问出它一本正经胡说八道的答案,客服和研发来回扯皮。这篇不讲原理,只给能当天动手改的东西:怎么让模型有据可依、怎么把回答框住、怎么在返回给用户之前拦一道。也会说清哪些手段在什么场景下不划算,别为了防幻觉把体验拖垮。
下面按动手顺序分四段:先解决「答什么」(检索),再解决「怎么答」(提示约束),再解决「发不发」(校验与兜底),最后是怎么复盘、以及什么时候干脆别折腾。每段都给了判断标准和具体动作,照着改就行。
先让它有据可依:检索增强的接入位置
判断一个需求适不适合走检索,看两点:答案是不是来自你手上的私有文档,用户是不是要求可溯源。两个都是,就做检索;纯创意写作、开放闲聊、头脑风暴类,硬套检索只会答得更死板,反而伤体验。
- 改写查询用户问题先改写成检索语句,别拿原句直接去搜。短句、口语、含代词的问法召回率普遍偏低,先改写再召回,可以对比改写前后召回片段的相关度。
- 召回并挂来源把命中的片段拼进上下文,每段带上来源标识(文档名加序号),后面让模型引用这些序号,方便人工和程序抽查。
- 控制片段数量与长度塞太多会稀释重点还涨成本。先按问题的宽窄做分级召回:窄问题给少量精准片段,宽问题给多点但做去重。向量库和嵌入模型怎么选,到 /stacks/vector-dbs 与 /embeddings 对照当时的资料。
- 定义降级条件召回为空或最高得分低于阈值时,别让它拿着不相关片段硬编,直接走「查不到」分支。阈值先用线上样本抽一批标一遍再定。
把回答框住:提示约束与结构化解法
- 给出「不知道」的出口:明确写没有依据就回答无法确定,否则模型默认会拼一个像样的答案出来。
- 要求引用来源编号并逐句可对:输出里带片段编号,便于抽查,而不是只给一段漂亮总结。
- 用结构化输出代替自由文本:固定字段、固定枚举、必填项校验,字段缺失直接判为失败重试。
- 约束不是越严越好:字段过多过细会让模型顾此失彼,反而在边角字段上编,先减字段再加规则。
- 把示例写进提示:给一正一反两个短例,比写一堆抽象规则管用。
这里有个顺序问题:先定输出结构,再定约束措辞。结构决定了模型必须填什么,措辞只是补充。反过来做,容易写出互相打架的长提示,模型执行得七零八落。
发出去之前拦一道:校验、置信与兜底
| 校验层 | 查什么 | 不过怎么办 |
|---|---|---|
| 格式与必填 | 字段是否齐全、枚举是否越界 | 直接重试一次,仍失败就降级 |
| 实体核对 | 关键人名、地名、编号是否出现在召回原文 | 标记为可疑,换更小范围重答 |
| 数值单位 | 数字是否越界、单位是否和原文一致 | 不展示该数值,改为引导用户查原文 |
| 口径冲突 | 和历史回答、内部规则是否矛盾 | 走人工确认,别自动发出去 |
这一层的关键是顺序:从便宜到贵。格式校验几乎不花钱,实体和数值核对要写规则或小模型,交叉检查要再调一次模型,成本翻倍。按顺序排,大部分问题在第一层就拦住了。
- 设定重试上限同一提示词重试两次还错,就停手,换成更小的回答范围,或者直接给用户暂时查不到。别无限重试烧钱。
- 按需加交叉检查关键链路可以再调一次模型,让另一个提示词只做判定不给答案。非关键链路不值得,成本翻倍还拖延迟。
- 提前写好兜底话术告诉用户答案基于哪些资料、可能不完整,并给人工入口。这比硬撑一个错答案便宜得多。
出错之后怎么复盘,以及什么情况下这套做法不适用
出了幻觉先别急着改提示,按类型归因:是召回没捞到、提示没约束住、还是模型推理本身跑偏。三类改法完全不同,召回问题要去调检索,提示问题要去改约束,推理问题往往只能换模型或缩小任务。分类口径可以到 /ai-dict/category/tips 翻当时的整理。
- 每次请求都留下输入片段与输出,做抽查样本。没有可回看的记录,任何改进都只是猜。
- 按周抽查一批线上记录,统计问题落在哪一类,别凭印象拍板。
- 幻觉率会随资料更新和模型切换变化,保持观察节奏,可以用 /tools/quality-monitor 这类工具盯变化。
- 复盘结论要落到具体改动,比如某条召回规则、某个字段校验,而不是「下次注意」。
- 改动上线后拿同一批样本回归,看有没有新的误伤。
什么情况下别硬堆校验:问题本身就没有标准答案、用户要的就是发散创意、延迟要求在毫秒级的实时场景。这几种优先做免责与预期管理,把用户预期拉正,比堆校验划算。
下一步想让检索和校验真正落地,选对模型和中转渠道是前提,去 /sites 核对当前的可用渠道、价格和可信度标注,再决定拿哪家做主力。→常见问题
检索增强是不是就能彻底解决幻觉?
不能。它能大幅减少「凭空编」的情况,但召回错了、片段本身过时、或者模型在多个片段间做了错误拼接,照样会出错。把它当成降概率的手段,配合输出校验和兜底话术一起用,同时接受一定比例的失败并设计好失败时的表现。
提示约束写多少条合适?
没有固定数字,判断标准是每条约束是否对应一个你能检查的结果。如果一条规则你没法在输出里验证它有没有被遵守,那它基本是心理安慰。建议从三到五条最关键的开始,上线后看真实错例再补,越加越多的提示词往往说明前面某条写含糊了。
怎么衡量改了之后有没有效果?
先攒一批真实问题做固定测试集,改动前后各跑一遍,人工标注哪些答案是错的,比总数的变化而不是单次观感。注意别只看准确率,也要看「拒答率」有没有飙升,过度保守同样会赶走用户。样本和口径的记录方式可到 /tools/quality-check 参考。