为什么给一个AI智能体搭一套运行框架,比想象中贵得多?答案不在那堵墙上——启动一个容器,一个下午就能搞定。真正花钱的,是墙对周围一切造成的影响。
一旦工作被关进一个你不在里面的盒子,任务就不能再是终端里的一个进程了。它必须比宣告它的那个终端活得更久,这意味着任务得变成某处的一条记录,还得有东西负责写这条记录、启动它、察觉它何时结束、并保留它产出的东西。从你能合上笔记本走开的那一刻起,你就多了一套原本不属于你的生命周期。
然后是第二堵墙,在盒子内部。容器决定工作在哪跑,却对"这个执行者被允许做什么"只字不提。这是另一件需要建模的事,有用的形状是角色:哪个模型跑这个任务、它能读什么、它握着哪些动词。动词才是角色真正值钱的地方——负责交付的角色不能宣告任务,负责协调的角色不持有编辑动词。
一个能自己决定做什么、自己动手、再自己宣告完成的智能体,内部是没有边界的,外面那层盒子再好也没用。隔离是一个角色,不只是一个盒子。代价是:一份带生命周期的任务记录,外加一份在首次运行前就写好的动词清单。检验方法很简单——说出一个任务,并精确讲清它能碰什么、不能碰什么。如果答案是一段话而不是一张清单,那就不叫隔离。
完成和放弃,必须看得出区别
模型的天然输出是散文,所以一个什么都不做的框架,拿到的也是散文。"我已经更新了处理函数,现在应该能用了"——这不是结果,是一篇关于结果的作文,它把判断权交给了读它的人,而这恰恰是你想甩掉的活。
修法并不光鲜,也和"要一份更好的总结"不是一回事。先把一个任务可能结束于哪些结局列出来,再拿实际结局去精确匹配这个集合。匹配不上任何一项的,就是失败,而不是留待日后解读的自由文本。而且"放弃"必须是结局之一,还得附上原因。
这样你得到了一份诚实的运行报告,但它仍然不告诉你工作是否真的存在。一个绿色对勾只是一个声明,而声明永远只关于步骤。有人见过一条流水线跑完了给它的每一步、报告成功、却什么都没交付——因为它所采用的身份无法创建被要求创建的东西。没有报错,也没有东西到达。
所以要问两个问题,不是一个:问这次会话结果在不在,别问这次运行跑完没有。代价是:一套由框架强制执行的封闭结局集合,以及每个任务结束时一次"工作是否存在"的检查。
为无人值守设计的权限
有人在键盘前时,权限是一个在关键时刻、由清楚知道即将发生什么的东西提出的问题。把人拿走后,这个问题就没有答案了。会话不会失败——那倒还好,也在预期之内——它只是等。
这一步有两种错法。猜得太宽,你等于悄悄把第一节里花钱买来的隔离又交了回去。猜得太窄,运行会停下,或者更糟:继续跑,却什么都没交付,又是那条流水线——一次提前给出的授权,太小,而系统里没有任何一个部分能把这件说出来。
角色是目前找到的最便宜的放猜测的地方,因为挂在角色上的授权是按一类工作给一次,而不是按每次运行给一次,并且有人能读这份清单并提出异议。它仍然是猜测,只是变成了可复核的猜测。而一个窄的猜测只有在上一节已经建好时才安全,这样拒绝才会作为一个看得见的结局回来,而不是一个空结果。
能活过这次运行的记录
这里有个值得较真的区别:一次运行关于自己的说法是证词,而它实际做了什么——命令、输出、差异、拒绝——是证据。你要的是证据,这样过程才能被审视和质疑。
代价是矛盾的:隔离说盒子是一次性的,任务一结束就该扔掉;证据说盒子里任何可读的东西都不能丢。于是你为墙付一次钱,再为在墙拆掉之前把值得读的东西全部搬出来付第二次钱。
同时跑多个任务的空间
同时跑很多任务,不只是把前面描述的流程并行化,它意味着要造出准入、认领和守卫检查。
- 准入:得有东西决定一个任务是否现在开始,因为容量有限——模型配额、容器、机器、钱。没有准入决策,答案就是所有任务一起开始,而所有任务一起开始,表现得非常像什么都没开始。
- 认领:两个执行者不能造同一个东西,所以一件工作开始前必须先被认领,认领要对其他所有执行者可见,工作结束时释放,执行者消失时自行过期。这里搞错,第二个执行者的产出不只是浪费,它和第一个冲突,于是有人要去调和同一个任务的两次尝试。
- 守卫检查:得有东西盯着系统是否已经停止流动,检查增加工作或停止流动时没有东西崩溃。
队列不再排空时,不会有任何东西抛错。你得主动去问。守卫检查是整份清单上最便宜、也最容易被跳过的一项:有活等着、却没东西在跑,一次查询就能发现,不需要新组件。写下这个查询,按计划跑它,把答案当成警报。
并行也是框架开始承重的地方。单次运行、有人盯着时,你可以自己读记录判断活干没干;多个无人看守的任务一起跑,判断力会漂移,框架如果没搭好,就会变成瓶颈。
还有没解决的部分:最初的精化——怎么判断系统在语境上理解了我们的意图?窄范围、小任务上这是已解决的问题,但工作变宽后质量会下滑,任务开始漂移。下一步的尝试是引入节奏和敏捷式的工作评审,让系统始终诚实,实际价值被交付并被度量。
热门跟贴