跳到主要内容

当代码胜过模型:用确定性逻辑替换 LLM 调用的决策框架

· 阅读需 9 分钟
Tian Pan
Software Engineer

大多数 AI 工程团队都有着相同的故事。他们从一个真正需要 LLM 的难题开始。然后,一旦 LLM 基础设施到位,每一个新问题在他们眼中都成了那把锤子下的钉子。六个月后,他们甚至在调用 GPT-4o 来检查电子邮件地址是否包含 “@” 符号 —— 并且还在为此付费。

这种 “直接用模型” 的本能反应现在是 AI 应用中不必要的复杂性、虚高成本和脆弱生产系统的主要驱动力。这并不是因为工程师们粗心大意。而是因为 LLM 确实令人印象深刻,工具链降低了使用门槛,而且一旦你构建了 LLM 流水线,增加另一次调用感觉成本极低。事实并非如此。

这篇文章是一个打破这种反射动作的决策框架。这并不是要拒绝 LLM —— 它们解决了确定性代码无法解决的真实问题。而是在每次调用 LLM 之前,提供一种严谨的方法来询问正确的问题:这项任务真的需要模型吗?

驱动复杂性的隐性假设

LLM 擅长处理模糊性、跨大型上下文综合信息,以及生成难以提前精确定义的输出。这涵盖了工程问题中很有意义的一部分。

但还有更大一类任务,其问题定义明确,输出空间有限,所需的 “智能” 相当于针对已知规则的模式匹配。这些任务不需要 LLM。它们需要的是运行时间以微秒计、单次调用成本为零且永远不会产生幻觉的代码。

工程师们持有的隐性假设是:任何涉及语言的任务都会自动归入 LLM 类别。这混淆了两个本质上不同的事物:涉及文本的任务和需要语义理解的任务。检查字符串是否符合日期格式涉及文本。总结医疗文件需要语义理解。前者是正则表达式(regex)。后者可能需要模型。

当你把每一个文本处理任务都视为 LLM 调用的候选对象时,你创建的系统在应该快速的地方变得缓慢,在应该免费的地方变得昂贵,在应该可审计的地方变得晦涩。

四个问题的决策框架

在每次调用 LLM 之前,请问自己这四个问题。如果你对所有问题的回答都是 “是”,那么请跳过 LLM。

你是否可以精确指定输出空间? 如果有效的输出构成了一个有限的、可枚举的集合 —— 类别、标签、布尔决策、具有已知格式的提取字段 —— 那么该问题本质上是确定性的。基于规则的分类器或查找表比 LLM 更可靠,因为它不会产生你定义集合之外的输出。

准确性是否要求零模糊容忍度? LLM 是概率性的。对于相同的输入,它们在不同调用中可能会产生不同的输出。如果你的下游系统依赖于精确、可重现的输出 —— 合规检查、定价逻辑、权限关口 —— 确定性代码可以消除一整类故障模式。据记录,在困难的评估任务中,以 LLM 作为裁判(LLM-as-judge)系统的错误率在 21–46% 之间。而一条规定 “如果字段 X 存在且字段 Y 为空,则标记该记录” 的规则,其错误率为零。

输入模式是否有限且可枚举? 如果输入遵循已知结构或属于一组封闭的变体,那么该结构本身就是解决方案。检测货币符号、验证电话号码格式、从日志行中提取版本字符串 —— 这些都是模式问题。正则表达式可以可靠地处理它们,即时运行,且不需要 API 密钥。

在这种业务量下,LLM 调用的成本或延迟是否不可接受? 根据模型的不同,单次 LLM 调用的成本在 0.001 美元到 0.01 美元之间。如果一项任务查找表就能搞定,而每天进行 100,000 次调用,那么每年就会产生 36,500 到 365,000 美元本可避免的支出。在每秒 10 次调用的情况下,即使是 300ms 的 LLM 响应时间也会导致不可接受的队列深度。模型延迟并不是恒定的 —— 它在负载下会恶化。

确定性逻辑几乎总是胜出的场景

从已知格式中进行结构化提取。 解析日期、URL、电子邮件地址、IP 地址、货币金额和版本字符串。这些格式都有规范。实现规范的代码比模拟规范的模型既快又准。

