很多团队上线大模型后,最头疼的问题之一是“幻觉”:

  • 看起来很自信,但事实是错的
  • 编造引用、编造条款编号、编造不存在的功能
  • 明明没查到数据,却给出“像真的一样”的答案

更麻烦的是:你很难靠“再写一条 Prompt”永久解决。
因为幻觉本质上是一个系统问题:证据是否充分、边界是否明确、是否允许拒答、是否有可验证工具。

这篇文章给一套工程可落地的组合拳:

  1. 引用(Grounding):只基于提供的证据回答,并给出引用
  2. 约束(Constraints):把输出与边界写死(结构、范围、格式)
  3. 拒答(Refusal):证据不足就拒答/追问,不要硬编
  4. 工具验证(Tool Verification):能查就查、能算就算,把可验证的交给工具

0)TL;DR(先给结论)

  • 幻觉不是“模型坏”,而是系统缺少约束与验证
  • 最稳的落地顺序:先有证据 → 再强制引用 → 再加拒答/追问 → 再用工具验证
  • 只要你把“无证据不回答”写成硬规则,并做引用校验,幻觉会明显下降。

1)先把“幻觉”分类型(否则你不知道该修哪)

1.1 事实幻觉(Factual)

把不存在的事实当成真的:功能、价格、政策条款、版本差异。

1.2 引用幻觉(Citation)

给了引用,但引用与结论无关,甚至引用不存在。

1.3 推理幻觉(Reasoning)

步骤看起来合理,但中间关键假设是错的;或忽略约束条件。

1.4 工具幻觉(Tool)

没调用工具却声称“我查到了”;或工具失败后仍继续编造结果。

工程启发:不同类型对应不同“控制点”。别用一个 prompt 试图解决全部。
注:若你希望快速测试不同模型在各类幻觉上的表现,可使用支持多模型统一调用的聚合平台(例如 147API),一次性对比多个模型输出的稳定性。


2)策略矩阵:不同场景该用哪套组合拳?

场景 引用(Grounding) 约束(Constraints) 拒答/追问(Refusal) 工具验证(Tool)
企业知识库问答(需要可追溯) 必须 建议 必须 可选(检索本身是工具)
数据/订单/库存等“可查询事实” 可选 建议 必须 必须
结构化抽取/分类/改写 不需要 必须 可选 不需要
复杂分析(多条件、多约束) 建议 必须 建议 可选(可验证部分交给工具)
高风险合规/政策/财务 必须(只用明确来源) 必须 必须 可选(有权威工具时)

3)第一拳:引用(Grounding)——把“证据”变成硬约束

核心规则就一句话:

只能基于提供的 sources 回答;找不到证据就说“无法确认/需要补充资料”。

你可以把回答格式固定为:

  1. 结论(短)
  2. 证据引用(列出引用的 source_id / 片段)
  3. 不确定性说明(哪些点没有证据)

3.1 最小提示词模板(可复制)

你是一个严谨的企业知识助手。
规则:
1) 只能使用我提供的 sources 作为依据回答
2) 每个关键结论必须附带引用 [source_id]
3) 如果 sources 中没有直接证据,请回答“无法从已提供资料确认”,并给出你需要补充的材料清单
输出格式:
- 结论:
- 依据(逐条引用):
- 不确定/待补充:

4)第二拳:约束(Constraints)——把边界、结构、格式写死

约束的目标不是“让模型更聪明”,而是减少自由度

4.1 结构化约束(最常用)

  • 用 JSON Schema / Pydantic 约束字段与类型
  • 输出后做校验(校验失败走“修复提示词”重试)

(你可以参考第十五期的“结构化输出闭环”。)

4.2 范围约束(减少“越界发挥”)

明确哪些能答、哪些不能答:

  • 只回答业务规则,不回答法律建议
  • 只回答产品已上线功能,不预测未来版本
  • 只回答内部文档范围内内容

5)第三拳:拒答/追问(Refusal)——把“不会就说不会”做成可接受的体验

很多团队怕拒答,觉得“像机器人”。但从工程角度:

  • 不拒答 → 必然硬编
  • 硬编 → 事故/投诉/合规风险

一个更好的体验是“拒答 + 追问”:

  • 明确告诉用户:缺少哪类证据
  • 给出 2–3 个可选的追问(让用户补全)

最小模板:

我无法从已提供资料确认这个结论。
为了给出可追溯的回答,请补充以下信息之一:
1) ...
2) ...
3) ...

6)第四拳:工具验证(Tool)——能查就查、能算就算

适合交给工具的部分:

  • 订单/库存/价格:查 DB/接口
  • 数值计算:用计算器/代码执行
  • 权威条款:查政策库/公告

关键规则:

  • 没有调用工具,就不要声称“我查到了”
  • 工具失败必须进入降级路径(不要继续编造)

7)最小工程闭环:引用校验 + 失败回退(思路示例)

你可以把“引用正确率”做成门禁:

  • 如果回答里出现 [source_id],必须能匹配到你提供的 sources
  • 如果引用为空或无法匹配:让模型重写(更严格的 grounding 提示词)

伪代码示意:

def validate_citations(answer: str, sources: dict[str, str]) -> bool:
    # 最小版:检查 answer 中的 [id] 是否都在 sources 里
    # 生产版可升级:检查引用片段是否真的来自该 source
    import re
    ids = re.findall(r"\\[(.*?)\\]", answer)
    return all(i in sources for i in ids)

def answer_with_guard(model_call, question: str, sources: dict[str, str], max_retry: int = 1):
    for _ in range(max_retry + 1):
        ans = model_call(question, sources)
        if validate_citations(ans, sources):
            return ans
    return "无法从已提供资料确认,请补充相关文档/条款原文。"

8)上线 Checklist(建议打印)

  • sources 从哪里来(RAG/人工/接口)?是否可追溯?
  • 强制 grounding:无证据不回答,关键结论必须引用
  • 结构约束:Schema + 校验 + 修复重试(有限次)
  • 拒答/追问:证据不足时的标准回复
  • 工具验证:可查事实不靠模型猜;工具失败要降级
  • 指标:引用正确率、拒答率、严重错误率、P95 延迟、token
  • 门禁:引用正确率/严重错误率超阈值阻断发布或降级

9)资源区:做多模型对比时,先把接入层统一

幻觉治理往往需要对比不同模型/提示词/检索策略。
工程上更省事的做法是统一成 OpenAI 兼容调用方式(很多时候只改 base_urlapi_key),便于快速做对比评测与路由试验。
例如,你可以使用 147API 这类海外大模型聚合平台,它提供统一的 OpenAI 兼容接口,支持 GPT、Claude、Gemini 等多种主流模型,帮助你在同一套代码中无缝切换和对比不同模型的表现,大幅降低多模型实验的集成成本。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