您当前的位置:首页 >> 滚动 >  >> 正文
焦点速看:AI模型多想一会儿,调用工具就能更准吗?
来源: 科技行者      时间:2026-09-17 21:24:08

你有没有遇到过这种情况:让AI帮你订机票、查天气、再把结果汇总成一份行程表,结果它要么漏掉一步,要么把参数填错,要么干脆把两个任务的顺序搞反了。

这不是你的错觉。当AI模型需要连续调用好几个工具、还要让后一个工具用上前一个工具的结果时,出错率会明显上升。这篇来自剑桥大学的论文,就是在琢磨一件事:能不能让AI模型在做决定之前,多"想"几遍,从而把这种复杂的工具调用任务做得更好。

先搞清楚,这件事到底难在哪


(资料图片)

现在的AI智能体,说白了就是一个不断做决策的系统。用户说一句话,模型要判断该调用哪个工具、填什么参数、调用完之后结果要不要传给下一个工具。

如果只是"查一下北京天气"这种单次调用,大多数模型都能应付。真正的麻烦出现在复合任务里。比如"把这个整数列表转成字符串,然后再把字符串里的特殊符号全部替换掉",这就要求模型先调用A函数,再把A函数的输出结果作为参数传给B函数。中间任何一步出错,整个任务就崩了。

**工具调用*:指AI模型根据用户请求,自动选择合适的外部函数(API)并生成调用参数的过程,是构建AI智能体的核心能力之一。

论文里用一个专门的说法来描述这种结构:模型给出的一整套工具调用方案,可以看成一张"有向无环图",节点是每一次具体的调用,边代表"这次调用的结果要喂给下一次调用"。如果这张图里节点之间没有连线,说明各个调用互相独立,可以并行执行;如果有连线,就意味着存在依赖关系,必须按顺序来,还得把中间结果正确地传递下去。

论文选用了三个评测基准来考察这件事:BFCL(主要测试单次调用和并行独立调用)、NESTful(专门测试有依赖关系的嵌套调用)、API-Bank(测试真实世界API的选择和参数填写准确度)。这三个基准合起来,基本覆盖了从"简单查一次"到"复杂多步协同"的全部难度梯队。

那么,"多想一会儿"具体是什么意思?这就要说到这篇论文的主角——循环语言模型。

循环语言模型:不是加参数,而是加"思考轮数"

普通的Transformer模型,结构是一层一层往上叠的,每一层参数都不同,模型跑一遍输入就直接产生输出,一锤子买卖。

**Transformer*:目前主流大语言模型采用的神经网络架构,通过自注意力机制处理序列数据。

循环语言模型(Looped Language Models)换了个思路:它不是把很多层不同的Transformer叠起来,而是反复使用同一组共享参数的Transformer模块,对输入的隐藏表示进行多轮加工。用论文里的公式说,第t轮迭代的隐藏状态h是由上一轮的隐藏状态经过同一个共享模块计算得到的,每一轮结束后都可以生成一次预测结果,模型可以选择在第1轮就输出答案,也可以选择在第2轮、第3轮甚至第4轮再输出。

这里有个关键区别要说清楚:这不是让模型变得更大,而是让模型对同一个问题多算几遍。打个比方,普通模型像是让你把一道数学题从头到尾抄一遍公式直接给答案,循环模型则像是让你把这道题在草稿纸上反复演算几次,每一次都检查一下上一次的结果对不对,再决定要不要继续算下去。

如果不这样设计会怎样?答案很直接:模型的计算深度永远和参数量绑死。想要更强的推理能力,唯一的办法就是堆更多层、更多参数,训练和部署成本跟着水涨船高。循环结构把"计算量"和"参数量"这两件事解耦了,同一套参数,你想让它算1轮就是轻量模式,想让它算4轮就是深度模式,不需要重新训练一个更大的模型。

这就好比家里做饭,一道菜可以按标准流程走一遍出锅,也可以多炖一会儿让味道更透。厨具(参数)没变,火候(计算轮数)变了,出来的成品质量也会不同。如果永远只按标准流程走一遍,遇到需要慢炖才能入味的菜(也就是复杂的依赖任务),味道自然就差了一截。

