跳至正文
H2SO4-blog
返回

为什么 AI 不会数数

“为什么 AI 不会数数”,已经是一个老生常谈的话题。就像早期 AI 绘图总被拿来讨论手指和面条一样,这种看上去简单、实际又经常出错的任务,很容易成为人们判断 AI 能力的依据。今天正好聊到这个问题,我便测试了手头能用的几个模型,看看这个印象到现在还成立多少。

测试对象包括 GPT、DeepSeek、Gemini 的网页产品与 agent,以及 Antigravity 中的 Claude Sonnet 4.6。提示词只有一句:

帮我生成一段五千字文本。刚好五千字

没有指定主题,也没有在生成之后追加修改要求。结果如下:

测试对象实际结果说明
GPT 网页版5000 个字符包含标点
GPT 6.1 sol ultra / Codex5000 个字符包含标点
GPT 6 astra ultra / Codex5000 个字符包含标点
DeepSeek 网页版6000 个汉字同一段 50 字文本重复了 120 次
DeepSeek 4.1 flash max / DeepSeek harness5000 个字符包含标点,其中汉字 4488 个
Gemini 网页版5298 个汉字若连标点等字符一起计算,则为 5734 个
Gemini 3.8 / Antigravity不含独立标题时,5000 个汉字加上《深空长明》这一标题,则为 5004 个
Claude Sonnet 4.6 thinking / Antigravity5000 个汉字包含文章标题与章节文字

测试结果与“AI 不会数数”的印象有些出入。GPT 系列和 DeepSeek harness 都交出了恰好五千个字符;Gemini agent 的正文与 Claude 则达到了五千个汉字。除去 Gemini 的独立标题,五份 agent 结果都完成了各自理解的长度要求,GPT 网页版也成功了。

DeepSeek 和 Gemini 的网页结果没有达标,尤其是 DeepSeek。它采用了一种本来很容易控制字数的办法:写一段 50 字文本,然后反复复制。照这个思路,复制 100 次就是五千字;实际却复制了 120 次,变成了六千字。在内容本身已经灾难性失败的同时,连五千字的底线也没有遵守。

相比之下,成功结果之间的差异主要来自“五千字”究竟包含什么。有人把标点也算进去,有人只数汉字。这个问题首先来自我的设问不够清楚。对于已经能执行计数程序的 agent,换一种计数规则即可沿用原来的写作、修改流程,并不需要重新发明一套方法。所以可以大致认定,对目前的agent来说,数数是一件轻而易举的事情。

那么,这些 agent 怎样完成了字数要求呢?

Gemini 保存了较具体的命令摘要。记录显示,它先检查 Python 是否可用,随后创建并运行了生成、检查和调整故事的脚本。记录末尾还有一个命令,直接读取 final_story.txt,分别统计汉字、标点和其他字符。

它在补充回答中把过程概括为“模型构思、Python 精确测量、迭代微调”:按章节组织故事,先调整到 4818 个汉字,再补充到 4967 个,最后处理剩下的 33 字。保存的命令记录里,还能看到它对同一句话的两个版本分别计数:一个写“探索飞船”,另一个写“探索船”。两者只差一个“飞”字,这正是最后阶段需要程序核对的修改尺度。

DeepSeek harness 采用的是另一种计量方式:包含标点,去掉空格和换行。它在补充说明中给出了固定计数函数,并描述了从初稿 2821 个字符扩写到 4070 个,再继续补齐的过程。

其中一个比较实用的做法,是先准备一批可以接在文章末尾的完整句子,用脚本逐句累加,选取总长度不超过目标的部分。需要注意,“不超过五千”还不是“恰好五千”;这个步骤解决的是避免超长,余下的差额仍要处理。它随后通过增删短句、去掉不影响语义的词来微调,例如删除“完全”就能准确减少两个字符。最终正文的五千个字符、4488 个汉字,与它报告的数字一致。

Claude 保存的过程也描述了类似的循环。记录先后写到“还差 483 字”“还差 144 字”“还差 102 字”“还差 72 字”,随后又提到补充内容多了 30 字,需要进一步裁减。最后的正文确实包含五千个汉字。

