LLM并非在「计算」,而是在做概率建模的文本补全——这解释了为何它能写出正确代码却算错简单加减法,以及如何通过外部工具规避这一缺陷。
你可能经历过这样的时刻:你向 AI 提一个数学问题,它把步骤讲得头头是道,像个耐心的家教一样解释逻辑,每一步都从容不迫——然后给出的最终答案就是……错了。不是大错特错的那种,通常只是自信地、看似合理地、微妙地错了。这种错误你甚至可能根本发现不了。
这看起来很荒谬。一个能写出可用代码、解释量子物理、起草法律论点、推理真正难题的东西,怎么会在 1975 年花两美元买来的计算器都能做对的算术上翻车呢?
直觉会认为模型"就是不擅长数学"——下一个版本就会弥补这个差距。但事实并非如此。真相更有意思:AI 在"解"数学题时做的事,和你想象中它做的事完全不是一回事。它根本就不是在计算。
一旦你看清底层实际发生了什么,错误就不再神秘,而是完全可以预测的——而且至关重要的是,很容易绕过。下面我们来拆解这个问题,不需要数学学位。
核心思想:LLM 不计算——它预测
这是你需要理解的最重要的一件事,本文其他内容都由此展开。
当你在计算器上输入 4827 × 391 = 时,计算器执行的是一条规则。它运行一套精确的、确定性的乘法算法——每次都相同的步骤——然后返回唯一正确的答案。它不是在"思考",而是在计算。同一输入执行一百万次,你会得到一百万次相同的输出,这是有保障的。
LLM 根本不是这样运作的。它不计算任何东西。归根结底,它只做一件事:基于从海量训练数据中吸收的统计模式,预测下一个最可能出现的文本片段。
所以当你向它提数学问题时,它不是在做乘法。它实际上是在问自己:"给定这个字符序列,什么文本最可能跟在后面?"——这和它补全"The capital of France is ___"时用的同一套流程。它是在用模式匹配出一个看起来像是接在数学问题后面的答案,而不是通过计算得出答案。
对于语言来说,这确实是奇迹般的表现。对于数学来说,这是一个根本性的错配。原因如下,一句话概括:
语言是统计的。数学是精确的。
在写作中,"差不多"不仅可接受——这就是语言运作的方式。大多数句子可以用几个不同的词来合理地收尾,换一个稍有不同的词仍然能产出通顺正确的句子。这里有灵活性、容忍度、弹性空间。
算术则完全没有这些。4827 × 391 的正确答案只有一个,接近正确毫无意义。1,887,357 是对的;1,887,000 和 42 的"错误程度"是一样的。一个被优化来生成最可能出现的延续文本的系统,它玩的游戏内置了容差——然后被一个零容差的科目评分。
这就是 LLM 能完美解释如何解题但给出错误答案的深层原因。解释方法是语言任务——是用文字描述一种熟悉的模式,模型非常擅长这个。执行计算则根本不是语言任务。模型能流利地描述数学,却无法做数学。就像一个人能完美背诵骑自行车的方法,但一上车就摔倒。
原因二:分词器把数字搅乱了
还有第二个更隐蔽的罪魁祸首——如果你读过之前我写的那篇关于 token 工作原理的文章,这里会瞬间理解。如果没读过,我来简要说明一下。
在模型"看到"你的文本之前,文本会被切分成 token——模型视为不可分割单元的片段。对于单词来说,这运作得很好。对于数字,它悄悄破坏了一切。
问题在于:模型看到的不是 87439 这个值——八万七千四百三十九。它看到的是一个或多个任意的 token——可能是 874 和 39,可能是 8 + 743 + 9,完全取决于这个特定的分词器恰好如何切分。关键在于:对模型来说,那个 token 只是词表中的一个 ID。一个数字片段的 token 和"apple"或"idea"的 token 在本质上没有区别。它是一个符号。它不携带任何内置的数量感、位值感,不知道哪个数字在十位而哪个在千位。
想一想算术实际上需要什么。手算乘法或加法,完全依赖位置结构:你把个位、十位、百位对齐;从一列向下一列进位 1;每个数字的位置就是全部关键。这恰恰是分词所抹去的结构。模型被要求做基于列的数学运算,但数字的列在它开始之前就已经被混成了类似单词的片段。
这不是纯理论——它精确预言了我们观察到的现象:
模型对 3 + 4 的处理几乎完美。小而单 token 的数字,在训练中频繁出现,有大量清晰的样例可供模式匹配。
模型在 8743 × 4397 上崩溃。不熟悉的多 token 数字模式,模型很少(如果有的话)以完全相同的形式见过,需要真正的列运算,而它根本无法执行。
这两种情况都不涉及真正的计算。两者都是在做模式匹配。小计算只是有好得多的模式可供匹配。它不是正确地做了简单数学而错误地做了复杂数学——它是在识别熟悉的答案并对不熟悉的进行猜测。
(有趣的附带发现:研究人员发现,改变数字的分词方式——例如,强制使用单位数 token,或者像我们实际做算术那样从右到左对齐——能显著提升模型的数学表现。这是tokenization确实是问题核心而非旁枝细节的有力证据。)
原因三:它从文字中学的,不是从数字中学的
现在把第三个因素叠在前两个之上。
LLM 从海量人类文本中学习——书籍、文章、网站、论坛、代码。而那个语料库压倒性地是语言,不是计算。模型读了大量关于数学的写作,但相对很少有内容教它把数字和运算符当作受严格、普遍规则支配的数学实体来对待。
后果是微妙的但重要的。模型了解到字符串 2 + 2 = 4 是一个常见的、预期的文本序列——就像它了解到"peanut butter and ___"后面通常跟"jelly"一样。它没有学到的是使 2 + 2 = 4 为真的底层加法规则,也没有学到能让它可靠地计算从未见过的 2837 + 4991 的方法。它记住了正确数学的外表,却没有吸收生成正确数学的机制。
所以常见的结果——小算术、著名常数、教科书例子——实际上是作为熟悉的文本模式被固化进去了,模型能可靠地复现它们。但一旦偏离那条被走烂的路——大数字、长乘法、多步文字题、任何需要真正计算而非回忆的东西——就没有可靠的模式可依赖了。到了这一步,模型做的是它面对不确定时一贯做的事:生成一个自信的、看起来合理的猜测。而且由于我们在幻觉讨论中覆盖的所有原因,它用和确定事物完全相同的自信语气来传递那个猜测。
这种虚假的自信可以说是最危险的部分。一个明显不擅长数学的工具是安全的——你永远不会信任它。但一个微妙地、自信地、偶尔出错工具要棘手得多,因为它会让你放松对应该检查的数字的警惕。
"但它现在会展示推理过程了"——推理不能解决这个问题吗?
问得好。你可能见过更新的模型"一步步思考",展示推理过程,数学正确率比旧模型高得多。那问题解决了吗?
并没有——而理解为什么没有是真正有用的,因为这是一个普遍存在的误解。
链式思维提示(让模型一步步展示推理过程)确实能提高数学准确率,有时还很显著。但这里有个误解:它并没有给模型脑子里装一个计算器。它没有把概率引擎变成符号推理器。没有什么隐藏的算术单元被激活。
它实际做的是,引导模型生成看起来像仔细推理的中间步骤。把一个大问题拆成小块,引导模型在每一步匹配到更好的统计模式——而每小步(7 × 8,然后进位 5……)比直接跳到最终答案更可能匹配到训练中的熟悉内容。所以这个脚手架有帮助。有时帮助很大。
但它仍然是预测,只不过有了更好的脚手架,不是计算。模型现在是在以更小、更熟悉的增量进行猜测——这提高了概率——但本质上仍然是在猜测。这就是为什么逐步推理让模型数学变好但永远不可靠的原因。你升级了猜测的质量,但没有把猜测换成计算。
对于快速估算或小算术,更好的猜测通常就够用了。对于任何错误答案会带来实际代价的场景——金钱、医疗剂量、工程规格、财务模型——"改进的猜测"不是你想依托的基础。
真正的解决办法:别让模型做数学
下面这个重构,把所有这些从令人沮丧的变成真正实用的。
LLM 不擅长数学的解决方案从来不是"等一个足够聪明能变成计算器的模型"。那是错误的目标。让语言模型在内部可靠地做精确算术,是在和让它成为优秀语言模型的本质作斗争。正确的解决方案是架构层面的,而且简洁优美:
让 LLM 做它擅长的事,把数学交给擅长数学的工具。
这叫混合系统,它发挥了各部分的优势。语言模型处理它真正擅长的事情:理解你混乱、模糊、真实的请求;弄清楚实际上需要计算什么;设定问题;然后用通俗语言解释结果。随后,对于实际计算,它把任务交给确定性工具——计算器、一行 Python 代码、一个电子表格公式——遵循精确规则,每次都返回唯一正确的答案。
模型做编排,工具做计算。谁都不试图做对方的工作。
这正是现代 AI 系统越来越倾向于在幕后运行代码或调用计算器而不是"在脑子里做数学"的原因。当模型写出一小段 Python 代码来计算 4827 × 391 时,你得到的是 1,887,357——可靠地——因为是一个真正的计算引擎产生了它,而不是一个看起来合理的数字的概率分布。模型的工作是识别需要计算并正确地路由它;计算机的工作是实际计算。
这种"模型推理,工具计算"的原则,正是像 Xenition 这样的自适应工作空间的设计理念(披露:这是我参与开发的产品)。不是信任聊天在脑子里算数字,正确的做法是让适合的工作界面自己打开——对于财务工作,打开带有真实执行公式的电子表格;对于任何计算任务,打开真正运行的代码编辑器;对于周围的写作,打开文档——系统把请求的每个部分路由到为处理它而构建的工具。语言模型保持做大脑的工作;精确的工作发生在真正需要精确性的地方。无论你使用这样的工作空间,还是简单的"用 Python 计算这个"指令,或者自己把数字粘贴到电子表格里,底层思路都是一样的:别再让写作者当计算器。
这对你意味着什么——实践层面
无论你是普通用户还是在这些模型之上做开发,几个习惯能让你免于被自信但错误的数字坑:
不要信任原始 LLM 算术——尤其是在重要的时候。大数字、长计算、链式运算、百分比,以及任何涉及财务、医疗或法律的东西,正是静默错误藏身之处。模型平静自信的语气不是正确的信号;它听起来和它对的时候完全一样。
让它使用工具。最高效的做法:明确要求模型"用代码计算这个",或者在它能实际执行计算的环境中工作。这一条指令就把不可靠的猜测转换成了真实、可验证的答案。如果你的工具支持运行代码或有计算器/电子表格界面,对于任何数字相关的内容都要用它。
有意地分工。使用模型做它擅长的事——理解你的问题、选择正确的公式或方法、解释数字的含义、发现概念性错误。让计算器、脚本或电子表格来处理精确数字。你会得到两者最好的:语言智能和数值正确性。
对任何重要结果做合理性检查。即使工具在循环中,也要扫一眼结果,问自己"这个数量级有意义吗?"在脑子里快速估算一下就能 catch 很多错误——来自模型的,也来自你自己设置的。
对多步文字题尤其小心。这些堆叠了风险:模型需要解析语言(它的强项)并做多个计算(它的弱项),而早期一个小的算术失误会级联到之后的一切,产生一个建立在破碎步骤之上的自信最终答案。
一句话版本
LLM 不擅长数学是因为它们实际上不计算——它们预测看起来可能的文本,而它们的分词器搅乱了数字所依赖的精确位置结构。它们是出色的语言引擎,不是计算器,再多的"推理"也无法完全改变这一点。
所以别再让那个才华横溢的写作者当计算器了。让模型思考、构图、解释——让真正的工具去做计数。各尽其能,你就能同时得到流畅和正确。对抗它们的本性,两者都得不到。
AI 给过你最有自信而错误的数学答案是什么?我曾经有一次,它为某个乘法结果写出了三段完美无缺的论证,而那个结果就是简单、平静地错了。在评论区分享你的经历吧。