返回博客

正则与 LLM 的边界:结构化文本解析的分层策略

最近在做一个批量文档解析的需求,目标是从大量格式重复的结构化文本里提取字段——题号、选项、答案之类。最直觉的想法是直接上大模型:输入原文,输出 JSON,干净利落。

但我停下来想了一下:这类文本的格式其实相当固定,变化点只在少数边缘情况。如果每条都打给 LLM,不只是成本问题,还有延迟、不确定性、难以测试。正则在这里明显被低估了。

从比例开始想问题

关键的第一步是估算「格式合规率」:这批文本有多大比例严格遵循固定模式?

如果答案是 90% 以上,那正则就是主力工具,LLM 只需要做兜底。如果文本是真正的自由格式——用户填写的评论、邮件正文、口语化描述——那直接上 LLM 才合理,因为根本没有稳定的模式可抓。

这不是一个「正则好还是 LLM 好」的宗教问题,而是一个比例判断:在这个场景里,确定性的工具能覆盖多少,模糊处理工具才需要接手多少。

实际跑下来的数据印证了这个判断:对于格式规整的结构化文档,正则的命中率通常在 95%~98%,真正需要 LLM 介入的只有个位数百分比的边缘案例。成本节省接近 95%,准确率没有明显损失。

置信度分层:把「不确定」显式化

正则解析的问题不是它处理不了复杂情况,而是它的失败方式是「静默的」——要么匹配不到,要么匹配到了但结果是错的,调用方不知道该不该信。

解决办法是加一层置信度评分,把正则解析的结果标注一个可信程度:

  • 选项数量不足时降分
  • 答案字段缺失时降分
  • 题目文本过短(可能是截断)时降分

低于阈值的条目,不是丢掉,而是转交给 LLM 二次验证。高置信度的直接输出,不走 LLM 这条路。

这个「置信度分层」的思路让我觉得很有价值:它把「不确定」从隐式状态变成了一个可以程序化处理的显式信号。整条 pipeline 知道自己对哪些输出有把握,对哪些没把握,然后对没把握的那部分采取不同的处理策略。

不确定性要显式化,不要埋掉

如果一个解析步骤可能失败,与其让调用方猜测输出是否可信,不如在数据结构里加一个 confidence 字段把置信度带出来。消费方可以根据它决定是否降级处理,而不是盲目信任结果。

LLM 作为「专家会诊」而非「流水线工人」

这个分层模式改变了 LLM 在 pipeline 里的角色定位:它不再是每条数据都要经手的流水线工人,而是只处理「正则拿不准」的那批案例的专家会诊。

这个定位对选模型也有启发。做二次验证这件事,并不需要最强的模型——上下文是有限的、任务是明确的(判断现有解析是否正确,必要时给出修正)。用轻量级的模型就够了,成本又降一个台阶。

更重要的是,这个角色分配对系统的可测试性有很大帮助。正则层是纯函数,输入确定,输出确定,覆盖典型模式和边缘案例的单元测试非常容易写。LLM 层的输入只是少量的低置信度样本,测试范围被大幅收窄了。

从「能不能用正则」到「正则覆盖到哪里」

我现在处理结构化文本解析时的默认顺序是:先用正则建立基线,记录实际命中率,再根据命中率决定要不要加 LLM 层。不是跳过正则直接上 LLM,也不是只用正则然后忽视失败案例。

这个顺序的好处是:正则层让你快速得到一个可观测的基线,你能看到失败在哪里、失败的比例是多少,这些信息才是决定下一步做什么的依据。

「先有基线,再有判断」——这条原则在很多工程场景里都适用,不只是文本解析。

一句话心法

正则不是 LLM 的对手,而是它的过滤器——让确定性工具先跑,把真正模糊的问题留给擅长模糊的工具处理。