实体查找和分类。 识别字符串是否匹配已知列表中的项 —— 产品名称、国家代码、错误代码、品牌名称。Trie 树和哈希表可以在 O(1) 时间内以完美的召回率完成此操作。LLM 既引入了延迟,又引入了误报(产生幻觉的匹配)和漏报(由于分词原因错过)的可能性。

路由和守门。 根据输入特征决定是否调用 LLM。如果请求来自免费层用户,如果输入少于 50 个 token,如果查询匹配缓存模板 —— 这些都是确定性的决策。使用 LLM 来做出路由决策,会为原本想要避免调用的请求增加延迟和成本。

验证和合规性检查。 文档是否包含必填字段,配置值是否在允许范围内,交易是否匹配已知的欺诈模式。这些都需要可审计性。LLM 产生的是难以向监管机构解释的概率性决策。基于规则的系统产生的是具有明确审计轨迹的确定性决策。

小标签集的高频分类。 支持工单的情感分析(积极/消极/中性)、使用已知信号的垃圾邮件检测、针对固定用户意图集的意图分类。对于大规模的封闭标签分类,受限生成架构或微调的小型模型在延迟和成本降低 5–10 倍的情况下,始终能达到 LLM 级别的准确度。

LLM 在何处才是真正必要的

这个框架的核心在于增加约束,而不是全面取代 LLM。在某些任务中,确定性代码确实无法替代。

开放式生成——即生成散文、代码、结构化文档或需要跨大上下文综合信息的回复——需要模型。其输出空间是无法预先指定的。

对非结构化输入进行推理——从自由文本中提取关系、从模糊表述中推断意图、对相关内容各异的文档进行摘要——需要规则无法编码的语义理解。

处理长尾场景——即你在编写规则时未预料到的情况。一个设计良好的系统会将 LLM 作为兜底方案,用于处理超出确定性处理器范围的输入,而不是将其作为应对一切的第一道防线。

实际的架构是一个漏斗:确定性的预处理和路由,仅针对那些通过了确定性阶段但未得到解决输出的输入调用 LLM,最后对 LLM 的输出进行确定性的后处理和校验。这种结构将 LLM 视为处理真正棘手案例的精密仪器,而不是代码的通用替代品。

校验陷阱

一个常被忽视的、表明你过度依赖 LLM 的信号是:你在调用 LLM 后添加了一个校验层。

如果你的流水线看起来像“调用 LLM,然后运行正则来检查输出是否有效,如果无效则重试”,那你其实已经承认了 LLM 是错误的工具。你不仅在为 LLM 推理付费,还在为延迟和复杂度付费,而验证输出所用的确定性逻辑,本可以直接生成正确的答案。

这种模式在结构化提取任务中很常见。团队使用 LLM 从文本字段中提取(例如)日期,然后用解析器验证提取的日期,如果解析器拒绝,则重试。这种重试循环证明了提取工作本可以由解析器更可靠地直接处理,或者配合一个用于隔离相关文本的预处理步骤。

当你发现自己在为 LLM 输出编写校验代码时,请以此为契机去思考,校验逻辑本身是否才是真正的解决方案。

让本能反应为你所用

我们的目标并不是从原则上减少 LLM 的使用,而是要确保每一次 LLM 调用所做的工作都对得起它的成本和延迟。这意味着要养成一种习惯,针对每一项新任务去识别:最简单的正确解决方案是什么?

从问题受限最严重的版本开始。查表能处理常见情况吗?正则能处理这种模式吗?一小组规则能覆盖 90% 的输入吗?如果是,请先实现这些。LLM 则作为剩余 10% 的处理器——即那些确定性逻辑无法解决的、真正模糊且高熵的情况。

这会在所有重要的生产指标上产生一个明显更好的系统:单次请求成本、p99 延迟、错误率以及可解释性。它还会产生更整洁的代码。一条写着“如果输入匹配此模式,则返回此标签”的规则,比一条写着“对输入进行分类”的提示词更容易调试、测试和更新。

“直接用模型就好”的本能反应在短期内感觉很高效。但在生产环境中构建最稳健 AI 系统的团队,往往是那些将 LLM 调用视为昂贵操作的团队——只有在穷尽更简单的替代方案后才会动用它,而不是将其作为处理每个文本问题的默认起点。

References:Let's stay in touch and Follow me for more thoughts and updates