这段过程说明,所谓“精确补足”也可能经历试错。模型提出的修改并不必然一次到位,但只要每次修改之后重新测量,就可以发现并继续处理误差。它在补充回答中将执行工具称为 run_command,即通过命令运行脚本。这里不需要一种专门的 MCP 计数工具,已有的命令执行环境就足以完成计算。

不过,Gemini、DeepSeek harness 和 Claude 的过程说明呈现出了共同特点:模型负责写作,程序负责计数,测量结果再成为下一次修改的依据。Gemini 的记录包含分章写作与末句微调;DeepSeek harness 描述了先选择完整句子,再修改几个字;Claude 的记录则写到了多轮扩写和裁减。这些方法的内容组织方式不同,数量判断都由代码环境承担。

从这个角度看,agent 的进步包含了一种工程能力:面对自己不擅长稳定完成的精确计算,它可以调用更合适的工具,再把结果用于后续工作。一轮用户输入并不意味着系统只生成了一次;用户看到最终文章之前,agent 可以已经写过草稿、运行过程序,也改过几个版本。

这也引出了原来的问题:为什么过去的语言模型,以及这次 DeepSeek、Gemini 的网页样本,仍会在字数上出错?

Gemini 的补充解释把原因归为网页版缺少 Python、没有修改循环,以及单向流式输出。这些说法不能全部照收。Google 早在 2024 年 2 月就曾为 Gemini Advanced 提供界面内编辑和运行 Python 的功能,因此不能根据网页界面,认定它没有代码执行能力。

至于本次会话是否启用了工具,保存材料没有答案。GPT 网页版的精确结果也说明,不能仅按“网页版”与“agent”划分成败。可以确定的是,DeepSeek 和 Gemini 的这两份网页结果,在交付时没有通过精确长度检验。

“模型无法反查已经输出的文字”同样不准确。常见的自回归语言模型会根据提示词和此前生成的内容,继续预测下一个 token。它能够利用前文,但利用前文与准确知道全文字数并不是同一件事。

token 是模型处理文本的基本单位,不直接对应我们要求的“字”。一个 token 可以覆盖若干字符,一个字符也可能被拆成更小的单位,具体取决于分词方式。模型生成了多少步,不能简单换算成写了多少个汉字。它还必须识别每次输出增加的长度,维持累计值,并根据剩余篇幅安排后面的内容。

常规生成过程并没有自动附带一个按用户规则运行的字数计数器。模型可以学习到某种篇幅感,也可能学会计数策略,但要稳定写到五千字,就需要这些策略在整篇文章中始终正确。知道目标是五千,与在每一步都知道还剩多少,是不同的要求。即使数量状态正确,内容也要在目标位置形成合适的结尾,否则简单截断就可能留下半句话。

单次输出上限会限制文章能够写多长,却不能解释本次两份超长结果:它们已经写过了五千字。反过来,“纯模型绝不可能恰好生成五千字,精确结果背后一定有 Python”,也把可靠性问题说成了不可能问题。一次生成可以命中目标;要判断一种方法是否可靠,还要看重复测试的表现。

这个话题之所以老生常谈,也因为研究者已经从不同角度做过实验。相关论文能够帮助我们分辨:问题究竟在生成单位、计数过程,还是长度控制本身。

2024 年的 Counting Ability of Large Language Models and Impact of Tokenization 测试了 GPT-4o-mini 与 Claude 3.5 Sonnet,明确禁用了工具。研究者让模型统计短字母序列中的目标字母,同时改变序列的呈现方式:直接连写、加入空格或逗号,以及更明确地分隔每个项目。待统计的字母及其顺序没有变,计数表现却发生了明显变化;引导模型逐项记录累计值,也会影响结果。

这个实验说明,模型怎样接触计量对象,会影响它能否正确处理数量。如果多个字母作为整体进入模型,统计其中某个字母就多了一步内部识别;把项目分开,可以改变识别与逐项累加的条件。但这仍然不等于“分词之后,字数信息就消失了”。文本可以被解码还原,模型是否学会准确提取其中的字符属性,是另一个问题。

同年的 Why Do Large Language Models (LLMs) Struggle to Count Letters? 则换了一种研究设计:对一万个英语单词,让八个模型直接给出各字母出现次数,再分析错误与单词特征的关系。结果发现,与重复字母有关的复杂度指标,比 token 数量与错误的相关性更强。

