先说一个数:27。
这是那篇论文里单步提交的中位行数。论文 11 月 2 日提交到 arXiv,编号 2611.02391,主分类 cs.RO,作者六个人。标题里那个 Late Autumn 大概只是时令,不用管。副标题写得直白:把一个通用的多机器人规划器专门化到一座仓库上。
结果是吞吐提升 22% 到 60%,六轮独立改进,在没见过的随机种子上也成立。这个数好卖,媒体会写这个。我盯的是另一处:最终补丁 0.7k 到 2.4k 行,由一串带评分的提交组成,单步中位 27 行。
27 行是这套东西能不能进主干的唯一理由。22% 只是它顺带的结果。
先把示意贴上。下面是照论文描述重画的调用形状,不是原文接口:
/* 示意,非论文原文接口名 */
plan_result_t plan(const site_t *site,
const fleet_t *fleet,
const task_queue_t *q);
site 是个参数。这意味着这个规划器得同时应付所有站点的布局、所有车队规模、所有服务时间,内部必然堆着一批分支去适配这些差异。作者干的事,是把这个 site 在编译期钉死成某一个仓库。
钉死之后,一条提交大概长这样:
- route = dispatch(q, site->layout, site->policy_cfg);
- if (site->policy_cfg == POLICY_ADAPTIVE) {
- route = refine(route, fleet);
- }
+ /* 本仓库三个出口,1 号口只走大车 */
+ route = exit_priority(q, 1, /*big_only=*/true);
二十来行。删一层通用分支,换一条只在这一个布局下成立的硬规则。这种东西,一个熟悉这个仓库的老师傅五分钟能看完,能当场说“1 号口确实只走大车”,或者“你漏了夜班那批货”。
2.4k 行的补丁给他,他只能看标题。
这里说句不太合群的话:多数人评估 AI 写代码的能力,看它一次能生成多少;我看它能不能把改动切到人能审的粒度。前者是生成能力,后者是工程能力,两码事。一个模型给你两千行没人看得懂的补丁,和没给一样。
不过我刚才那句话说得有点满。粒度只是可审的必要条件,不是充分条件——27 行如果每一条都在动同一个隐藏的耦合点,攒起来照样是一坨。
代价得说清楚。论文里有一条:部分补丁把规划器的计算开销放大了 100 倍以上。
100 倍开销换 22% 吞吐。这笔账划不划算,取决于你的瓶颈在不在 CPU 上。多数仓库的瓶颈在月台、在拣货员、在订单结构,不在这几个进程里。用算力换吞吐,在这类场景里便宜得离谱。但这不是通例——同样的事搬到一台边缘设备上跑,100 倍就是直接判死。
失败条件也值得单独摆出来:
同一套补丁挪到别的场景
另一种布局 大体能迁移
更大车队 大体能迁移
更小车队 收益缩水
出库任务主导 收益基本消失
出库主导下收益没了,这个我信。出库的约束在门口,不在路径规划里。你把路径调得再顺,货出不去还是出不去。专门化不是变魔术,它只能砍掉那些确实存在的浪费。
回到 27 行。它成立的另一半原因在评分回路。
# 示意,不是原文实现
score = throughput_after - throughput_before
if score > best_score:
keep(patch)
评分只看一个数,它就必然只看得到这一个数。论文里人工评审抓到过评分机制没抓到的问题——这不奇怪,评分是你自己定的那个指标,它衡量不了你没想到要衡量的东西。AI 自己给自己打分,盲区是结构性的,跟它努不努力没关系。
所以那 27 行是写给人审的。分数决定往哪个方向走,人决定这一步能不能落。
评分回路还有个副作用,我读的时候没想到:六轮活动,不同轮次独立指向了同一个性能瓶颈。这挺关键。方向稳,人才敢把注意力放在每一步的细节上,不用每轮都重新吵一遍“我们到底该优化哪”。
另一头,它重新发现的都是 MAPF 里早就有的机制:走廊出口优先级、局部引导、rollout 推演。这一点让我有点泄气,它没发明任何新东西。转念又觉得无所谓——专门化本来就不需要发明,它需要的是把已知的东西按这一个仓库的形状摆对。摆对这件事,人嫌烦,机器不嫌。
论文附了一份 frontier_steps.csv,辅助材料,我还真没打开。但从描述看,里面记的无非是每一步的行数、得分、留没留:
# 列名我猜的,示意
step lines score kept
41 27 1.8 y
42 31 1.9 y
43 19 1.2 n
这份文件比论文正文有意思。它是一条改进轨迹的原始账本,谁都能拿去对一遍。作者说专家有能力逐条审查,凭的就是这个账本加 27 行的粒度,不是凭“相信模型”。
说句题外话。我手头那个玩具存储引擎,第一版我想做“通用”,什么都能存;第二版想做“灵活”,什么都能换;第三版删到只剩存取。删的过程里最难的,是承认当初那些分支有一半从来没被走到过,而写它们的时候我觉得每一行都有用。
扯回来。
这套东西我不觉得是什么新范式。它是一个很朴素的分工:机器负责试,人负责审,粒度定在审得动的尺寸上。22% 还是 60% 不重要,重要的是那 27 行里,有没有一条人眼看不出来、会被生产环境看出来的东西。
最后一条规则:凡是 AI 交给你一个几千行的补丁,先别问它涨了多少,先问它能不能拆成 27 行一条。拆不出来的,先别合。