给 AI 一场实验

我开始编写提示词,向模型解释贪吃蛇实验。

提示词描述神经网络、可调参数、参数范围、当前配置,以及看起来相关的实验历史。Fr3d 然后选择一个参数值,通过 Snake Lab API 提交新实验。

整个过程形成一个循环:

提示词 → LLM → 配置 → Snake Lab → 结果 → 提示词

令人惊讶的是,它很快就跑通了。

虽然算不上优雅。

但真的能工作。

我已经有一个可用的贪吃蛇配置,最高分大约是 38;而且经过几个月对 RNN 的手动试验,我知道还存在更好的配置。所以 Fr3d 面对的是一个真实的问题。

这不只是让 LLM 生成看起来像样的 JSON。

它必须根据真实实验结果作出决策。


对视觉模型的短暂尝试

差不多在这个时候,我试用了 Qwen 2.5 VL,也就是模型的视觉语言版本。

这个想法很诱人。

也许我不必用数字描述所有内容,而可以把贪吃蛇实验的图表甚至图像交给模型,让它通过视觉分析发生了什么。技术上确实可行,但我很快遇到更重要的问题。

视觉模型的推理能力不如 Qwen 3.5。对于这个应用来说,推理能力远比视觉重要。

Qwen 3.5 还能展示推理过程,这对提示词开发极其有帮助。我能看到模型认为我在要求它做什么。有时候,它几乎是在明确告诉我:

“这提示词根本不合理。”

当然,它未必会真的这么说,但意思就是这样。

有时我要求它选择一个未使用的参数值,却从推理过程中发现,所有合法值其实都已经用过了。有时我遗漏了模型显然需要的某段实验历史。还有时我用自己觉得非常清楚的数据结构组织信息,却让模型难以判断哪些数值可以直接比较。

阅读推理过程使这些缺陷显露出来。

这大概是我对提示词工程的第一堂真正的课。一个糟糕的回答,不一定是模型的问题。有时只是你提出了一个糟糕的问题。


提示词工程就是软件工程

开发 Fr3d 之前,我主要把提示词看成指令。到了项目后期,我越来越觉得它们更像接口。

模型只能根据你提供的信息进行推理。信息结构很重要,术语很重要,约束很重要,所包含的历史记录也很重要。

如果你让模型从搜索空间里选择一个值,它就必须知道搜索空间是什么。如果必须避开之前测试过的值,它就需要可靠的已测试值记录。如果不同随机种子的结果不能直接比较,提示词就必须明确这一点。如果提示词里有互相矛盾的要求,LLM 遇到的问题,就和程序员面对矛盾规格说明时一样。

提示词已经成了系统架构的一部分。


原型的问题

大约一周后,Fr3d 跑起来了。

但代码糟透了。

并不是因为某个模块特别复杂,而是因为我一边弄清系统究竟应该做什么、一边研究底层代码,程序就这样自然生长起来了。

这就是熟悉的原型阶段:软件从技术上说能工作,但理解它为什么能工作却越来越困难。这时,我又意识到自己做错了另一件事。


报告本该是一等功能

我一直把日志和报告视为附加在实验周围的功能。这个顺序完全反了。对于自主实验系统来说,可观测性就是实验的一部分。我需要轻松回答这些基础问题:

一堆日志文件在技术上也许能回答这些问题。但“技术上能找到答案”和“系统真正容易理解”,完全是两码事。下一代系统必须从一开始就围绕报告能力设计。


找到边界

Fr3d 还教会了我如何识别自然的模块边界。

有些部分是通用的:

另一些则是这个实验特有的:

在 Fr3d 中,这两类职责纠缠不清。当我看清这个区别,下一版架构就变得明显多了。


从头开始

面对一个能运行的原型,人总想继续修修补补:重构一部分,移动一个函数,抽取一个类,整理提示词,删除重复代码。

但我决定不这样做。

Fr3d 已经完成了自己的使命。它证明了想法可行。更重要的是,它让我了解真正的难点在哪里。这些信息极有价值,而且很难通过事先设计完美架构得到。所以,我保留教训,抛弃原有架构。

我从 Fr3d 得到的结论不是动手之前先把一切设计正确,反而几乎正好相反。

Fr3d 很凌乱,但它确实能用。正因为它能用,我终于知道下一步该建造什么。


链接