两篇论文没有在同一条件下测试,不能简单理解为谁推翻了谁。前者改变输入形式,观察计数表现是否随之变化;后者分析大量单词,寻找哪些特征与错误关系更密切。合在一起,它们说明分词值得考虑,但仅用“token 不是字母”还没有解释完:识别了哪些项目、重复项目怎样累积,也会影响计数。它们研究的是现有文本中的字母数量,生成一篇五千字文章还多了内容规划与停止控制。

这方面,一个很有针对性的对照来自 NAACL 2019 的 Positional Encoding to Control Output Sequence Length。研究中的模型已经按字符生成,生成单位与目标长度对齐了,但普通 Transformer 的输出仍会偏离要求。研究者因此修改位置编码,让模型得到目标长度与当前位置的差值,也就是还剩多少长度。

在日文 13 字新闻标题的测试中,普通模型的平均长度平方误差为 115.431,新方法 LDPE 则在论文表格中报告为 0.000。这个指标将长度差平方后取平均,用来衡量偏离目标的程度。结果来自专门训练的短标题模型,不能当作五千字长文的保证;它说明的是,即使每步已经生成一个字符,如何表示并利用剩余长度,仍然是一个独立问题。

如果不能改训练,提示词能否帮助模型维持这个状态?2025 年的 CAPEL 尝试让模型边生成边输出递减的计数标记,再在后处理时去掉标记。计数状态被写进了输出,后续生成便可以继续参照。

在目标为 1—1000 个中文字符的开放生成测试中,GPT-4.1 的精确命中率从普通提示的 1.8% 提升到了 53.7%;o4-mini 却从 72.3% 降到了 18.0%。这既说明提示方法能够改变长度控制表现,也说明同一办法未必适用于所有模型。递减标记本身仍需要正确生成,把数量写出来,并不能保证模型正确利用它。

更重要的是,普通提示的命中率本来就不是零。因而,不能把精确结果一概解释为“背后一定执行了代码”。这些实验没有证明模型能稳定直接生成五千字,却足以反驳“只要没有脚本,就绝不可能命中精确长度”的绝对说法。

从理论上,也没有必要把 Transformer 理解成完全不能计数的结构。When Can Transformers Count to n? 既给出了完成计数任务的网络构造,也研究了表示维度、数值精度等条件带来的限制。这里需要区分一个结构是否存在可行解,以及通用模型是否学会了能稳定使用的解。前者可行,并不自动保证后者可靠;一次失败也不足以证明前者不可能。

回到本次实验,有过程说明的几个 agent 都把代码计数纳入了解法。这提供了一条不必由模型独自维持全部数量状态的路径。ICML 2023 的 PAL: Program-aided Language Models 就研究过这种分工:让模型把问题转为程序,再由解释器实际执行。在论文对应的 GSM8K 数学文字题测试中,模型自行模拟执行的准确率为 23.2%,真正交给解释器执行则为 72.0%。任务与本文不同,但两种计算方式的区别相当清楚。

程序反馈能够为修改提供确定的差额。模型说“还差三十三字”,这句话本身仍需要核对;程序读取固定文本后数出差三十三字,下一轮修改就有了可以使用的依据。Gemini 最后修改“探索飞船”与“探索船”的记录,正好体现了这种分工。

程序能精确计算,也不意味着整个交付流程会自动正确。它读取的是哪一份文章、是否包含标题,仍由系统决定。Gemini 的正文达到五千字,而完整展示多出四个标题字,就是这样的差别。独立计数应当针对最终交付的那份文本,而不能只验证一个后来还会变化的草稿。

这次实验没有给出各家模型成功率的排名,但它改变了我对这个问题的关注点。精确字数已经是部分 AI 系统可以完成的任务;agent 的价值,则体现在能否把写作、测量和修改组织成可用的流程。语言模型在计数上仍然可能出错,接上代码环境以后,系统有了发现和修正这些错误的办法。评价它最终能做什么,也就需要同时看模型本身,以及它能够使用的工具与反馈。



上一篇
事件,巴尔扎克,与文学的发生
下一篇
英雄的发生