论文里用到的模型主要分两类。一类是"原生"循环模型,比如Ouro-1.4B和Ouro-2.6B,它们从预训练阶段开始就是按照循环结构设计的,最多支持4轮迭代,预训练用了大约7.7万亿个token。

**预训练*:指模型在海量通用文本数据上进行的初步训练,让模型先学会语言的基本规律,之后再针对具体任务微调。

另一类是"改造"循环模型,研究者拿现成的Llama-3.2-1B和OLMo-2-1B这些标准模型,把中间一部分层改造成可以循环执行的模块,最多支持8轮迭代。这种改造方式的好处是不用从零训练,直接在原有模型的基础上做手术,代价是可能没有原生设计那么彻底。

Ouro模型是怎么学会"该想几轮"的

原生的Ouro模型有一个很巧妙的设计:它不是傻乎乎地固定跑满4轮,而是自带一个"退出闸门"。

具体来说,模型在每一轮迭代后,都会顺便算一个"我现在要不要停下来"的概率,这个概率经过一系列连乘运算,就形成了一个关于"到底该在第几轮退出"的概率分布。训练的时候,模型的损失函数会综合考虑所有轮次的预测结果,并且用一个类似正则化的手段,鼓励模型别急着在第一轮就草率退出。

训练分两个阶段进行。第一阶段,语言模型本身和这个退出闸门一起训练。第二阶段,语言模型的参数被冻结住,只单独训练退出闸门,训练信号来自"多算一轮到底能带来多大的提升"这个指标,如果多算一轮几乎没有改善,闸门就该学会在这里喊停。

这套机制的好处显而易见:简单问题不用陪着复杂问题一起"陪跑"满血计算。这就像考试的时候,选择题扫一眼就能确定答案,你不会非要按大题的解题步骤把选择题的每个选项都推导一遍。如果不设计这种自适应机制,模型面对一道送分题也要老老实实算满4轮,白白浪费计算资源,这对追求推理效率的实际部署场景来说是不划算的。

改造版的循环模型(比如基于Llama和OLMo做手术改造的那些)就没有这套自适应退出机制了。它们训练时的做法是,每个训练批次随机采样一个循环轮数(用一种叫泊松-对数正态分布的方式来采样),然后只在这个采样到的最终轮次上计算损失,同时用KL散度约束新模型的输出不要偏离原始预训练模型太远。

**KL散度*:一种衡量两个概率分布差异程度的数学工具,这里用来约束改造后的模型行为不要和原模型差太多,防止"改造"把模型原有能力搞坏。

这意味着改造版模型在推理时,只能靠人为指定一个固定的循环轮数,没法像Ouro那样自己灵活判断该停在哪一轮。这也是论文后面重点讨论的一个差异来源。

实验结果:复合任务里,循环计算的优势最明显

论文做了一系列对照实验,控制变量做得相当扎实:所有模型用同一份Hermes函数调用数据集微调,用完全相同的训练超参数(学习率、训练轮数、LoRA配置等),确保比较的是"循环结构"本身带来的差异,而不是训练技巧的差异。

**LoRA*:一种参数高效微调技术,只训练模型中一小部分新增的参数,而不是重新训练整个模型的全部参数,能大幅降低微调成本。

先看BFCL这个基准的结果。Simple类别(只有一个工具、只需一次调用)里,循环模型和非循环模型的差距很小,因为这种任务本来就不难,谁都能做好。但是到了Parallel和Parallel-Multiple这两个需要生成多个独立调用的类别,差距就明显拉开了。

举个具体数字:Ouro-2.6B在SFT(监督微调)之后,Parallel类别达到83.0分,Parallel-Multiple达到76.5分,整体准确率86.4分,这个成绩甚至超过了参数量更大的Qwen3-4B(SFT后整体只有56.7分,尽管其指令微调版本表现更好)。而基于Llama-3.2-1B改造的循环版本,在Parallel类别上从非循环版本的14.0分跃升到31.0分,Simple类别也从29.8分升到43.5分,提升幅度相当可观。

**SFT(监督微调)*:Supervised Fine-Tuning的缩写,指用人工标注好的高质量数据对预训练模型进行针对性训练,让模型学会执行特定任务。

