正在加载页面…
交互界面暂未加载完成。你可以先阅读下方内容,或刷新重试

Kaggriculture:我把一个种田AI改了19版,然后发现版本号真的没什么用

我一开始参加Kaggriculture,并不是因为我有多喜欢模拟经营。 我当时的想法其实挺俗的:找一个Agent方向的Kaggle比赛,最好不需要手工标数据,不需要训练特别大的模型,代码可以主要交给AI完成,然后看看能不能比较快地混到一块奖牌。 Kaggriculture看起来正好符合。 它是一场双人种田比赛。两个Agent在同一张地图上种地、养动物、雇工人、建牧场、买东西、卖东西,最后谁的钱多谁赢。 听起来有点像《星露谷物语》,实际写起来更像一个不会给你报错、只会默默把钱亏光的小型量化系统。 每局有720个状态,Agent每回合都要返回动作。市场还是双方共享的:你卖得早,可能吃到高价;你卖得

我一开始参加Kaggriculture,并不是因为我有多喜欢模拟经营。

我当时的想法其实挺俗的:找一个Agent方向的Kaggle比赛,最好不需要手工标数据,不需要训练特别大的模型,代码可以主要交给AI完成,然后看看能不能比较快地混到一块奖牌。

Kaggriculture看起来正好符合。

它是一场双人种田比赛。两个Agent在同一张地图上种地、养动物、雇工人、建牧场、买东西、卖东西,最后谁的钱多谁赢。

听起来有点像《星露谷物语》,实际写起来更像一个不会给你报错、只会默默把钱亏光的小型量化系统。

每局有720个状态,Agent每回合都要返回动作。市场还是双方共享的:你卖得早,可能吃到高价;你卖得晚,对面可能已经把价格砸下去了。

而且你不能联网,不能在比赛里临时调用大模型。最后提交上去的就是一个纯Python文件。

所以这次所谓“用AI打Kaggle”,不是让大模型坐在农场里一回合一回合地指挥工人,而是让AI在比赛外面做研究:读规则、看公开方案、写代码、跑测试、复现败局、打包版本,然后我再决定要不要提交。

截至2026年9月22日,我们的队伍“哈基米南北路多”暂时排在 第62 / 9808,分数是 2818.0,大概在前 0.63%

当前银牌线是2596.5,金牌参考线是2898.5。

也就是说,银牌位置暂时还算稳,离金牌差80.5分。

但这只是临时榜。比赛没结束之前,谁都不能说自己真的拿到了奖牌。Kaggle这种东西,最后几天突然冒出一批人把你往后挤,也不是什么稀奇事。

刚开始的时候,我以为胜率高就够了

第一份提交其实很普通。

代码能跑,动作格式没问题,不会在720回合中途暴毙。我把它交上去以后,看着分数从600一点点往上涨,最后涨到了2160.1。

战绩是18胜1负。

当时看着还挺激动:19场赢18场,这不挺强的吗?

后来才发现完全不是这么回事。

新提交一开始匹配到的通常也是低分对手。你打低分对手打出十几连胜,并不能说明你能打赢排行榜前面的人。

甚至后面还发生过更离谱的事情:某个版本58胜9负,分数只有1425;还有一个版本98胜6负,分数却只有2333。

所以Agent比赛里的“胜率”很容易骗人。

你赢了谁、输给了谁、对手本身是什么评级,这些都很重要。单看一个“胜率95%”,很容易以为自己已经天下无敌,实际上可能只是在新手村刷怪。

前几个版本基本是在抄作业,但抄作业也没有想象中简单

V3到V5主要是在复现和组合社区里的公开策略。

这里也没什么不好意思说的。Kaggle本来就允许使用公开Notebook,比赛社区里也有很多很强的Agent。问题不在于能不能参考,而在于你到底有没有搞清楚那份代码为什么有效,以及你改完以后有没有把它改坏。

早期版本加入了不少东西:

  • 更成熟的生产路线;
  • 开局资金保护;
  • 根据对方公开状态调整开局;
  • 提前出售可能被压价的商品;
  • 仓库容量保护;
  • 饲料、雇工和市场订单保护。

