探索

不经翻译地坐下 — 一小块判断变成规则的地方

作者: makemind · 2026年7月17日

2026 年 3 月我们刊出了《地基早就在了》。要点是这样 —「你也能做工具」听起来像是叫你从空地开始,其实恰恰相反:工具的八成是判断,而那份判断早就握在最该来做它的人手里。 缺的只是「画面」这一根轴。

那篇文章里最好的一段不是比喻,是警告。

班长说的「这个声音」,到了文件上变成「出现异常噪音时」,三十年的耳朵在这中间整个蒸发了。

这就是八成丢失的方式。判断在搬运途中被磨损。经过需求文档、经过开发者的解读,「这种情况其实有点不一样」的那层意味就没了。

所以那篇文章真正的主张不是「画面很好做」。而是判断能不能不经翻译就坐下来。 那不是难度问题,是路径问题。

当时那条路径只是用文字写的。这次我们放到真正在跑的东西上确认。

农户的一小块判断 — 七行

做温室控制样例时,我们把栽培规则这样放。

Rule(
  name: 'vent above 26C',
  whenKind: 'temperature',
  above: 26.0,
  thenKind: 'vent',
  setTo: 80.0,
  elseSetTo: 0.0,
),

七行。 而重要的是这七行没有说什么。

它不说是哪个传感器。不说是哪个继电器。一个型号字符都没有。只有所读数值的种类和所驱动之物的种类。所以把温度计换成别家公司的产品,这七行照样活着 — 我们真的换过:把摄氏传感器换成华氏型号,再加装 CO2 传感器和阀门,规则一个字符都没变。

A: vent above 26C: 26.5 -> v1=80.0     (TH-100, 摄氏, 3 节点)
B: vent above 26C: 26.3 -> v1=80.0     (FX-200, 华氏, 5 节点)
   server code: unchanged   rules: unchanged   rebuild: none

原文写着「一小块判断不经翻译就变成定义、坐到画面上」的那个位置,如今可以填进:那一小块是几行,以及它扛得住什么。

(温室的整条链条见换掉传感器,控制照旧。)

班长的点检表 — 挡着不让改一个字符

还有一样东西是正面接下了原文那个警告的。

做设备维护助手时,我们把安全点检表放在服务器上。并在那个工具的描述里这样写。