再看NESTful这个专门考察依赖链条的基准,结果趋势是一致的。Ouro-2.6B经过SFT后,Win Rate(执行预测的调用序列后,答案是否正确的胜率指标)达到0.371,远超Ouro-1.4B的0.191,也超过了参数量差不多大小的Qwen3-4B的SFT版本(0.063)。要知道NESTful里的任务需要模型先调用一个函数拿到中间结果,再把这个结果准确地喂给下一个函数,这种"接力赛"式的任务对模型的结构化推理能力要求极高。

最后看API-Bank,结果就没那么统一了。这个基准里大多数任务只需要一次API调用,考察的重点是"选对API、填对参数"这种局部能力,不太涉及多步协同。数据显示,循环和非循环模型在这里的差距明显缩小,甚至在改造版模型上,循环版本反而略逊于非循环版本(比如OLMo-2-1B改造后的Call Correctness从37.1降到34.0)。

这个结果其实挺说明问题的。循环计算带来的好处,不是那种"什么任务都能通吃"的万能加成,而是专门针对"需要维持结构、追踪依赖"这类任务的针对性提升。简单任务不需要反复琢磨,多算几轮反而可能是浪费,甚至因为训练时的随机性引入一点点噪声。

这就好比让你去买一瓶矿泉水和去策划一场婚礼,前者你走进便利店拿了就走,根本不需要"多想几遍",后者你反复推敲场地、流程、宾客名单之间的相互配合才能不出岔子。如果强迫你对着买水这件事也反复推敲三四遍,不仅没有帮助,还显得多此一举。

固定轮数实验:计算深度和准确率的关系到底是什么样

前面的对比实验没法说清一件事:模型表现更好,到底是因为循环结构本身,还是因为训练数据或者训练方式恰好更适合这些模型?

论文设计了一组更干净的实验,把模型参数完全固定住,只调整推理时执行的循环轮数,专门观察"多算几轮"这一个变量的效果。

在BFCL上,结果显示准确率总体随着循环轮数增加而提升,提升最明显的还是那些需要多次调用的类别。Ouro-1.4B在Simple类别很快就趋于饱和,但Multiple、Parallel、Parallel-Multiple这几个类别在轮数增加到3轮、4轮时还在持续进步。有意思的是,Ouro-2.6B在3轮左右就基本饱和了,这说明参数量更大的模型,本身"想得更周全",不需要靠反复迭代来弥补,就像一个经验丰富的老师傅,看一眼图纸心里就有数,不需要反复核算草稿。

NESTful上的规律更加清晰:Win Rate几乎是随着循环轮数线性增长的。这一点特别值得琢磨,因为NESTful里的任务本质是"后面的调用依赖前面调用的输出",这种任务需要模型在生成过程中不断回头检查、修正之前的判断,恰好是循环计算最擅长发力的场景。

不过有个地方要泼一盆冷水:改造版的循环Llama模型,在NESTful上的表现明显弱于原生Ouro模型。哪怕轮数拉满到8轮,Win Rate依然很低(个位数百分比),远不如Ouro-2.6B四轮就能达到的35%以上。这说明"事后改造"和"从头设计"之间存在真实的差距,改造能带来提升,但提升的天花板明显更低,可能是因为预训练阶段的表征方式没有专门为循环计算做过适配。

论文里给了一个特别直观的例子,展示了同一个NESTful任务在不同循环轮数下的表现变化。任务是把一个整数列表转成字符串,再对字符串做标准化处理。第1轮时,模型直接编造了一个工具目录里根本不存在的函数,第二步调用干脆漏掉了;第2轮时,模型意识到需要两步调用,但第一个函数名依然是编的,而且变量引用格式也是错的;到了第3轮和第4轮,模型终于给出了和标准答案完全一致的调用序列,包括正确的输出到输入的变量引用。

这个例子说明,循环计算修正的不只是格式问题,而是实实在在的语义错误:函数名选错了、调用结构漏了、变量绑定错了,这些都是需要模型"回头再想想"才能纠正的深层错误,而不是简单的格式排版问题。

自适应推理:不是越多轮越好,是够用就好