这几个版本很快把分数推到了2500附近。

这个阶段最大的收获不是分数,而是我终于不再满足于“它能打赢starter”。

我们开始让两个版本在同一个初始世界、同一个座位、同一个对手下面分别跑一遍,然后比较它们到底在哪些地方产生了差异。

现在看起来这很正常,但刚开始的时候确实没有这么严谨。最早的思路基本就是:这个改动听起来不错,先跑几局,赢了就交。

后来的很多坑,都是这种心态留下来的。

V8是第一次让我觉得,这东西可能真能拿牌

V6和V7主要解决的是市场竞争。

如果双方采用差不多的生产路线,那两边很可能在差不多的时间卖同一种商品。共享市场里,先卖的人通常价格更好,后卖的人就只能接被砸下来的价格。

最简单的办法当然是:那我什么都提前卖。

我们真的试过。

效果也确实很好——在一部分相似对手上特别好。

然后它把另外两场原本能赢的比赛改输了。

这件事后来反复发生:一个规则在它熟悉的场景里像神一样,在不熟悉的场景里像个拆迁队。

所以V7最后没有无条件提前卖货,而是先观察双方的公开状态。只有确认对方和我们走的是近似路线时,才扩大预售窗口。

V8则继续调整第6天的生产路线。简单来说,如果前两家商店里出现毛线店,就切换到更适合的既有路线。

这听起来不像什么惊天动地的创新,甚至有点朴素。

但最后真正有效的改动,经常就是这种东西。

V8冻结后跑了143场正式测试,结果是116胜、8平、19负。所有对局都完整跑完720状态,没有中途报错。

上传以后,V8最后达到了 2814.5分

这是我们第一次真正进入高位银牌区域。

看到这个分数的时候,我当然觉得后面还能继续涨。毕竟V8都已经这样了,再做个V9、V10,不是很自然就能摸到2900甚至3000吗?

事实证明,这个想法非常乐观。

V9和V10让我交了一次很贵的学费

V9做的是市场订单清理。

本地165场测试里,它把很多平局变成了胜局。上线以后,开局甚至一度28连胜。

那段时间看起来特别美好。

最后V9停在了 2722.9分,比V8低。

V10继续优化卖单顺序。本地247场配对测试中:

  • 26场改善;
  • 221场不变;
  • 0场退化。

看到“0场退化”的时候,很难忍住不提交。

于是V10被上传了。

但Kaggriculture只保留最近两个活跃提交。V10进去以后,当时分数最高的V8被挤出去了,团队分数和排名立刻下降。

而V10最终只有 2684.9分

也就是说,我们用一份“247场测试零退化”的候选,换掉了一份已经在线证明能到2814.5的版本。

这件事后来一直影响我们的提交流程。

本地所谓“零退化”,只能说明在那247场里面没有观察到退化。它不代表在整个排行榜的真实对手分布里也不会退化。

听起来像一句废话,但不真的亏一次分,很难对这句话有那么深的印象。

V11到V15,版本号开始像一部拍烂了的续集

后面几个版本尝试得越来越多:

  • V11试图收窄市场压缩的触发条件;
  • V12针对部分商店组合调整养什么动物;
  • V13继续修改路线和羊牛选择;
  • V14改成更保守的饲料优先开局;
  • V15尝试推断对手销售、提前卖肥料、重新排列卖单,以及在第9天切换乳品路线。

单看实验报告,其中很多版本都挺漂亮。

有的版本能把历史败局翻过来,有的在所谓“精英对手面板”上进步很大,还有的平均能多赚几十、几百金币。

问题是,这些数据很多都已经被我们反复看过。

如果你对着同一批11场败局不断调参数,总能找到一个“能修好其中10场”的版本。这和考试前提前拿到题目差不多,做对并不说明你真的学会了。

V15后来做了一次更严格的复测。

我们拿V8重新提交后产生的32场新对局,把V8和V15放在完全相同的条件下重新运行。

结果是:

  • V8:26胜6负;
  • V15:26胜6负;
  • V15平均只多了0.09375金币;
  • 没有新增胜场;
  • 还有两场小幅回退。

平均多赚0.09375金币,这个数字看起来甚至有点喜剧效果。

所以V15最后的正式结论是:不晋级。

到了这个阶段,我们终于开始接受一件事:版本号从V14变成V15,并不意味着任何东西。

V16先失败了一次,然后我们换了思路

最初的V16尝试根据对手的公开生产压力,决定是否把商品提前更多回合卖出。

开发集上有一些收益。

但冻结以后,时间顺序留出是8胜8负,平均分差下降53.3,最差一场退化625。

于是这个版本也被拒绝了。

后来的V16不再继续调整这套卖货参数,而是直接换用了更强的公开V53核心,再加入受保护的闲置工人种麦。

它最后在线达到 2521.9分

这不是一个特别高的分数,但它告诉我们:与其在一个已经落后的核心上叠第十层补丁,有时候不如先承认基线选错了。

V17也是类似的过程。

它中间有一版换了核心,却漏掉了旧版本里“三单位额外收麦”的机制。结果新核心看起来更先进,实际整体表现反而下降。

最后我们把这个机制重新接回来,再把多层公开调度中的旧核心升级为完整Metav4 v13,并加入一个相对保守的卖单顺序求解器。

冻结后的96局里,V17取得82胜14负。

上线后,V17达到 2658.3分

这个分数依然没有超过V8,但至少说明方向开始重新变得正常。

V18的突破,不是来自更聪明,而是来自少犯一次蠢

V18一开始只是想优化最后一天。

到了比赛末尾,一些工人其实已经没有重要任务了。V18会让这些工人补收附近的产品,计算剩余路程,及时回仓,然后在结束前卖掉。

这个改动有用,但只能算小幅提升。

真正让V18发生变化的,是一场线上大败。

我们把那场比赛完整复现以后,发现问题并不是什么神秘的高阶博弈。

V17在开局时额外种麦,又做了一笔市场交易,结果第24步现金只剩1元。

它原本计划雇3个工人,最后只雇到了1个。

少掉两个工人之后,后面的一切都开始出问题:牧场建不起来、动物喂不及时、产品运不回来、下一轮种植资金也不够。

一开始只少了几块钱,最后却变成整条生产链断掉。

V18增强版没有加什么复杂模型,只改了三件事:

  • 把开局小麦交易从“买20卖15”缩小成“买10卖5”;
  • 等真实现金结算后,再决定要不要额外种麦;
  • 提前给基础种子和第二天雇工留钱。

在针对这个故障构造的反应式压力测试里:

  • V17是0胜16负;
  • 新V18是15胜1负。

V18上传以后,一路涨到了 2818.0分,超过了V8原来的2814.5。

有时候一个版本变强,不是因为它学会了什么新技巧,而是因为它终于不再在第24步把自己花到只剩1元。

V19又给我上了一课

V19继续改进最后一天的联合收获、交仓和出售调度。

本地冻结测试很好看:

  • 对三套公共策略,V18是60胜12负,V19是70胜2负;
  • 直接对V18,V19是24胜0负;
  • 平均金币分差也明显提高。

所以我们上传了V19。

截至写这篇文章时,V19已经打了104场,战绩是 98胜6负

然后它的分数是 2333.2

对,98胜6负,2333.2分。

而V18是97胜1平40负,分数2818.0。

如果只看胜率,这两个数字完全不讲道理。但如果考虑到对手强度和评级路径,它又是可能发生的。

V19目前赢下的比赛很多,却未必击败了足够多的高分对手。V18输得更多,但它可能在更成熟的高分对手池里拿到了更有价值的胜利。

所以现在还不能说V19一定失败,也不能拿98胜6负宣传它已经超过V18。

它只能继续打。

回头看这19个版本

截至2026年9月22日,比较关键的线上版本大概是这样:

