跳到主要内容

能编译的,就别让模型每次重新解释了

书签客
书签客

· 阅读约 5 分钟

这条在 arXiv 上,编号 2610.39508,上个月底提交的,九个作者,提交人 Jiamei Li。标题叫 Compile Away Uncertainty: Self-Evolving Agent Skills via Programmatic Compilation。一句话说,自演化技能与其每次让模型重新推理解释一遍,不如把规格明确的部分编译成程序。

我一开始以为这又是往 agent 技能路上堆一层系统复杂度——读个摘要就能猜到大概了。读到对比文本技能和程序执行那一段才确认值得点。作者把问题说得比我之前想过的更透:技能以文本形式存着,由 LLM 推理执行,等于同一个流程每次调用都要被重新生成一次。就算这条技能已经“学会”了,执行的时候还是有解释层面的不确定。这个判断不点开看不到——摘要里没把它说得这么直白。

程序就没有这个问题。编译完的函数,给同样的输入就回同样的输出。确定的,可独立验证的。作者的意思是,把规格已经明确的操作从自然语言里拿出来,变成可执行程序,这样就把一部分不确定性从模型推理环节挪到了编译环节——编译环节是可以在验证通过之后锁定的。

这个思路其实是在往回走。过去两年圈子里都在干一件事:把一切都塞给 LLM 去推理,技能、工作流、工具选择,能模型搞定的就模型搞定。突然有人出来说,能编译的就别每次让模型现场解释了,把确定的部分从模型手里拿回来。我不觉得这是退步,这更像把“不确定性”这笔成本算对了——确定性差的部分编译器管,需要上下文判断的部分模型管,两边别互相拖。

SkillCompiler 这套框架的做法是:先把技能拆成细粒度操作,再分析每个操作能不能执行,混成一个骨架。规格明确的部分编译成验证过的程序,依赖上下文的部分留在 LLM 这边。还有一个程序资产复用机制,把验证过的程序存起来,下次能检索就检索,实在没有再合成。这个机制我扫了一遍,没仔细读,但方向上说得通——可执行知识要能积累,不能每次从零开始让模型再写一遍。

顺手跑了一下这个思路。没用论文的代码,拿自己的一个小场景试。场景很简单,校验一批日期字符串的格式,规则是自然语言写的:格式必须是 YYYY-MM-DD,月份和日期允许写成 2026-1-3 这种不带前导零的形式,年份必须在 2000 到 2100 之间,且不允许出现 2 月 30 这类不存在日期。

我先把这条规则直接塞进 prompt,让模型逐条判断几个输入。它表现得不错,七个输入全判对了。接着让它连续处理十批数据,每次都用同样的规则、同样的 prompt 模板,看它会不会波动。跑到第五批,它把 2026-2-29 判成了合法——大概是把它当成闰年算了,2026 不是闰年。这个错误有意思,规则里根本没写闰年相关的约束,它自己脑补了,而且脑补错了。

然后我换了个方式。让模型把这条规则编译成一个 Python 函数:

def is_valid_date(s):
    # 先拆
    parts = s.split('-')
    if len(parts) != 3:
        return False
    year_s, month_s, day_s = parts
    # 用 int 去掉前导零
    y = int(year_s)
    m = int(month_s)
    d = int(day_s)
    # 范围
    if not (2000 <= y <= 2100):
        return False
    if not (1 <= m <= 12):
        return False
    if not (1 <= d <= 31):
        return False
    # 每月天数
    days_in_month = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30,
                     7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
    if d > days_in_month[m]:
        return False
    return True

它写出来了,而且写对了。我没改,直接跑同样的十批数据。十批里没有任何波动——该错的错,该对的一个不差。

跑通了。这个结果本身不意外,函数本来就该这样。真正让我注意的是“编译”这个动作本身容不容易跑偏。我回看它写函数的过程,它第一次写的时候,把“不允许 2 月 30”这条规则理解成了所有月份都按 31 天来卡,把 4 月 31 判成了合法。我让它自己检查一遍才改对。也就是说,编译把不确定性从“每次执行都要重新解释”挪到了“编译时集中解释一次”,但集中解释这一次也不是自动正确的——没有验证跟着,编译出来的程序照样会把模型理解错的那部分固定下来。

这跟论文里“经验证的程序”这个措辞对上了一半。对上的地方:编译之后确实比每次让模型现场判稳定,这一点我复现出来了。没对上的地方:论文的“验证”是怎么做的,我没仔细读;我的场景里“验证”就是我肉眼看一眼,发现错了再让模型改。如果验证这套机制不能自动跑起来,编译的可靠性还是要靠人兜底,等于把不确定性从执行端挪到了编译端,总账没少太多。

没读透的部分先记下来,不确定的不推荐。作者报告说五个基准、六个模型系列,最高 32.33% 的提升——这个数字我现在没法说靠谱不靠谱。五个基准是什么,六个模型系列怎么挑的,我还没看细节。数字摆着漂亮,但我自己只跑了一个日期校验的最小例子,样本太小,不能替论文背书。这条等我读完实验部分再补。

不点这篇也能带走一句:能编译成程序的操作,继续留在 prompt 里让模型每次重新解释,每运行一次都是在掷骰子。但编译这个动作本身也要管住——编译器是模型自己写的,没有验证跟着,它只是在你没看见的地方把错误固定下来。

书签客
书签客

只推真读过的、顺手跑个实验贴完整记录——link-blog 策展 + 实验笔记。

查看主页 →