用正则拦截LLM幻觉:构建AI内容可信度闸门 📅 发布时间:2026/9/5 21:52:50 👁 浏览次数: 我真正意识到 LLM 会用一种极其严谨的语气编故事是前阵子帮团队审核一批 AI 生成的技术文档草稿。当时为了赶进度我让模型先补全一节“常见错误排查”说明它给出的内容结构工整、前后呼应里面赫然写着一句“详见 GitHub Issue #47321 的讨论”。我去仓库里搜了半天才发现这个编号根本不存在。更有意思的是那个 Issue 的写法非常真实时间、版本号、报错现象全都自洽如果不是手动检查它就会被当成参考资料混进正式文档里。那也是我第一次认真琢磨与其反复调提示词不如在人和模型之间加一道不依赖模型自觉、可解释、成本也可控的“可信度闸门”。最后我采用的做法很朴素——根本不需要再套一个大模型来打标用几行正则就能先拦截掉一大批高风险片段把“哪些地方需要人工多看两眼”筛出来。如果你平时也会用 LLM 生成技术文档、营销文案、周报或知识库内容又不想每次都拿放大镜逐字审这套做法可以直接借走。下面我会从 LLM 为什么会出现“自我欺骗”讲起再把检测项、正则规则、Python 示例代码、实战测试和踩坑过程全部摊开。你可以把它理解成一套“内容进门前查身份证”的小工具而不是什么能消灭幻觉的银弹。1. 先别急着写正则搞清 LLM 是怎么“骗自己”的1.1 幻觉不是偶然错误而是机制的副产品大语言模型在预训练阶段做的是“根据前文预测下个 token”它没有数据库也没有事实校验器。训练目标里并没有单独一项“保证输出符合现实世界真值”它只是在海量文本中记住了大量模式。结果就是在推理阶段模型会优先输出“在统计意义上大概率出现”的句子而不是“经过验证为真”的句子。再加上解码时往往会设置一定的随机性于是同一个问题会让它生成多个版本其中某些版本就可能包含不存在的论文、假链接、错误日期或子虚乌有的用户反馈。这不是一个可以用一句“提示词让它别撒谎”就绕开的 bug因为模型在生成时根本没有“撒谎”的意图它只是在做概率抽样。说白了幻觉是这套架构的副产品而不是运行异常。你越是给它一段详细的背景它就越是会用合理的词汇把它包装得像模像样因为“伪装成权威”本身就是语料里非常常见的句式模式。1.2 连续生成时幻觉会出现“自我强化”比单条回复出幻觉更麻烦的是“LLM 开始骗自己”的现象。当模型的长上下文里已经包含了它自己之前生成的虚构信息它会把这些信息当成真实前提继续往下推理。比如让它先写一篇行业分析它编造了一个统计数字你再让它基于这篇分析生成三条行动计划它就会把那个假数字作为“已知事实”来引用继续推导出一套包装精美的建议。这种现象很像脑补闭环第一次输出的小幻觉被第二次生成当作上下文证据第三次生成时已经变成“毋庸置疑的背景”。如果你不拦在第一轮输出之后后面的内容会在这个错误地基上越砌越高。这也是为什么我坚持在内容进入下一道流程之前就做检测而不是等几句话的幻觉已经污染了整个会话再返工。1.3 提示词和知识库只能降低概率做不了闸门有些人觉得加一句“请输出真实的信息”或者接一个 RAG 知识库就能解决问题。从实际效果看这些手段有用但并不充分。提示词是软约束模型依然可能因为采样概率产生幻觉RAG 能减少编造却无法保证检索到的知识一定适配当前问题更无法阻止模型在整合材料时把不相关的内容强行拼在一起。真正可靠的做法是在“模型输出之后、内容正式使用之前”加一个外部判断环节。这个外部判断不一定要很重。对一个普通团队来说直接用另一个大模型做内容审核确实方便但成本和稳定性都让人头疼。正则的优点恰恰体现在这里它运行快、结果稳定、每一次都能解释清楚“是哪条规则、匹配到哪个片段、为什么扣分”不会像模型判断那样偶尔给出模棱两可的回答。当我需要向团队解释为什么某篇文章没有通过检查时给出一条具体命中的规则比给出一句“模型觉得有问题”要有说服力得多。2. 六类最高频的可疑信号正则应该先拦这些2.1 第一类无中生有的链接与 DOILLM 很擅长伪造“看起来真实”的链接因为它知道真实域名的常见写法。你让它举例时它可能生成https://github.com/xxx/issues/98213或https://medium.com/someone/ai-report-2025这些链接从字符结构上看没有明显问题可你一旦点开就发现所谓 issue、文章、白皮书根本不存在。正则在这里的价值不是“判断链接是否真实有效”而是把文本中所有链接和 DOI 快速抽出让它们进入“待验证”清单URL_RE re.compile(rhttps?://[^\s\“”‘’。、】》], re.IGNORECASE) DOI_RE re.compile(r10\.\d{4,9}/[-._;()/:A-Z0-9], re.IGNORECASE)匹配到之后再对尾部做一次rstrip(.,;:。)避免句子末尾的句号被吞进链接里。我第一次写 URL 规则的时候没有做尾部清洗结果所有以“https://xxx.com。”结尾的链接都带着中文句号导致我一度以为链接提取逻辑写错了。匹配完成之后还要继续做一级风险判定比如一篇普通博文里出现超过三个神秘域名、或者链接的路径里同时带有 “whitepaper-v2-final” 这类典型 AI 生成特征就需要标记为高危。2.2 第二类编号对不上的引用与参考文献学术论文摘要、技术报告和行业调研里[1]、[2]这种引用标记是 LLM 最爱伪造的。它经常会在正文里写“已有研究表明[3]”但整篇内容其实并没有参考文献列表或者有列表却只有两条正文却引用到了编号 8。在 Python 里做一个简化版检查并不复杂。先用re.findall(r\[(\d{1,3})\], text)收集所有引用编号再用re.findall(r^\s*\[(\d{1,3})\]\s*, text, re.MULTILINE)统计文末参考文献列表的条目数。如果“正文有引用编号”但“列表为空”或者“正文引用编号的最大值远大于列表条目数”就应当把相关内容标成高危。需要注意这个检测不能算绝对证据因为有些作者习惯用方括号表示步骤序号。它的作用是在内容过闸时唤起人工注意而不是直接判定一篇文章造假。也可以换一个思路不直接判定造假只输出一条“伪引用风险”的发现。真正严苛的验证还要靠 DOI API、文献数据库或搜索引擎来确认。正则负责在最小的成本里把可疑句子挑出来。2.3 第三类无源头的“信任背书”句式“研究表明”“专家指出”“业内人士普遍认为”“根据相关数据”这类表达是 AI 在没有真实来源时最喜欢用来填补信息空白的套话。它的作用是把陈述包装成有依据可实际上你往里挖根本找不到具体出处。人类作者也会这么写但在正式内容中通常会紧随其后给出机构名、文章标题或年份。我常用的检测模式是r(?:研究表明|多?项研究(?:显示|表明|指出)|专家(?:表示|认为|指出)|业内人士(?:普遍)?认为|据(?: