返回笔记

笔记

模型会用工具之后

aiagentsjudgmenttoolspost-training

最近,我把软件内部的一套私有调试接口交给了模型,包括强制渲染、读取数据变化、模拟操作、构造样本。这些 API 没有公开,模型此前也不知道它们的用法。

在这之前,代码已经给了模型相当多的信息,它能据此分析问题可能出在哪里。可软件的实际表现不对,还是得我去操作,截图,再描述哪里出了问题。截图这条路还要求模型具备视觉能力;碰上看不见的模型,就只能靠文字转述。模型负责改,我负责替它看。

拿到接口后,模型就能把对代码的理解和软件实际运行的情况对照起来,自己摸索调试方法。我没有替它写一套完整流程,只要求它操作真实软件,检查自己的判断。过去需要我截图和解释的异常,它开始通过 API 调用自己发现,还会主动构造不同的样本,检查边界条件。有些边界的探索,已经超过了我平时会主动构思的深度。用的甚至不是原生多模态模型。它看不见屏幕,却可以通过布局、事件和数据变化,拼出一双机器自己的眼睛。如果要形容以前的做法,那确实是在逼一个瞎子写代码。

模型会用工具以后,终于不只是在文本里描述世界,而是可以伸手碰到它。但这几次开发实验让我开始关心另一件事:当现有工具不足以回答问题时,它能不能发现自己看不见什么,决定怎样才能知道,再为这个问题创造对应的工具?

人类把这套动作叫作实验。

创造工具

命令行不是世界。它只是今天很容易给模型打开的一扇门。模型适合读写文本,终端又能把大量操作压缩成结构清楚的输入输出,所以不少智能体环境最后都长成了相似的东西:文件、日志、命令、脚本、Markdown,再套一层循环。

终端当然也可以提供丰富的观察能力。结构化状态、事件流、操作前后的差异,都可以从命令行里读出来。问题在于,我们有时只开放了文件和命令执行,就以为模型已经接触到了真实系统。一个软件能编译,进程没有退出,日志没有报错,不代表它真的表现正确。模型会写脚本,也不意味着它已经知道自己还缺少什么观察。

真实软件里有布局、渲染、事件、焦点、状态和用户操作。机器人面对的是传感器、电机、空间和物体。接口最终长什么样可以商量,关键是它让模型看见了什么,又允许模型改变什么。

模型也不必照搬人的界面。它可以拥有自己的感官:结构化状态、事件流、可控干预,以及能够直接检查结果的验证器。对于软件调试,这些东西有时比截图更有用。截图告诉模型某个地方“看起来不太对”,内部接口则可能直接告诉它对象在哪里,哪次操作触发了什么,哪些状态发生了变化。

视觉当然有价值,尤其是在面对无法改造的外部软件时。但在一个可以开放内部状态的系统里,让模型永远像人一样盯着像素,未必是最好的终点。

有时候,需要增加的动作甚至很简单。最近,我给几个独立工作的模型增加了一个通信渠道,并没有写一套“多 Agent 协作 SOP”。结果它们自己开始在发现跨项目依赖时联系对方,确认接口是否稳定、谁负责哪一部分、是否需要等待,然后各自继续工作。

最有意思的是,这些通信反而减少了真正需要协作的部分。几句话把边界确认清楚以后,结论经常只是:你做你的,我做我的,等接口稳定以后再接。

我没有教它们这套协作方式。我只是给了“去问另一个正在工作的主体”这个动作。这让我越来越怀疑,我们今天称作“模型不会”的一些事情,究竟有多少是能力不足,又有多少是它已经学会的概念,在当前环境里没有对应的动作。

这些知识要起作用,环境得允许相应的行动。观察和实验需要可读的状态与可控的干预;要处理另一个项目的依赖,就得能够联系到负责它的人。没有对应的动作,模型学过的道理就很难在任务里派上用场。

在这两次实验里,动作渠道仍然是我提供的,模型自己探索了用法。再往前一步,就需要它在已有渠道不够用时,自己发现缺口。

我所说的创造工具,就包括把原本不可见的状态变得可见,制造一次能够区分原因的变化,或者建立一个可以独立检查结果的验证过程。模型不能永远等着人替它准备好这些东西。它应该在卡住时意识到:“我现在缺的可能不是更长的推理,而是一只眼睛。”然后想办法把它造出来。

判断力

我们总说模型缺少判断力。相比执行、计算和生成,判断力仍然经常被认为是人类最珍贵、最难替代的部分。但在评价模型之前,至少应该先看看,我们究竟把哪些判断留给了它。

如果问题由人定义,工具由人提供,测试由人写好,验收标准已经封闭,模型拿到的就是一个整理过的世界。它仍然需要判断怎样完成任务,但那些关于问题是否成立、证据是否充分、验证方式是否合适的判断,已经提前替它做掉了。我们把这些判断拿走,再根据剩下的执行结果宣布它没有判断力,这个结论下得未免太草率。