| 版本 | 分数 | 胜 / 平 / 负 | |---|---:|---:| | 第一份提交 | 2160.1 | 18 / 0 / 1 | | V4 | 2517.9 | 73 / 0 / 27 | | V5 | 2511.6 | 84 / 0 / 26 | | V8 | 2814.5 | 64 / 1 / 33 | | V9 | 2722.9 | 126 / 0 / 91 | | V10 | 2684.9 | 155 / 0 / 57 | | V11 | 1521.6 | 33 / 0 / 32 | | V12 | 2414.7 | 79 / 0 / 31 | | V13 | 2501.7 | 69 / 0 / 50 | | V14 | 2188.6 | 69 / 0 / 27 | | V15 | 1425.9 | 58 / 0 / 9 | | V16 | 2521.9 | 95 / 0 / 70 | | V17 | 2658.3 | 129 / 0 / 19 | | V18 | 2818.0 | 97 / 1 / 40 | | V19 | 2333.2 | 98 / 0 / 6 |

这张表看久了,会觉得版本号和分数之间甚至有一点反向关系。

当然,这也不能完全怪策略。不同提交遇到的对手、比赛数量和评分路径都不一样。但至少它足够说明:不能因为本地多赢了几十场,就直接宣布“V19全面超过V18”。

AI到底帮我做了什么

如果只说“AI帮我写了代码”,其实不太准确。

这次AI真正做的是一整套比较琐碎、但又很重要的工作:

  • 下载排行榜和提交状态;
  • 收集公开回放;
  • 提取公开Notebook中的Agent;
  • 检查许可证和保留作者署名;
  • 复现历史比赛的最终金币;
  • 记录每一笔真实成交;
  • 自动生成成对实验;
  • 找出胜变负、负变胜和最坏退化;
  • 检查720状态是否完整;
  • 测试关闭新增功能后是否与父版本逐动作一致;
  • 生成只有一个main.py的提交包;
  • 计算源码和压缩包的SHA-256;
  • 上传后继续观察分数和胜负。

我做的事情反而比较简单:提出目标、决定能不能接受风险,以及在真正消耗提交次数之前给出授权。

当然,中间也经常出现“AI一本正经地证明一个候选很好,然后线上分数告诉我们并不是”的情况。

但换个角度想,这可能也是这次比赛最好玩的地方。

最后总结几个教训

第一,固定回放不是真实对手。

它适合复现问题,但当你改变了市场以后,对手还在按照旧世界的动作行动。这样测出来的胜利不能直接外推到线上。

第二,平均多赚钱不等于更容易获胜。

一场从-10变成+10,比十场各多赚20但胜负不变更有价值。

第三,不要反复对着同一批败局调参数。

调得越久,报告越漂亮,泛化往往越可疑。

第四,一定要检查真正上传的入口。

一个文件里可能存在很多层Agent包装。你以为上传的是完整版,实际最后被Kaggle加载的可能是更早的一层。

第五,上传是有成本的。

最近两份提交才是活跃版本。新版本进去,旧版本就会被挤出去。我们已经因为这件事丢过一次当时最好的线上分数。

第六,也是最重要的一点:

不要为了做V20而做V20。

如果V19没有通过真实对局证明自己,那么最合理的下一步不一定是立刻写一个V20,也可能是继续等它进入更强的匹配池,或者认真看它输掉的那6场到底发生了什么。

现在的结果

截至这篇文章的数据快照:

  • 团队排名:62 / 9808
  • 团队分数:2818.0
  • 临时银牌线:2596.5
  • 临时金牌参考线:2898.5
  • 距离临时金牌线:80.5分

当前最可靠的线上版本仍然是V18,而不是编号更新的V19。

比赛还没有结束,所以我也不知道最后到底会停在银牌、掉回铜牌,还是还有机会摸到金牌。

不过就算最后排名不再变化,这个项目对我来说也已经不只是一个Kaggle分数了。

它更像是一套被失败一点点逼出来的Agent研究流程:

先复现,再归因;先冻结,再验证;别删失败数据;让线上结果推翻本地自信。

听起来还是有点像总结报告。

但没办法,吃过的亏确实就是这些。