固定轮数实验说明了一个规律:轮数越多,效果通常越好,但会在某个点上饱和。这意味着,如果你不管三七二十一每次都跑满4轮,会在那些本来2轮就够用的任务上白白浪费计算资源。

这就是自适应推理要解决的问题。论文用Ouro自带的退出闸门,让模型自己决定每个token生成时到底需要几轮计算,设置了从0.1到0.8几档不同的置信度阈值,阈值越高,模型越倾向于多算几轮才敢下结论。

结果显示,自适应推理在计算量和准确率之间找到了一个明显更划算的平衡点。在BFCL上,自适应方式用比固定4轮更少的平均计算轮数,就能达到甚至略微超过固定4轮的准确率。在NESTful上,Ouro-2.6B用自适应方式,能用比固定4轮更少的平均计算量,达到和固定4轮相同的Win Rate。

这个结果换个说法可能更好理解。假设某个任务90%的token其实一轮计算就能搞定,只有10%的token是那种需要反复推敲的"硬骨头",如果你固定跑4轮,就是拿处理硬骨头的力气去处理那90%根本不需要那么费劲的部分。自适应机制相当于给每个token配了一个"分诊台",简单的直接放行,复杂的才转到专家那里反复会诊。

如果不这么设计,代价是什么?代价是推理成本和准确率的性价比会明显变差。论文的图表显示得很清楚,固定深度曲线要爬很久才能接近自适应曲线的水平,而自适应曲线几乎是"贴地飞行"式地用更少资源触达差不多的高度。

这也带出一个更值得琢磨的问题:如果这种自适应停止机制被更广泛地应用到实际的AI智能体系统里,未来的推理成本账单可能会因为"简单问题少算、复杂问题多算"这种动态分配方式,出现结构性的下降,而不是单纯靠模型变小或者变便宜来降本。

写在后面

读这篇论文时,最触动我的不是"循环计算比不循环好"这个结论,这个结论其实符合直觉,多想想总归没坏处。真正让我停下来想了一会儿的,是改造版模型和原生模型之间那道明显的鸿沟。

同样是循环结构,同样多轮迭代,原生训练出来的Ouro能在NESTful上冲到35%以上的胜率,改造版的Llama却始终在个位数徘徊。这说明"循环"这个架构本身不是万能钥匙,它需要底层表征方式在预训练阶段就为这种反复推敲的模式做好准备。这让我想到学一门乐器,你光靠成年后天天练琴很难达到童子功那种肌肉记忆的水平,不是练得不够多,而是错过了神经可塑性最强的窗口期。模型的"童子功",可能就是预训练阶段。

论文里还有个细节我觉得该单独提一下:参数量更大的Ouro-2.6B反而在3轮左右就饱和了,不需要像小模型那样一路迭代到4轮才见效。这暗示着"想得深"和"想得远"某种程度上是可以互相替代的资源,模型越聪明,越不需要靠死磕轮数来补救。那么下一个问题自然就来了:如果继续放大原生循环模型的规模,它需要的迭代轮数会不会进一步减少,直到接近普通模型的一次前向推理?这条曲线最终会收敛到哪里,是这篇论文没有回答,但我很想知道答案的地方。

Q&A

Q1:循环语言模型和普通的大语言模型有什么区别?

A:普通语言模型是一层层不同参数堆叠、跑一遍就出结果,循环语言模型是反复使用同一组共享参数的模块对隐藏表示进行多轮加工,可以在不增加参数量的情况下增加推理时的计算深度。

Q2:循环语言模型在哪种工具调用任务上提升最明显?

A:在需要多步协同、维护调用之间依赖关系的复合任务上提升最明显,比如BFCL的Parallel、Parallel-Multiple类别和NESTful的嵌套调用任务,而在单次简单API调用的场景(如API-Bank)提升较小甚至不明显。

Q3:自适应推理和固定轮数推理相比有什么优势?

A:自适应推理让模型根据每个token的难度自主决定计算轮数,简单预测提前退出,复杂预测多算几轮,能用更少的平均计算量达到接近甚至超过固定深度推理的准确率,性价比更高。

广告

X 关闭

广告

X 关闭