LLM 提议,规则裁决:让 AI 主动出手,又不让它决定该不该出手

一个会主动开口的 AI 导师,最危险的不是说错话,是在不该说话的时候说话。我们把「说什么」交给模型,把「要不要说」留给一套零 AI 参与的确定性仲裁。

做一个会主动开口的 AI,最先想到的风险是它说错话。真跑起来会发现,更麻烦的是另一件事:它在不该说话的时候说话。

学生正在盯着一道题预测答案,AI 弹出来提醒他「要不要看看这个知识点」——这句话本身完全正确,出现的时机毁掉了这道题。他本来要自己想出来的那一下,没了。

所以我们把这件事拆成两半,用两种完全不同的东西来做:

  • 说什么 —— 交给模型。它擅长把一句话说得像人、说得贴着这个学生。
  • 要不要说、什么时候说、这次轮到谁说 —— 交给一套确定性的规则。零 AI 参与。

这篇讲第二半怎么搭。

为什么「要不要出手」不能交给模型

一个直觉的做法是:把学生当前的全部状态塞进上下文,让模型自己判断该不该开口。

这个做法的问题不是准确率,是不可预测。同样的场景,这次它开口了,下次它沉默;你没法向任何人解释它为什么这么做,也没法在它做错之后修。更要命的是,你没有办法给它加一条硬约束——提示词里写的「学生在答题时不要打断」是建议,不是保证。

我们要的是相反的性质:同样的状态,永远同样的决定;每一次决定都说得出理由;要加一条铁律,改一行代码就能加上。

这三条一旦要求下来,答案就只有一个:决定权归确定性的代码,模型只负责措辞。

三样东西:注册表、黑板、仲裁

注册表:一个行为想出手,先说清它冲着什么去

每一种主动行为都登记在一处。登记的时候必须填两件事:

  • 它冲着哪一个「学不会」的根因去 —— 前置断层、认知负荷、迷思概念、会背不会用、理解错觉、遗忘、动机情绪、节奏错配,八选一。
  • 它要学生做哪一个动作 —— 不是「提醒他注意」,是他看完之后手上要做什么。

这两项填不出来的行为,注册不进去,服务起不来。这条约束是故意设得这么硬的:说不清教学价值的主动行为,本质上就是播报。「你已经三天没做题了」这种话,对学生没有任何帮助,只是让产品显得很关心他。

黑板:所有行为读同一份事实

一次决策开始时,建一块黑板,把这次事件、当前界面状态、学生画像挂上去。所有候选行为只准从黑板上读,不许自己另开查询。

这条约束的用处在于一致性:如果每个行为各查各的,同一次决策里的两个行为可能看到不同版本的学生状态,然后给出互相矛盾的判断——而这种 bug 极难复现。学生的全景快照是惰性加载的,一次决策内只装配一次,重的查询不会因为多几个候选行为就多跑几遍。

仲裁:逐个评估,选一个或者选择沉默

事件进来之后:

  1. 按事件类型取出候选行为;
  2. 按优先级从高到低逐个评估,每个行为要么返回「我适用,依据是这些」,要么返回「不适用」;
  3. 选中第一个适用的,或者全都不适用——沉默也是一种决策
  4. 无论出手还是沉默,落一条决策记录。

其中最有价值的一条规则是占用抑制:几个界面状态为真的时候,学生正被别的教学流占着,所有主动行为一律让路。学生正在想探针的答案、正在上一堂从零讲起的课、正在考试模式里、正在新手引导的聚光灯下——这些时刻不许插话。

这条规则有一个反直觉的推论:高优先级的行为让路。误区反应是我们最想当场打断的那一类,但学生在预测窗口里的时候,它照样静默。这是有意的设计,不是漏洞——他正在想的,可能正是那个误区,让他自己撞上去比我们提前告诉他有价值。

我们踩过一次相关的坑:新手引导的聚光灯状态一直只在前端拦着,中枢不知道引导正在进行。于是绕过前端那道闸的调用方(实测有三处)能在聚光灯上插话。修法不是再去补前端,是把这个状态加进送给中枢的事件信封里——判断的依据必须到达做判断的那一层,否则前端每加一个入口就漏一次。

模型在哪一层进来:提议,然后被校验

规划下一步做什么,原本是一棵手写的决策树。它安全,但浅——只会按固定分支给建议。

我们让强模型来提议:把学生的完整处境和诊断出的误区交给它,让它提出接下来几步的计划。然后由一个纯确定性的校验器去判这份提议能不能用:

  • 学生状态弱或者卡住时,不许安排测试;
  • 只允许出现合法的动作类型;
  • 第一步必须是一个真动作,不能是「继续保持」这种废话;
  • 步数有上限。

校验不过、置信度不够、或者任何一处报错,一律退回规则版本。

这个结构有一个很好的性质:接上模型之后,系统不可能比原来的规则更不安全。最坏情况就是回到原来那棵决策树。校验器本身是纯函数,不碰数据库、不调模型,可以脱离一切外部依赖测试——它是整套东西的承重墙,所以它必须是最容易验证的那一块。

诊断误区那一层也是同样的结构:模型给出结构化的假设,但置信度不够的猜测不许写进学生模型。宁可不判,也不能让一个瞎猜污染后面所有的教学决策。

留痕:包括它为什么没说话

每一次决策都记一条,沉默也记。记的内容是:这次为什么做这个决定、当时看到了什么、其他候选为什么被跳过。

只记「出手了」的系统,出问题时你查不出任何东西——学生说「它从来不帮我」,你打开日志,一片空白,因为沉默不产生记录。而沉默恰恰是最需要解释的那种行为。

留痕还有一个用处,是让「这个行为对这个学生管不管用」变成可以回答的问题。某个行为在某个学生身上反复不奏效,就跳过它,让下一个候选出手。依据是这些行为真实的结果记录,不是给行为打的分。

一个实现细节值得一提:决策记录写在一个独立的追加型库里,不碰主库。写失败静默吞掉,绝不影响决策返回。观测不能成为故障源 —— 记录写不下去,最多是丢一条日志,不能让学生那边的导师卡住。

这套结构能搬到哪儿

它跟学习这件事没有必然关系。任何一个「AI 要主动介入人的工作流」的场景,都会遇到同样的三个问题:

  • 该不该在此刻介入?——需要确定性的仲裁和让路规则;
  • 介入的依据是什么?——需要一块所有判断共享的事实;
  • 事后能不能查?——需要包含「没介入」在内的决策记录。

模型能力再强,这三个问题也不会自己消失。它们是流程问题,不是模型问题。

我们的做法可以概括成一句:让 AI 提议,让规则裁决。 提议错了,代价是退回一个稳妥的默认值;裁决错了,代价是整个系统不可预测。所以这两件事必须由不同性质的东西来做。