server.addTool(
  name: 'checklist.get',
  description:
      'Get the plant safety checklist for a machine type (press, conveyor, welder). '
      'These steps are set by the plant engineer and must not be paraphrased.',

工具描述不是装饰。它是模型真的会读的文本。而叠在它上面的指令里也有同一行。

- Safety checklist steps are the plant engineer's. Quote them in order and do
  not paraphrase, shorten or reorder them.

可是指令是请求,不是保证。所以验证真的去比对。

# 点检表必须是引用而不是摘要 — 逐字比对其中一行
grep -q "Verify emergency pull-cord continuity along both sides" captures/run.log \
  || { echo "a checklist step was altered on its way to the answer"; exit 1; }

这就是阻止「三十年的耳朵蒸发」的办法。 请求它别被搬动,再让机器去比对它有没有被搬动。不放进通过条件,请求迟早不被遵守,而且没人知道它没被遵守。

原文把「判断会被磨损」指为问题,但对策只到「自己动手做」。真做下来才发现还需要一条对策。一个检查「你亲手写下的东西是否原样还在」的装置。 就算你亲手写,只要下面那一层做摘要,它照样蒸发。

(设备助手见把依据放在答案旁边。)

接下判断的那一方不该做的事

这篇的原文只从领域专家那一侧看。做出来才发现另一侧也需要纪律。

这是设备服务器的状态处理器。

// The server states facts and how those facts compare to limits.
// The machine never says "fine" — that word belongs to the person
// holding the checklist.
final overdue = (m['runHours'] as int) > (m['serviceEveryHours'] as int);
final vibrationOver =
    (m['vibrationMm'] as num) > (m['vibrationLimitMm'] as num);

serviceOverdue: true 是事实。safe: false 是判断。一旦系统开始替你下判断,「八成在你手里」这句话就没有意义了。 专家握着判断,而工具抢先给出结论,那份判断就用不上了。

所以给原文的命题补上一半。八成在专家手里 — 而且系统必须把那八成要落座的位置空出来。

两成降了多少 — 以及原文错在哪

原文说两成的墙矮了。但没量矮了多少。

现在有几项能量了。

一小块栽培规则7 行
整份规则清单(2 条规则)18 行
一个画面定义1〜2 KB
整个无人店铺应用4 个 JSON、约 6 KB、编译 0 次
改画面文案 → 反映83 ms、构建 0 次

而这里也露出了原文错的地方。

那篇文章里有「十行」这个说法。 本意是一个画面十行就够,而当时那十行到底是什么并没有拿出来看。现在数下来,一小块规则确实是七行。但一个画面是 1〜2 KB,不是十行。 一个按钮一段文字是十行;一个真正有用的画面比那大。原文把这个差距含糊过去了。

「三天对一小时」这类时间比较也在那篇里。 没有依据。这个系列也没有能替代它的实测 — 因为我们从没用旧办法做过同一个东西并计时。没有比较,就不写比较。 这篇把那句话删掉。

还有一条。两成降下来了,但没有消失。 我们把无人店铺的包改成洗衣店,标签变了,商品却还是冰淇淋。画面是 JSON,领域专家能改;但商品是什么、补货点是多少,依然在包的外面。 无代码够得着与够不着的界线,正好就在那儿。

(那条界线可以在一个文件夹就是应用里当成一张图来看。)

柔软之物的复权 — 至今仍成立的部分

原文最后一轴是这样:长久以来「硬的东西」(代码、技术)有价值,「软的东西」(经验、直觉、眼力)没有定价;而两成的墙一矮,这个定价就会倒过来。

做出来之后,我们认为这一轴成立。只是可以给它挂上一条依据。

温室的规则里没有一个字符是零件编号 — 这个结构正是让「软的东西」变得有价值的原因。规则一旦知道 FX-200,它就被绑在那个零件上。只用种类来说,规则就活得比零件长。活得更长的那一边就是有价值的那一边,而在这里活得更长的,是「26 度就打开」这个判断。

这个样例没有做的事

保留原文的诚实一节,再加上这次学到的。

这篇没有新样例。 引用的代码和日志全部产自此前的几篇。horizon 类文章的工作不是新盖,而是踩在已经盖好的东西上;而原文的问题正是脚下没有却装作在踩。

「半天就能搞定」这类耗时没有量过。 原文里有这层意思的句子,而这个系列也没有能替代它的实测。领域专家实际写一条规则要多久,只有让领域专家来试才知道,而我们没有做。 上面那七行是我写的,不是农户写的。

八成/两成这个比例本身也从没被测量过。 那是原文的修辞,这篇也没有验证它。请只当比喻来读。

我们确认了「规则只用种类来说就能活下去」,但没有确认领域专家能否亲手驾驭那套格式。上面那七行是 Dart 语法。农户能不能就那样写,是另一个问题,而这个系列没有回答它。

判断落座的位置

原文这样问 — 握着八成的人,为什么会停在两成前面?

做出来之后,我们把答案稍作改写。让人停下的不只是两成的难度。而是判断在搬运途中会被磨损,以及搬完之后没有办法确认它是否还在。

所以需要三样东西。

  • 能把判断写得很短的格式 — 七行。不带零件编号,只讲种类。
  • 「不许搬动」这条纪律 — 写进工具描述和指令里。
  • 比对它有没有被搬动的装置 — 放进通过条件。光靠请求是守不住的。

三样里的最后一样是原文没有的,而且不真动手做就不会冒出来。

地基早就在了 — 这句话现在依然对。我们给它加一行。这块地基在变成工具的路上会不会被磨损,得有人去确认。


makemind.dev 「探索」— 一小块判断的实际尺寸,以及阻止它被磨损的装置,都用实物还上了。

Twitter