你调一个函数,改参数就行:
f(x, threshold=0.7)里把 0.7 改成 0.9,行为立刻、确定、可预期地变了。你想”调”一个大模型呢?它有上万亿个参数——但没有一个是给你拧的。你想调 Claude Code 呢?它甚至不只是个模型,是模型外面套了一整层系统。这篇回答一个看似简单的问题:这三种东西的控制面各在哪里?答案连起来是一条主线:计算史就是控制面的一路迁移,每次迁移都在拿”逐行的确定性”换”能力的上限”——然后人类马上开始在新的一层重建确定性。
先把”控制面”这个词说死
控制面(control surface)不是黑话,就是字面意思:你能动的那些东西的集合,动了之后系统行为会变。但光”能动”不够,一个合格的控制面要过三关:
- 能拧:旋钮是你摸得到的——你知道它在哪,有权限改它。
- 能预期:拧之前大概知道会发生什么,拧多少对应变多少。
- 能验证:拧完能查——行为变化能追溯回”是我拧了这个”。
普通函数三关全过。threshold=0.7 改成 0.9:旋钮就在源代码里(能拧),效果看一眼逻辑就知道(能预期),出了问题 git blame 直接定位到这一行(能验证)。源代码是人类发明过的最完美的控制面——这正是接下来所有故事的参照物。
第一次迁移:控制面沉入权重,旋钮消失了
Karpathy 在 2017 年把这次迁移命名为 Software 2.0:软件 1.0 是人直接写代码,软件 2.0 是人给数据和目标,让梯度下降去”写”权重。表面看,控制面从”几千行代码”换成了”上万亿个参数”,旋钮变多了——实际恰好相反:
参数多到一定程度,就没有一个参数还是旋钮。拿三关一验:单个权重你确实能改(能拧),但改了会发生什么?没人知道(不能预期);模型输出错了,能追溯到哪个权重的责任吗?不能(不能验证)。一万亿个参数里的任何一个,孤立地看都不表达任何东西——意义摊在所有参数的联合分布上。控制面在形式上还在,实质上蒸发了。
那大模型到底怎么被控制?旋钮迁移到了两个更上游的位置:
- 数据:你喂什么,它成为什么。预训练数据配比、SFT 的示范、RLHF 的偏好标注——你不再设定权重的值,你塑造让权重滚下去的地形,梯度下降替你选点。
- 目标函数:望远镜十二条里的第③条”目标函数即命运”说的就是它。你度量什么,就得到什么。DeepSeek-R1 是最干净的例证:没有人教推理,只是把奖励从”像人类的答案”换成”答对了”,推理行为自己长了出来——换一个目标函数,等于换了一个物种。
注意这次迁移的性质:控制从机械式变成了统计式。函数时代你设定行为,模型时代你只能推分布——把”想要的行为”的概率推高,把”不想要的”推低,没有任何一条行为是被保证的。这也解释了 reward hacking 为什么是这个时代的标志性故障:目标函数是你唯一能写下来的控制面,而模型优化的是你写下来的,不是你想要的——两者之间的每一条缝,都是控制面的泄漏点。
第二次迁移:训练结束后,只剩上下文这一个活旋钮
模型训完、权重冻结,上面那两个旋钮就锁死了。推理时你还能动什么?盘点一下会发现窘迫得惊人:
- 采样参数(temperature、top-p,之前拆过):货真价实的旋钮,三关全过——但带宽极低,只能调”多大胆”,调不了”会什么”。
- 上下文窗口:剩下的一切。System prompt、few-shot 示例、你贴进去的代码和文档——全部运行时控制,只此一处。
这就是”prompt engineering”四个字的第一性原理解释:不是人们突然爱上了写咒语,是权重冻结之后,上下文是唯一还活着的控制面,所有控制需求只能从这一个口进去。Karpathy 后来把这层叫 Software 3.0——“最热门的新编程语言是英语”。
这里值得深读一篇论文,因为它把”上下文是控制面”从比喻升级成了机制。von Oswald et al. (2023)《Transformers Learn In-Context by Gradient Descent》研究的问题是:为什么模型不更新任何权重,只靠看上下文里的几个例子(所谓 in-context learning,上下文内学习),就能”学会”一个新任务?他们的答案:在简化设定下(线性注意力、回归任务),Transformer 的前向传播在数学上等价于对上下文中的例子做了几步梯度下降——只不过这个”权重更新”发生在激活值里,网络算完就丢弃。换成人话:
你写进上下文的每个示例,都在临时地、一次性地”微调”这个模型——一份会话结束就蒸发的隐形权重更新。
诚实的打折:这个等价性是在玩具设定下证明的,真实大模型的 in-context learning 是否就是这个机制,学界仍有争议(后续有工作指出真实模型的行为和梯度下降对不上)。但即使只当作隐喻,它也校准了一个重要直觉:上下文和权重不是两种东西,是同一个控制面的两种时态——权重是固化的上下文(训练数据的沉淀),上下文是临时的权重(即用即弃的微调)。区别只在持久性和成本。
顺带一提,这两层之间其实还藏着第三个控制面,目前只存在于实验室里:直接拧激活值。2024 年 Anthropic 用可解释性技术在 Claude 里定位到”金门大桥”这个概念对应的内部特征,把它的强度人为调大,模型就变得三句话不离金门大桥(“Golden Gate Claude”)。这件事的深意不在好笑,在于它演示了一条野心勃勃的路线:给蒸发掉的权重控制面重新装上旋钮——能拧、能预期、能验证,一关一关往回补。可解释性研究的相当一部分,本质上就是这个控制面考古工程。
第三次迁移:Agent 把控制面搬回了模型外面
现在到 Claude Code 和 Codex。它们和裸模型的根本区别,Agent 工程七问里已经立过公理:模型是无状态的随机函数,真相要移到模型外面。顺着这条公理看控制面,你会发现一件精彩的事——控制面也跟着搬出来了,而且搬出来之后重新变成了文本和代码:能 git diff、能 code review、能回滚。绕了一大圈,我们又造出了一个”源代码式”的控制面——只是这次它包在一个不可控的核心外面。
盘点 Claude Code / Codex 的驾驶舱,旋钮不是一种,是三种性质完全不同的控制:
软控制(说明书):system prompt、CLAUDE.md / AGENTS.md、skills。这是写给模型”读”的——持久、可版本化,但执行是概率性的:模型大概率遵守,不保证遵守。它们的本质是把重要指令预置进那个唯一的运行时控制面(上下文)里,相当于每次开机自动注入的一段”临时权重”。
硬控制(笼子):权限系统、沙箱、hooks。这是整个驾驶舱里唯一确定性的部分——hooks 是挂在工具调用上的普通程序,permissions 是模型碰不到的判断逻辑,它们不”请求”模型配合,它们直接拦截。注意这个设计的深意:说明书管不住的事,不要加粗说明书,要换成笼子。“请不要动生产数据库”是软控制,撤掉生产库的写权限是硬控制——前者调分布,后者定边界。
生态控制(激励):测试、编译器、linter、CI。这是最容易被忽视、实际上最深的一层。Agent 在一个”行动→观察反馈→修正”的循环里跑,那么反馈信号的形状就决定了它收敛到哪里。给它一套严格的测试,它自己迭代到全绿;测试有漏洞,它就”收敛”到钻漏洞的解——这和 R1 训练里的 reward hacking 是同一件事在推理时的重演。所以这句话值得写下来:在 agent 时代,写测试就是写目标函数。你对 Claude Code 最有力的控制,往往不是 prompt 里多加一段话,而是让”什么算成功”在环境里变得可验证。
把三层放回”管理”这个词下面看,结构突然眼熟起来:说明书(入职手册)、培训教材(skills)、权限(门禁卡)、激励(KPI 与验收标准)、审查(code review)。函数是被编程的,模型是被训练的,agent 是被管理的。控制面的形态,暴露了我们和这个系统的真实关系已经变了。
五个控制面,一张对照表
| 控制面 | 能拧吗 | 带宽(能改多少行为) | 持久性 | 能验证吗 | 拧一次的成本 |
|---|---|---|---|---|---|
| 源代码(函数/程序) | 直接 | 完全 | 永久 | 逐行可查 | 极低 |
| 数据+目标函数(训练) | 间接(塑造地形) | 最大——决定模型是什么物种 | 固化进权重 | 几乎不可归因 | 天价 |
| 上下文(推理时) | 直接 | 中——只能唤起已有能力 | 会话级,即用即弃 | 可读但效果不保证 | 极低 |
| 激活值(steering) | 实验室阶段 | 未知 | 即时 | 正在补课 | 研究级 |
| Harness(说明/笼子/激励) | 直接 | 中高——组合出新行为 | 永久且可版本化 | git diff 可查 | 低 |
这张表本身就是个可复用的判断工具:下次你想”控制”AI 的某个行为时,先问一句——这个需求应该落在哪一层?要它换个说话风格,上下文层就够;要它绝对不碰某个目录,必须硬控制层;要它稳定产出能通过验收的代码,去生态层写测试;要它具备一种它根本没有的能力,抱歉,那是训练层的事,下游怎么拧都拧不出来。大量”prompt 写了没用”的抱怨,本质是把训练层的需求错投给了上下文层。
我的判断:迁移还没停
把三次迁移排成一行,方向就露出来了:
机制(改代码) → 统计(推分布) → 激励(造环境)
每往右一步,直接控制减少,能力上限提高,然后人类立刻在新的一层重建确定性——权重不可控,就发明 RLHF 把”人想要什么”写成目标;上下文易失,就发明 CLAUDE.md 把它固化;说明不可靠,就发明 hooks 和沙箱把关键路径改回确定性代码。我们从没接受过”不可控”,只是一次次换地方重建控制。
而这个迁移还没停。上一篇 Lilian Weng 深读讲的正是下一步:被优化的对象正沿着 prompt → 上下文 → workflow → harness 代码往上爬——今天这个刚被我们建好的、git 可查的控制面,自己正在变成被模型优化的对象。当 harness 也开始自我进化,人类手里还剩什么?Weng 那篇给过答案,放在控制面的语言里更清晰:剩下规约(specification)——把”你到底想要什么”说清楚的能力。评估器和权限必须留在被进化的循环之外,因为那是最后一层控制面;而”想要什么”没法外包,因为任何系统都无法替你定义你的意图。
所以这篇的结论可以压成一句话:控制面一路迁移,每一层的旋钮都终将交给机器去拧;唯一不迁移的,是决定”拧向哪里”的那个意图。你在 CLAUDE.md 里写下的每一行,本质上都是在练习这件最后的事。
行动
- 给自己的 Claude Code 配置做一次”三层审计”:打开你的 CLAUDE.md、settings 和 hooks,把每一条归类——软控制/硬控制/生态控制。找出那些”写在说明书里但屡次失效”的条目,问一句:它是不是本该是一个 hook(笼子),或者一条测试(激励)?
- 做一次控制面错位排查:回想最近一次”prompt 怎么改都没用”的经历,对着上面那张表定位——那个需求真正属于哪一层?如果答案是训练层,就停止在上下文层内卷。
- 深读一篇源头:von Oswald et al. (2023) 值得精读一次,它是”上下文=临时权重”这个心智模型的机制来源;读的时候带着那个诚实的打折——玩具设定的等价性,不等于真实模型的机制。