拿走计算器:LLM算术能力评测与工具增强的真实边界

发布时间:2026/8/30 13:49:08
拿走计算器:LLM算术能力评测与工具增强的真实边界 前段时间看到一个挺有意思的项目标题Show HN: I took the calculator away from 50 LLMs and graded the arithmetic。大意是有人把50个大语言模型的计算器没收了然后专门考它们的算术能力最后打分。这个实验很小但很值得认真聊一聊因为它触动了一个大家平时容易忽略的问题当我们夸某个LLM“数学很强”的时候我们其实分不清这个强到底来自模型自己的运算能力还是来自它调用外部工具的能力。我个人的判断是LLM的真正优势从来不是逐位精确计算而是把模糊的自然语言问题转译成可执行的结构如果你把计算器拿走很多模型的算术分数往往会出现明显回落。这既不是某个模型的黑点也不是什么新闻而是这类模型的底层机制决定的。真正要思考的是在评测和工程落地时如何不把“工具增强后的表现”误当成“模型的内在能力”。很多人看到这类实验的第一反应是打算用算术题给模型排名。这个方向其实容易跑偏。更值得做的是把这次实验当成一次“能力隔离测试”先去掉外部工具看看模型自身能算到什么程度再允许工具介入看看表现能提升多少最后对比两组结果才知道哪些问题应该交给模型哪些问题必须交给确定性工具。1. 这个实验到底在测什么内在算术而不是工具增强算术1.1 先区分三个容易混淆的概念数学推理、算术计算、工具调用在继续之前先把三个概念分开数学推理、算术计算、工具调用。数学推理是指理解题意、建立数量关系、判断解题路径。比如给出一道应用题“商店有120个苹果卖出三分之一又进货40个问现在有多少个苹果”模型能读懂“三分之一”、能识别“卖出”是减少、“进货”是增加并能列出正确算式这部分属于推理。算术计算是指把算式执行到一个确定数值。这个动作要求每一步进位、借位、乘法表、除法余数都精确无误。对于人类来说三位数乘三位数已经需要草稿纸对于LLM来说这也不是它的天然优势区域因为它本质上是基于概率生成下一个token而不是执行寄存器运算。工具调用则是模型通过调用代码解释器、计算器API、Excel公式或者其他外部程序来完成计算。在这类工作流中模型承担的是“调度者”角色它决定应该算什么、怎么算但真正的逐位运算发生在外部确定性工具里。很多评测或者产品演示里模型能答对复杂的数学题依靠的是第二和第三种能力的叠加。如果不做隔离你很难判断模型本身在计算环节贡献了多少。“拿走计算器”这个动作本质上就是在测试模型在纯计算环节到底有多可靠。1.2 为什么“拿走计算器”是关键动作如果你采用工具增强架构模型可以调用计算器那么“123456 × 789”这种题对它来说其实没有太大压力。模型只需要生成一个可执行的表达式计算结果由计算器给出。这时候评测成绩高并不代表模型自己会算只代表它学会了“用工具”。反过来一旦禁止使用工具模型的算术能力就会暴露出来。它会尝试直接自回归地生成一串数字。这串数字经常看起来很像答案但可能在中间某一位出错。问题不在于模型“笨”而在于它采用了并不适合精确计算的方式来做这个任务。这就是实验设计中最有价值的一点它不是去比较哪个模型“更聪明”而是去测量一个工作流中哪一部分能力被高估了。如果你在做评测建议把这类测试单独作为一个维度叫“无工具算术能力”。如果模型在这个维度上表现一般不要急着否定它而是应该在产品设计里加上计算器或代码解释器。1.3 50个模型能告诉我们什么边界50个模型这个样本量不能代表所有可能的大语言模型但足够看出一些共性趋势。通常在这类测试里不同参数规模的模型表现会有分层大模型在复杂推理上更强但对长数字的精确计算也不一定稳定小模型可能更依赖训练数据中见过的表达式。这里最容易带来的误解是用一道算术题就判断模型好坏。因为算术能力不等于综合能力也不等于推理能力。从工程视角看这里有个更务实的边界如果产品里有数值计算场景不能默认“模型能力强就一定能算对”也不能默认“模型能力弱就一定算不对”。正确的做法是事先设计好“哪些计算必须走工具哪些计算可以直接输出数字”并把决策依据写清楚。2. 为什么LLM算不好整数乘法从token化到自回归2.1 token化把数字切碎了模型看到的不是完整数字很多人第一次看tokenizer输出时会觉得奇怪一个像123456789这样的整数可能不是一个整体token而是被切成了好几个token。例如按子词切分后它会变成“123”“456”“789”或者更碎片化的组合。对模型来说它看到的不是十进制数字的完整结构而是一串离散符号。进位和位权的概念在token序列里被弱化了。这就好比把一个两位数乘一位数的计算过程拆成几个不连续的音节让一个人去心算难度自然会上升。模型要在大脑里重建数字的十进制结构然后完成逐位运算。它确实有一定能力但这种能力不是通过“硬编码的算术指令”实现的而是从训练数据中统计出来的近似映射。数字越大、携带的token越多重建失败的概率也会明显抬升。Token化不直接导致计算失败但它解释了为什么模型对“看上去很长”的数字会有天然的短板。在设计测试题时如果不控制数字长度不同模型的可比性就会下降。所以评测题目应该覆盖短、中、长三个数字区间分开统计正确率而不是全混在一起算一个总分。2.2 自回归生成让每一位都可能出错LLM的推理过程是自回归的每生成一个token都基于前面的token再做一次概率预测。这意味着一旦某一位数字生成错误后续的数字生成都会在错误基础上继续。它不像传统算法那样可以“回退重算”除非模型在生成结束后做一次自校验。这个机制对算术题非常不友好。因为算术答案的每一位都很重要任何一位错整个答案都不成立。模型可能在生成前三位时完全正确第四位开始偏离最后结果差之毫厘谬以千里。这也是为什么在评测中只看“是否完全正确”会低估模型的部分知识。更好的做法同时记录“整体正确率”和“达到某一精度阈值的比例”例如答案有多少位和标准答案完全一致。另外解码参数也会影响稳定性。温度较高时概率分布被放大一些非最高概率的数字token也可能被采样到导致“随机性错误”。如果你需要复现实验建议把温度固定到较低值或者使用确定性解码否则实验结果会带上明显噪声。2.3 训练目标和注意力机制并不偏向精确算术语言模型的训练目标通常是预测下一个token而不是保证每个答案逐位精确。训练数据中算术问题通常以“题面答案”的方式成对出现但模型未必能从中提取通用的算术规则。它更擅长处理那些在训练数据中高频出现的模式比如常见的乘法表、日期计算、简单百分比。注意力机制擅长捕捉长距离依赖但逐位运算要求的恰恰是局部的、严格规则化的步骤例如进位。模型可能在需要进位的场景中表现不稳定。这种不稳定不是“没学会数学”而是它在试图用模式匹配去近似一个形式系统。从落地角度看这意味着你不能把LLM当成一个可解释的确定性计算单元。它的输出天生带有概率性和近似性。如果业务需要100%稳定的数值结果那就必须在模型后面挂一个校验层或者把计算完全交给代码解释器。2.4 模型精度和推理引擎的次生影响热搜词里经常出现“LLM大模型之精度问题(fp16, fp32, bf16)”这个话题和算术评测也有关系。推理引擎在加载模型时经常使用FP16、BF16等低精度格式来节省显存。这些格式会略微降低模型权重的表示精度大多数生成任务感知不到差异但在一些对数值极其敏感的任务上可能会造成输出不稳定。这里需要说明模型权重精度和模型计算答案是两回事。权重精度影响的是模型激活值的稳定性不是直接把12.34变成12.35。但如果你在一个较长的自回归生成过程中累积了微小差异最终答案可能从“完全正确”变成“差一位”。在评测时建议固定推理引擎和精度设置并记录推理配置。否则你会把“环境差异”当成“模型能力差异”。同样推理引擎的调度也会影响结果。比如是否使用贪心生成、是否启用beam search、是否设置随机种子都会影响输出。评测报告里应该写明这部分状态方便复现。这也是为什么很多严谨的LLM评测不只是给模型打分还要附上tokenizer版本、推理框架、精度类型和解码参数。3. 如何设计一份“没收计算器”的LLM算术评测3.1 先把评测目的定清楚是想证明什么还是发现问题如果你也想跑一个类似的实验不要上来就找50个模型挨个问。先问自己这份评测用来做什么是团队选型时想比较模型还是写文章时想说明某个问题还是想发现模型在哪些题型上容易错。不同的目的对应完全不同的题目设计。如果目的是选型题目要偏向实际业务的数据形态比如长串订单号、金额计算、库存数量、平均值。如果目的是技术分析题目要更结构化按数字长度、运算类型、是否涉及进退位、是否涉及小数、是否涉及负数分组分别测试。如果目的是验证工具增强的价值那就需要同一组题跑两次一次不允许调用外部工具一次允许调用记录两组准确率差异。题目数量也要合理。太少的题没有统计意义比如每个模型只考5道题很容易受随机性影响。建议每个维度准备20道以上题目并且打乱顺序。否则模型容易受到前文内容的干扰也不能稳定区分能力差异。3.2 题目设计难度分层、数字范围、运算类型、表达方式设计题目时至少覆盖以下维度运算类型加法、减法、乘法、除法、混合运算、带括号表达式。数字范围个位数、两位数、三位数、四位数以上、小数、百分比、负数。是否涉及进位或借位这是最容易暴露错误的场景。表达式形式自然语言、纯算式、Markdown算式、包含单位。建议使用表格来组织测试集例如题目类型数字范围是否进位/借位代表算式主要风险两位数加法11-99部分题目包含进位47 85进位后结果个位/十位混淆三位数乘法100-999通常包含进位327 × 186中间积错位带小数除法0.1-99.9小数点位置12.6 ÷ 0.3小数点前后处理错误混合运算数字不定运算顺序15 6 × 7 - 8运算优先级遗漏不要只出“两位数加两位数”这种简单题。你真正需要的是能拉开差距的题目而不是让所有模型都得100分的题目。如果怕题目太难导致普遍低分可以按难度分层最后分别统计。3.3 提示词模板尽量保持一致禁止中间穿插额外信息所有模型都必须使用同一个提示词模板否则结果不可比。模板要明确要求“只输出最终数字不要解释过程”这样解析答案会更容易。但也要考虑到有些模型即使在指令中说了“只输出数字”也可能输出“结果是3829”之类的解释。这时候需要后处理提取数字。提示词示例通用结构请计算下列算式不要使用任何外部工具不要解释过程只输出最终数值。 算式{question} 最终数值这个模板的关键点在于明确禁止外部工具要求直接输出把算式放到一个固定位置用“最终数值”作为生成起点。在实际使用中不同系统提示词格式会影响效果建议对每个模型都使用同样格式而不是针对每个模型写不同提示词。否则就不是在测模型的算术能力而是在测“适配提示词的能力”。3.4 判分规则严格等价、数字答案提取、部分得分判分规则直接影响结果。最简单的是“字符串完全一致”但这样会误伤一些合法等价答案。比如“42.0”和“42”在数学上相等但字符串不同。更合理的规则是提取数值并允许一定的容差。判分步骤建议从模型输出中提取第一个数字表达式。使用确定性计算器计算该表达式的值。与标准答案做绝对误差或相对误差比较。完全一致记1分在容差范围内记0.5分超出容差记0分。对于纯算术测试我更推荐记录两个指标完全正确率和答案在1%相对误差内的比例。因为LLM对于长数字常出现“接近正确但某一位偏差”的情况。如果只统计完全正确率模型得分会偏低信息量也有限。加入部分得分才能看出模型到底能算到哪个精度。3.5 控制变量解码参数、上下文长度、并发环境先跑小样本确认输出格式稳定再扩大测试规模。解码参数要尽量固定。建议温度设为0或使用贪心解码关闭随机采样。上下文长度也要固定给所有模型相同的上下文宽度。并发请求可能会因为服务端排队影响超时但不影响答案内容不过如果你发现同一模型在两次测试中结果不一致优先检查解码参数、随机种子和推理引擎版本。另外建议把每个模型的输入输出都记录下来包含原始响应。光记录一个分数没有排查价值。后续分析时需要查看具体的错误输出才能判断错误是“计算方向错了”还是“最后一位抄错了”。4. 跑完评测后怎么分析结果而不是只看准确率4.1 要有误差分布错多少、错在哪一位、哪些数字类型更容易错只给一个总分数很难发现规律。更好的做法是统计误差分布例如错误答案和正确答案的差值分布。错误发生的位置是第一位错、中间位错还是末尾位错。最容易出错的数字类型比如是否带小数点、是否包含零、是否很长。这些信息可以用来回答“为什么这个模型答错”。如果模型对三位数乘法表现良好但一到带小数的除法就翻车可能是因为模型对数和运算符的关联建模不足。如果模型总是把结果多算或少算10倍可能是小数点位置处理有系统性偏差。分析时建议把题目和输出对齐到表格里比如题目标准答案模型输出是否完全正确绝对误差相对误差可能错误类型47 85132142否107.58%进位错误12.6 ÷ 0.3424.2否37.890%小数点偏移这种表格能让你对错误模式一目了然而不是停留在“准确率80%”这种模糊信息上。4.2 要分位数而非只给平均分50个模型的平均分可能被几个极端值拉高或拉低。更合理的做法是同时看中位数、四分位数和最高/最低分区间。如果平均分和中位数相差很大说明模型之间能力并不均衡。在实际选型时不能只选平均分最高的模型还要看它的分数是否稳定尤其在你关心的数字范围上。建议报告格式包含最低分、25分位、中位数、75分位、最高分、标准差。如果一个模型在中位数附近表现出色而另一个模型在特定题目上偶尔满分、经常零分那后者可能在真实场景中更不可靠。4.3 要区分“完全不会”和“接近正确”“完全不会”可以理解为输出方向和标准答案没有关系比如把加法结果写成了负数或者明显不在数量级上。“接近正确”则可能差了最后一位或者小数点错了一位。这两类错误的内在原因完全不同。接近正确的错误更可能是token级别的局部波动比如某个数字token生成概率不够高被低概率token替代。完全不会则可能是模型没有理解运算规则或者训练数据中这个运算模式出现得太少。分析时建议把这二者分开统计。如果某个模型大量接近正确但少数完全错那么加一个自动校验步骤就能大幅提升可靠性如果大量完全不会那校验也救不回来只能换方案。4.4 要和工具增强版对比知道模型的真实提升来自哪里同一个实验最有说服力的对比是同一批题目在“禁止工具”和“允许工具”两种情况下的分数对比。允许工具时需要额外设计一个接口让模型输出代码或调用表达式。对比结果通常能说明一部分提升来自外部计算器一部分提升来自模型对流程的理解。这个对比对你的工程决策非常有帮助。如果你发现模型在无工具情况下算术得50分接上工具后变成98分这个问题就不需要继续优化模型的算术能力而是应该把工具调用做稳。反之如果接上工具后分数提升不大那可能是模型连“该调用工具”或“怎样构造表达式”都没学会这时候该补的是指令遵循能力。5. 工程落地不要指望LLM直接做精确计算5.1 最稳妥的架构LLM负责解析和规划计算器负责计算在真实产品里我更建议采用“LLM 确定性工具”的分工架构。LLM负责从自然语言中抽取数量关系生成算式或结构化运算步骤计算器或代码解释器负责执行所有数值计算。这样能最大程度发挥模型的语义理解优势同时避免模型在数值计算上的概率性误差。具体来说可以有几种工程模式提示词模式让模型输出一个计算表达式然后使用确定性计算函数或安全解析器计算结果。函数调用模式让模型输出一个调用计算器函数的请求系统拦截后计算结果并返回给模型。Agent模式把计算器封装成工具允许模型在推理过程中主动调用工具获取结果。在这三种模式里模型都只需要做“决定算什么”不需要“亲自算”。这也是目前很多应用里“数学变强”的真实来源。5.2 什么时候可以容忍模型直接算极短数字、容错场景并不是所有场景都必须接计算器。如果数字很小、规则简单比如“3 5”这种一位数运算模型直接输出通常没问题。另外如果结果本身只是给用户参考不依赖数值精确性比如“大致估算价格范围”那么模型直接输出粗略值也可以接受。但一旦满足以下条件之一就强烈建议加工具数字超过两位数或者涉及连续运算。结果要用于金额、库存、时间、长度等精确业务。多个数量之间存在依赖关系一个算错会连带后续步骤错误。需要给用户看可追溯的计算过程。判断标准可以写成一条如果这个数值错了会带来业务损失就必须使用确定性工具。5.3 常见错误排查链路从现象到根因下面是一套通用排查链路适合落地时遇到模型算术问题使用先看现象模型输出是空、报错、格式错还是数字错再看输入题目是否清晰数字格式是否完整比如是否有空格、单位、小数点。再看环境推理引擎、模型精度、解码参数、上下文长度是否固定。再看解析从响应中提取数字的正则或表达式是否可靠是否把“正确答案”误判为错误。最后看模型边界同一个输出在多轮、多次请求下是否稳定如果二次请求结果不同优先怀疑解码随机性。例如你发现模型回答“123.45 × 67”结果为“8271.15”但标准答案也是“8271.15”程序却判分报错。这时先检查数字提取规则是否只匹配了整数再检查模型输出是否带了多余单位或前后缀。这种错误不是模型算术问题而是工程解析问题。另一个例子模型输出“8271.150000000001”原因是代码解释器或模型自己做了浮点运算。这时需要判分时设置容差而不是直接要求完全一致。浮点误差属于正常的数值计算边界不是LLM独有的问题。6. 微调和推理引擎是否真的能改变算术能力6.1 微调可以提升格式模仿但不等于提升算法泛化有些团队会试图通过微调提升模型的算术能力。微调确实可以让模型在特定题型、特定格式上表现更好比如让它更熟练地生成“第一步、第二步、最终答案”这种结构。但微调很难从本质上让模型获得完整的通用算法能力尤其是面对训练分布之外的数字组合时。如果在真实业务中经常遇到固定形式的算式微调是有意义的因为模型可以从示例中学会匹配模板。但如果你问的是“四位数乘三位数、随机数字”微调未必能带来可靠提升。而且微调数据如果质量不高反而可能让模型学会在输出中塞进更多解释性文字影响答案提取。因此我的建议是确定业务场景中的算式形态针对高频形态微调或做few-shot示例对于长尾数字和复杂运算仍然交给外部工具。微调的目标不是让模型变成计算器而是让模型在“算之前能更准确地表达出要算什么”。6.2 推理引擎的精度设置是稳定性问题不是能力问题FP16、BF16、FP32这些精度配置主要影响权重存储和计算速度通常不会让模型从“会算”变成“不会算”。但在长序列生成过程中低精度累积误差可能导致部分token的概率分布发生轻微变化。如果你发现同一模型在不同精度下个别题目结果不同不必惊讶。这属于环境层面的不稳定性而不是能力层面的结论。在做模型对比时建议固定精度。否则你可能会把一个因为推理引擎差异导致的错误归因到模型头上。我的经验是先用FP32或BF16跑一遍基准确认模型表现正常再考虑切换到低精度以提升吞吐如果低精度下出现偶发算术错误可以先尝试固定温度、增加采样次数、做答案校验。6.3 一个更务实的判断把算术留给工具把推理留给模型回到项目标题背后的判断移除计算器之后很多LLM的算术分数并不稳定。这不是说LLM没用而是说它适合的职责边界已经越来越清楚。语言理解、任务拆解、工具编排、生成解释这些是LLM的强项逐位精确计算、随机数生成、时间戳换算、汇率计算这些是确定性工具的强项。未来应用架构里模型和工具不是竞争关系而是协作关系。模型的价值体现在能判断什么时候需要工具、如何描述需求、如何解释结果。工具的价值体现在提供稳定、准确、可验证的计算结果。能把两者组合好的系统才是真正可落地的系统。所以当你看到类似“把计算器拿走”的实验时不要只把它当成模型排名而应该把它当成一个提醒任何精确数值场景都要在设计阶段想清楚“这一步到底应该由模型完成还是由工具完成”。评测时也要把这个边界写清楚否则你得到的分数会被工具增强效应严重污染。7. 回到实验真正值得长期关注的是什么这个“拿走计算器”的实验真正的价值不是证明哪个模型更聪明也不是算出一份“算术能力排行榜”。它让我们重新看到了一个常常被忽视的事实大语言模型的能力边界不同于人类直觉。人类会觉得“计算能力是基础能力LLM连这都不行是不是不行”但技术落地的逻辑不应该是这样。我们应该关心的是在什么条件下模型的输出是可靠的在什么条件下必须增加外部约束工具。如果你打算在自己的场景里复现这个实验我的建议是先把小样本跑通50个模型成本高可以先用5个模型、20道题做预测试。记录所有输入输出检查判分规则是否与业务一致再扩大规模。不要一上来就追求“50个模型”的壮观场面先确认自己的评测流程是可靠的。更长期来看评测报告本身也要加入“工具环境”这一栏。如果说“模型在允许调用计算器的情况下真实业务准确率是98%”这没有问题但要把“是否允许工具”写清楚。未来无数应用会默认接上各种工具模型是否自己具备算术能力可能越来越不重要。重要的是它能不能在合适的时机调用合适的工具能不能在工具返回结果之后做正确的判断。所以不必纠结于“拿走计算器后LLM到底能考几分”。真正值得长期追踪的是在去掉外部增强之后模型还剩多少可用的推理能力在加入外部增强之后模型又能在多大程度上利用工具。前者帮助你理解模型的内在边界后者帮助你设计稳定的系统。两件事分开做评测才有意义工程也才经得起验证。