甚至当模型表现出一点判断倾向,评价方式也未必欢迎。一个模型拿到任务后,先花半小时研究环境,确认哪些接口可以观察真实状态,再决定从哪里开始;另一个模型立即写代码,很快交出一个看起来能运行的结果。如果测试很窄,又只比较完成时间和 token,后者很容易占便宜。前者那半小时,却可能改变后面几个小时的工作质量。

调查当然也可能没有必要。判断力恰恰包括分辨这半小时值不值得,而这需要知道它消除了什么不确定性,不能只看它多花了多久。

真正的判断,经常发生在答案出现以前。假设一个界面没有正确更新。原因可能是数据没有变化,事件没有送到,布局没有重算,也可能前面的过程都正常,只是最终渲染没有刷新。如果模型不能把这些解释分开,给它再多接口也只是乱试。它可以翻完日志,跑完命令,再写几个调试脚本,最后仍然不知道自己究竟在找什么。

它首先需要意识到,当前缺少的是能够区分这些解释的证据。一个有用的问题是:什么现象会让我放弃现在的判断?围绕这个问题,模型才有依据决定继续观察,还是主动制造一次变化,需要什么工具也会逐渐清楚。

读取操作前后的状态,就能检查数据是否变化;记录事件流,则可以确认事件有没有送达。对于布局和渲染的问题,模型还可以主动触发相应过程,制造一次确定的状态变化,再检查最终输出。

创造工具和判断力因此很难分开。判断决定需要什么证据,证据决定应该造什么工具;新的观察回来以后,又会改变判断,让模型调整工具和路径。这已经是一套很熟悉的实验逻辑。面对几个都说得通的解释,我们寻找能够把它们分开的现象;现有测量没有分辨力,就换一种测法;单纯观察不够,就进行干预。

很多时候,判断力就体现在知道此刻缺少什么证据,以及应该怎样向现实提问。模型从语言里接触过这套逻辑。现在值得继续训练和检验的,是它能否在实际工作中主动使用,尤其是在问题没有被人整理好的时候。

如果它遇到不确定性时,开始判断当前的观察条件为什么不足以回答问题,并主动改变这些条件,那么提升的就不只是任务完成率。它开始扩张自己能够获得的证据。有些原本只能反复猜测的问题,会因此第一次变得可解。

品味

并不是所有问题都能靠实验收敛。两个实现可能都通过测试,两个界面也都可以正常使用,但我们仍然会觉得其中一个更好。一篇文章没有明显逻辑错误,读起来却还是一股流水线味。现成的验证程序很难替我们完成这部分判断。

一谈到模型的品味,讨论很容易被拖进意识问题,纠缠于它是否真的喜欢某个方案,是否拥有主观审美。在这里,我不太关心这些。

我更在意的是,模型在开始处理一件事之前,会不会先想一想什么样的结果算好,以及自己为什么这么认为。它已经从人类语言里学到了不少关于好坏的知识,应该尝试用这些知识形成自己的判断。接到任务后直接生成一个东西,再补一句“整体比较协调”,和真正先想过好坏,差别很大。

比如写一篇文章,模型可以先根据内容判断合适的语气。一段具体的开发经历,用直接、朴素的表达就能讲清楚;套上过于整齐的结构和一连串漂亮的总结,反而会把其中真正有意思的东西磨掉。先有了这个判断,再动笔,写出来的东西才有可能摆脱那些熟练的套路。

这不要求我们先证明模型真的“在品”。我只希望它能利用自己已经学到的知识,在执行之前做一次关于好坏的推理。判断可能会错,也会随着工作展开而改变,但至少它先有了一个经过思考的方向。

人类在这里的要求有时相当滑稽。我们希望 AI 像一个优秀设计师一样判断,又要求它像一个按钮一样响应,最好从头到尾不要提出异议。它真的顺从了,我们再回过头骂它没有观点,只会迎合。这和那些要求下属“大胆发挥”,最后每一处都必须改回领导意见的人,没什么区别。

人当然可以不同意模型的判断,也可以保留最终决定权。但既然希望它有品味,就得给它认真想过以后再动手的余地。

时间感

时间感一直在前面这些动作里。时间使观察具有寿命,使行动产生机会成本,使验证存在期限,也让模型知道自己是否真的在前进。

现在不少系统会在提示词里告诉模型:“当前日期是 2026 年 9 月 3 日。”这只能说明模型拿到了一个日期字段,并不代表它会把时间纳入判断。

假设我们在 8 月 20 日讨论某个在线服务的部署异常,下一次对话已经是 9 月 1 日。只要两段文字在语义上接得起来,模型就可能沿用上一次的判断,仿佛十二天只是两条消息之间的一次换行。但对于高速变化的线上服务,十二天已经很长。上次的观察仍然相关,却不能直接代表现在。

不同信息的寿命完全不同。一个架构原则过了半年仍然可能成立;一个部署状态过了两周就值得重新核验;一条“今天路上很堵”的记录,两个小时后都可能没用了。有长期记忆,却没有时间感,结果很可能是拿旧世界不断污染新世界。

两条历史记录互相矛盾,也未必需要判定其中一条错误。8 月服务异常,9 月恢复正常,它们可能都是真的。矛盾有时只是世界变化之后留下的两张截面。

时间也作用于模型自己。一个原本预计十分钟能够修好的问题,模型折腾了三个小时还没解决。即使期间没有出现新的报错,三个小时本身也已经是新证据。一个人类工程师到这时候,很容易冒出一个念头:这事不对。

这时候需要重新检查对问题的理解。问题分类、采用的抽象、关键输入,都可能值得回头看一遍,尤其要弄清自己是不是一直在重复同一种失败。“我他妈搞了三个小时还没搞定”,看起来像一句抱怨,其实包含了很强的元认知。

智能体却可能一直没有这个转折。它能数出自己尝试了多少次,却没有让已经花掉的时间影响下一次决策。每一轮推理醒来,眼前仍然只有一句“继续完成任务”。

它需要不断判断:这一段时间里,我到底有没有获得新的有效信息?花了很久,但正在逐步排除原因,可以继续。花了很久,却始终在同几条路上打转,就应该换路,重新理解问题,或者停下来找人。

时间同样会改变模型怎样与人协作。白天,用户一直在持续交互,说明他大概率就在。模型可以在必要时及时询问,趁用户在场把需要判断的地方确认清楚。到了深夜,用户已经几个小时没有参与,可能睡觉了。在已经授权的范围里,模型就应该尽量继续那些风险低、可以撤回的工作,别让一个无关紧要的问题阻塞整晚。

这也不能靠一句“晚上不要打扰用户”解决。用户可能凌晨两点还在疯狂开发。模型需要结合当前时间、最近一次交互、任务进度和风险,判断用户此刻是否可用,以及怎样协作更合适。

任务执行期间,世界和用户的状态都在变化,原先没想到的问题也会陆续暴露。一个目标不应该把执行策略从头到尾钉死。时间会改变原来的证据是否仍然可信,当前工具是否合适,什么时候继续实验,以及什么时候承认自己已经卡得太久。

后训练

前面的两个实验,让我开始重新理解后训练应该承担的任务。观察接口开放以后,模型开始自己发现异常、构造样本。通信渠道开放以后,它开始确认依赖、协商边界。我没有在这个过程中重新训练模型,也没有逐步安排这些行为。至少在这些任务里,我不需要从头教它什么叫观察、实验或者协作。

但在一个任务里做出来,与在不同环境、长时间运行和连续受挫之后,仍然能够主动选择这些动作,还有很长的距离。不同模型在这里的表现也可以很不一样。有的模型看到新的能力,会主动探索它能做什么;有的模型即使知道工具存在,也要等到提示词明确要求才会使用。

我们当然可以把要求写进提示词:修改之后必须验证,旧信息需要检查时间,缺少观察能力时尝试创造工具,长时间没有进展时重新评估。任务刚开始时,模型可能会认真遵守。但经历几十次工具调用、几轮方向变化和上下文压缩以后,这些要求能否继续约束行动,就又成了问题。写在提示词里,并不等于已经成为可靠的工作方式。

我希望后训练能够缩小的,正是这个距离。模型遇到几个无法区分的解释时,应该主动寻找更有分辨力的观察;如果长时间仍然没有进展,就该检查当前路线。品味也是如此:在开始生成之前,先根据任务想清楚自己认为什么样的结果更好。

这些行为也不能只按动作数量奖励。跑了很多测试,仍然可能漏掉真正的问题。前面那个通信案例里,最有价值的结果,恰恰是确认边界以后各自继续工作。需要训练和评价的,是模型能否在合适的时候采取这些动作,以及动作带回来的信息有没有真正改变判断。

后训练可以让这样的选择更主动、更稳定,但它仍然需要一个允许行动的世界。观察和干预有赖于系统开放状态、允许操作,协作需要通信渠道。即使模型懂得时间的意义,运行时也得持续提供可靠的时间和状态变化,它才有依据判断。

预训练让模型接触了大量关于智能行为的知识,运行时为这些知识提供可以落地的动作,后训练则应该让模型更可靠地选择和使用它们。这几件事需要一起发生。

最近这些开发实验让我越来越关心的,是模型怎样处理自己的不知道。发现证据缺口之后,它应该有办法改变观察条件,让现实参与推理。如果尝试始终没有带来新信息,也应该能够承认当前的办法已经不值得继续。

模型可能没有我们想象中那么缺少这些概念。我们却太习惯把它放在一个没有眼睛、没有手、没有同伴,连时间都只剩一个日期字段的环境里,然后问它为什么不像一个真正活在世界里的智能体。别再只让模型解释这些概念。

让它在不知道的时候,先决定怎样才能知道。

本页目录