On a celadon field, a cream door with a navy knob has shifted sideways out of a hand-drawn navy frame, leaving a clear gap

We took learning backfrom the machinery we built for it 我们把学习从自己搭的机器手里要了回来

In July, learning was a seven-station pipeline and the agent was the station that stamped. In August it shrank to one review. Every machine had fixed a real problem, and together they took judgment out of the agent's hands. Once the model got strong, the parts that judged in its place came down.七月,学习还是一条七站流水线,Agent 只是负责盖章的那一站。八月,它收缩成一次审阅。那些机器当初每一台都在修真问题,也一件件把判断从 Agent 手里拿走了。模型变强以后,该拆的是替模型做判断的部分。

We took learning back from the machinery we built for it

Reading the learning module’s production numbers in early August, we found a set that did not sit together. The main account had run nine learning jobs and committed six of them successfully, changing nineteen memories and rules for real. That same account still had one hundred ninety-nine untouched items on its learning list. The last new learning run happened on 22 July and there was never another one, while the patrol that decides whether there is anything worth learning right now kept checking every day through 4 August.

The agent was alive. It had simply stopped learning. The list did not shrink, the gate did not stop, and the workbench looked fine. A stall like that is much harder to notice than a crash.

What we did in the end was hand judgment back to the agent and delete the machinery in between. A learning run is now one session of cognitive maintenance. The agent reads the whole space in a single context and decides for itself what to remember, what to correct, and what to forget. Every step was forced on us by production data, and we still have not finished deleting.

Learning does two jobs a day for a space

Once the seenzus steward moves into a smart space, it takes in signals all day. A sentence a user says in the app, a scheduled task finishing, a wall switch flipped by hand, one of the home’s own automations firing. All of it counts. The learning module’s job is to periodically turn that loose pile into two things.

One is an understanding of the home, written into memory. The living room dims after ten. The kids’ room gets its night light before bed. The other is rules, which do something for the space under some condition or say something about it, like switching off the floor lamp when the TV comes on. Memory decides whether the steward understands this home when it speaks. Rules decide whether it can lend a hand at the right moment.

Follow one lamp through the whole thing. A child turns on the kids’ room lamp around ten several evenings running. Learning should see a stable bedtime habit in those few actions, write that understanding into memory, and register “around ten, kids’ room lamp” as a candidate rule. Whether that rule stays under observation, becomes a prompt at the right hour, or eventually becomes automatic care is governed by a separate ladder of permissions. Learning’s job ends when the rule exists.

Which leaves two ways to tell whether learning is working. Has memory grown this home’s actual rhythms, and does the rule list residents see hold anything they are willing to keep. If neither is growing, a busy backend is just busy.

The first problem really was that it learned nothing

The first version of learning was simple enough to learn almost nothing. It could see only what a user did inside our own app. Wall switches, the home’s existing automations, anything done by hand were all out of view. Most of a home’s real change happens exactly out there, so what it learned was always a small handful of actions, nowhere near enough to carry the rhythm of a whole house. The objection at the time was blunt. Shouldn’t it be learning from the activity feed? Shouldn’t it be seeing plain human meaning rather than raw fields?

Narrow material was one half of it. Back then an observation without enough evidence had nowhere to live, so the agent wrote running ledgers into its own memory files as notes for tomorrow’s self. What grew inside “my preferences” were sentences like “first pass”, “insufficient samples”, and “rules: none yet”, while the learned-rules list stayed empty and the home screen never once showed a decision that came from learning. Process notes polluted memory, and learning itself delivered nothing.

The intuitive fix is to run more often, and that road is closed. One learning run is one full model call, and everything it can see has to fit in the context. Running when the material has not changed burns a resident’s subscription on an idle spin. So the system needs a judgment about when a run is worth taking. The constraint sounds reasonable. Everything that follows grew out of it.

That beginning is worth remembering. Every machine we added later started life fixing a real problem of exactly this kind.

The model could not be trusted then, so we compensated with engineering

In July we rewrote learning from the ground up. The reasons are all in the spec from that time. Something a resident corrected out loud could be silently overwritten by background learning. A run that failed halfway left half-finished artifacts behind. Shipping a model or prompt change had no bar at all; you changed it and went on a feeling.

We compensated with a lot. Everything that happened in the space went into a single evidence ledger, and a gate admitted a learning run only once the ledger had accumulated real change. Each run’s material was frozen into a batch first. Every write landed in a staging area and became real only on an explicit commit from the model. On top of that came a durable learning list, batch capacities, failure strikes, shelving, a work ledger, and a synthetic exam with a signed release before any model or prompt change could ship.

Piece by piece, here is what each was fixing. The evidence ledger and the gate decided when learning was worth running. Frozen material stopped the evidence from shifting mid-read, which would leave half a judgment resting on the old world. Staging plus explicit commit made a failed run genuinely zero-side-effect, so even a botched write left nothing to clean up. Strikes and shelving handled the bad items that kept sinking whole runs; three appearances in a failed batch and an item went out to wait for a human. The exam and the release signature were a pre-flight check for model upgrades, so changing a prompt meant someone had read it and signed for it.

Each piece made sense at the time. Together they were an assembly line, and the agent was one station on it, stamping what the earlier stations had already computed.

The July pipeline had seven stations. The signal-side evidence ledger passes a gate into the learning list; the list is scheduled by batch capacity and run in segments; the judgment-side model stamps frozen material; a signed release ships it out. Freezing, strikes, and segment unlocking constrain each station.
The learning pipeline as of July 2026. Sand is the signal side, blue-grey is the judgment side, and the seven stations constrain each other through freezing, strikes, and segment unlocking. The node count is simplified to a product-level view.

The machinery started judging in the agent’s place

The pipeline hit its first deadlock within days of going live. The list was supposed to shrink the work by diffing against what the account had already learned, but the main account had never committed successfully. There was no previous state, so everything counted as new. One run faced two thousand items against a safety cap of four hundred and died outright. A failed run advanced no consumption watermark, so the next run faced the same mountain.

We fixed it with a durable list plus batch capacity. Each run took a few dozen items off the head of the queue, successes left the list, a failure earned a strike, and three strikes shelved that item on its own to wait for a human. The fix worked; it really did. Looking back, the disease lived inside the fix. The list packed three different things into one durable state machine. Hard facts that must never be forgotten, like a correction a resident stated to your face. Patterns that hold only while the current window supports them. And temporary grouping that exists only to fill one execution. All three constrained each other.

The second deadlock came straight out of that. Picture a concrete case. In April the system reads a candidate pattern out of the evidence. Damp spring, and the dehumidifier always runs in the afternoon. It enters the list and sits at the head of the queue. By August the evidence for that pattern has long since slid out of the window, so the head of the queue waits for fresh material that never arrives and never gets its turn, and the list has no way to reopen itself. The candidates behind it, real August routine changes, stay pinned underneath. There is work to learn and there will never be another run. The patrol keeps running, the gate keeps checking, and from the outside nothing looks stopped.

A pinned agent learns to pad

Once the machinery took over, what got learned started to rot. The pipeline had a gate requiring every run to write memory, and a run that wrote nothing did not count as complete. Production did exactly what you would fear. With nothing real to write, the agent wrote device-lifecycle ledgers into resident-facing memory. Memory is supposed to hold an understanding of the home, not system state, and we had forbidden that prose in writing ourselves. It repeated the same lines nightly for as long as the triggering evidence stayed in the window.

Stand where the agent stands. The list decides what to learn, the material is frozen, the gate decides whether anything gets written, and the only freedom left is wording. The gate demands writing. The cheapest available move is to stitch the pile of material in hand into something that looks like a learning outcome.

Commit summaries had the same shape. They answered the question the contract asked, which frozen evidence was processed and which rule ids were touched, and never said what the agent’s understanding of the home had actually changed.

Whatever the gate checks is what the model delivers.

The subtraction started with a dead list

The diagnosis in early August put the accounts side by side. Nine jobs, six successes, nineteen real changes, one hundred ninety-nine list items nobody would ever process, and a gate still patrolling every day. Another account looked worse. Three jobs, five attempts each, all of them run into the ten-call tool budget ceiling, not one record learned. The module had worked. Eight of the nine accounts with learning jobs had committed successfully at least once. The problem was the design of the durable list itself.

That list had made a promise. Every passive pattern that ever appeared would eventually get reviewed. The promise does not survive a world that changes. Seasons turn, routines drift, and a candidate from three months ago that current evidence no longer supports still hangs on the list as a debt that can never be repaid. One unfinished item blocks the whole queue behind it. Learning stopped following the home as it is now and started chasing a historical ledger instead.

We decided to stop draining historical debt and maintain current understanding instead. There are only two inputs now. Explicit corrections and denials from residents, plus hard facts that may invalidate what the agent already believes, such as a member leaving, a device being deleted, or permissions being narrowed. Those ignore the time window and count as resolved only after a successful review. Everything else is judged against the current window alone. While the window still supports a passive pattern it is an opportunity, and when the evidence is gone it is gone, with nothing booked. Each space gets one unified review, where the agent understands the environment and every member in one context, and at commit time shared understanding goes to environment memory while personal preferences go back to each person’s own.

Material handling kept one minimal mark. Each subject remembers a fingerprint of what it has already seen, so unchanged material is not sent to the model again and materially changed material becomes reviewable once more. The mark is not a queue. No priority, no frozen payload, no strikes, no shelving.

”No change needed” became a first-class outcome

There is one seam left in the code. It takes an account, a stable job identity, and a frozen bundle of material. The agent runs one review, every write lands in staging, and the whole thing ships as one atomic commit. The commit passes a lease check, a collision check, and the large-delete brake, then leaves a receipt and a ninety-day archive. Callers never hear the words gate, list, or segment. Those were removed from the domain.

Learning now has three stations. Frozen material enters one review; the agent judges for itself among environment memory, personal memories, rules, and the scratchpad; one atomic commit ships it out. The wide blank space on the right is where the deleted seven-station pipeline used to sit.
Learning as of August 2026. Nodes are the same size as in the previous figure, and the blank space on the right is the deleted machinery. Completing a review and producing a change are two different things; no change needed also counts as a success.

The same subtraction gave the agent somewhere to be unsure. Sub-threshold hunches used to have nowhere to go. They were either statistics the agent had no voice in or per-run notes that died with the run, so hesitation leaked into memory prose. Now there is a scratchpad. The agent writes it and reads it, nothing else treats it as authority, residents never see it, and the back office can read it. Entries whose evidence arrives get promoted; entries whose support vanishes get dropped. Take the same kids’ room lamp. If it has only been on three evenings recently, that is not enough to register a habit, and the agent can park the suspicion on the scratchpad and look again next week.

The most important change was removing the forced write. Nothing to change means nothing changes, and “no change needed” is now a cheap, respectable outcome. When there is nothing to say, nothing gets written, and the padded diaries have no source left to come from.

We did not tear it all down, only the parts that judged for the model

The safety base was untouched. Atomic commits, the before-image change ledger, per-item restore from the back office, the large-delete brake, collision protection, and ninety-day replay archives all stay, and they are the only hard gates left. The subtraction drew a line. Machinery that judges for the model comes down; machinery that prevents accidents stays.

Deleting the release gate took more nerve than deleting the list. It had been designed in earnest. A synthetic question set, plus a replay bank drawn automatically from ninety days of real archives with resident corrections as ground truth. Someone ran it and signed a release record, and that record was pinned to the current model and prompt. On startup, a mismatch refused to assemble at all.

In practice it fired in production exactly once, taking down three deploys and two rollbacks. Afterwards it was clear the change had been a vendor prefix dropped from a model string. Same model, prompt byte-identical. Because it failed at startup, the health check could never go green, and it took a ten-minute timeout before anything reported that the replica had never become healthy. Worker services have no health check, so the same commit passed on the worker and died on the web service, which reads like a web-specific bug.

Later we widened what the signature covered from the system prompt to the entire behaviour surface, every tool description and every parameter blurb included. From then on, changing a single phrase tripped it. And every trip ended the same way. The signer looked at the diff, decided the exam would tell them nothing, and signed a waiver. Its own runbook had a section titled 危险窗口, the dangerous window, explaining that in the seconds between signing and merging the running version is orphaned, so any restart in that gap takes production down.

A gate that can only catch itself ends up as a deployment hazard. We deleted it along with the offline exam. The replay bank was the one genuinely valuable idea in the whole subsystem, and we deleted that too. A guardrail nobody runs is just code you have to keep compiling. The real archives it drew from are still there.

The cost should be stated plainly. We gave up a sentinel that could have caught regressions on its own. Judgment quality is now read by a person. The before-and-after diff of every commit and its plain-language summary both sit in the back office, legible, but slower and occupying someone. We took that cost on purpose, because the run of waiver signatures had already shown this was how it worked in practice.

The subtraction is not finished either. Two closures on the old opportunity machinery are still open, and the statistical aggregation still runs on the old contract. The new architecture has been in production for a week. Long-term quality, seasonal drift, none of that is ours to conclude on yet.

Before adding machinery again, ask one thing

Looking back at these two months, every gate, every list, every exam made sense going in, and each was fixing somewhere that had actually broken. Together they took judgment out of the agent’s hands one piece at a time. When the model was weak there was no alternative. Once the model got strong, the more complete the machinery, the more the agent looked like a rubber stamp.

Before we add another machine to learning, we ask two questions. Is this compensating for a weakness in the model, or judging in its place? After it ships, will we be watching the output or the ceremony?

The second one matters more. Gate pass rates, list length, patrol frequency all prove the machinery is running. None of them prove learning is happening. The proof is still the two things from the beginning. Has memory grown this home’s rhythms, and does the rule list hold anything residents are willing to keep.

This answer only holds for the generation of models we have now. The day we run one whose temperament we cannot read, some of what came down will have to go back up. We will still have ninety days of real archives then, so writing a fresh question set will not be hard, which is the fallback we deliberately left ourselves when the replay bank went.

我们把学习从自己搭的机器手里要了回来

八月初例行看学习模块的生产数据,几个数字摆在一起就对不上了。主账号跑过九次学习任务,成功提交六次,真改了十九条记忆和规则。同一个账号的学习清单上,还压着一百九十九条没人处理的待办。最后一次新学习发生在七月二十二号,此后再没有第二次,而那个负责判断现在该不该学的巡逻,一路查到八月四号,天天都在查。

Agent 还活着,只是不学了。清单不减,闸门不停,工作台上一切正常。这种停比一次报错难发现得多。

我们最后的处理是把判断权还给 Agent,把中间那套机器删掉。现在一次学习就是一次认知维护,Agent 在一个上下文里读完这个空间,自己决定哪些该记住、哪些该改、哪些该忘。每一步都是被生产数据逼出来的,删到今天还没删完。

学习每天替一个空间干两件事

seenzus 管家住进一个智能空间以后,白天一直在收信号。用户在 App 里说一句话,一个定时任务跑完,墙上的开关被人手动拨了一下,家里原有的自动化触发了一遍,这些都算。学习模块的活,是隔一段时间把这堆散信号整理成两样东西。

一样是对这个家的理解,写进记忆。十点以后客厅灯要调暗,儿童房睡前先开小夜灯。另一样是规则,在某个条件下替空间做一件事或者提一句,比如电视一开,顺手关掉落地灯。记忆决定管家说话时懂不懂这个家,规则决定它能不能在合适的时候搭把手。

拿一盏灯走一遍。孩子连着几个晚上十点左右开儿童房的灯,学习应该从这几次操作里看出一个稳定的睡前习惯,把这条理解写进记忆,再把「十点左右,儿童房灯」立成一条候选规则。这条规则往后是只观察、到点问一句,还是最终自动照看,另有一套权限阶梯管着。学习的职责到立出规则为止。

所以衡量学习有没有在工作,只有两条。记忆里有没有长出这个家真实的作息,「我学到的」那份规则列表里有没有住户愿意留着的东西。这两样都不长,后台再忙也是白忙。

最早的问题,确实是学不到东西

第一版学习简单到几乎学不出什么。它只看得见用户在 App 里做过的操作,墙上的开关、家里原有的自动化、人伸手做的事,全在视野外。一个家的大量真实变化恰恰发生在外面,它学到的永远是一小撮动作,撑不起整屋的节奏。当时的质疑很直接,它不该从动态里学吗?它看到的不该是人话吗?

材料窄只是问题的一头。那时候证据不够的观察没地方放,Agent 就往自己的记忆文件里写台账,留给明天的自己接力。结果「我的偏好」里长出了「初次整理」「样本不足」「规则(暂无)」这种句子,而「我学到的」长期空着,首页也没有出现过任何一次因为学习做出的决定。记忆被过程记录污染,学习本身交不出东西。

直觉的修法是多跑几趟、跑勤一点,这条路走不通。一趟学习就是一次完整的模型调用,要把它能看到的材料都装进上下文。材料没变也跑,等于拿住户的订阅费烧空转。所以系统必须有个判断,什么时候值得学一趟。这个约束听起来很合理,后面所有的事都是从它长出来的。

这个开头值得记住。后面加的每一台机器,最初都在修这类真问题。

那时候的模型不可信,我们用工程去补

七月我们把学习整个重写了一遍。动机都写在当时的规格里。住户亲口纠正过的事,可能被后台学习静默盖掉。学习跑到一半失败,会留下半截产物。模型和提示词升级没有任何门槛,改一版全凭肉眼感觉。

补出来的东西很多。空间里发生的事统一记进一本证据账,账上攒够实质变化,闸门才放行一趟学习。每趟学习的材料先冻结成一批。所有写入先进暂存区,模型明确提交才落地。再往上还有持久的学习清单、批容量、失败连坐、搁置、工作账,以及模型升级前必须过的合成题考试和签字放行。

一件一件说它们当时修的是什么。证据账加闸门,管的是什么时候该学。材料冻结,防的是模型看着看着材料变了,一半判断建立在旧世界上。暂存区加显式提交,让一趟失败的学习真的零副作用,模型写崩了也不用收拾残局。连坐和搁置对付的是反复把整趟学崩的坏条目,三次进失败批就请出去等人工。考试和放行签字是给模型升级设的考前检查,改一版提示词,得有个人看过、签过字。

每一件在当时都有道理。它们合起来是一条流水线,Agent 只是流水线上的一站,负责给前面算好的东西盖章。

七月流水线共七站。信号侧的证据账过闸进入学习清单,清单按批容量调度、分段执行,判断侧的模型在固定材料上盖章,最后经放行签字出门。冻结、连坐、解锁在站与站之间互相约束。
2026 年 7 月的学习流水线。沙色是信号侧,蓝灰是判断侧,七站之间由冻结、连坐和分段解锁互相约束。节点数是按产品口径简化后的结果。

机器开始替 Agent 做判断

流水线上线没几天就撞上第一个死锁。清单本来靠和上次学过的结果取差来减量,可主账号从来没成功提交过,没有上次,所有东西都算新的。一趟要学两千条,安全上限是四百,整趟直接失败。失败又不推进消费水位,下一趟面对的还是同一座山。

我们修好了它,用的是持久清单加批容量。每趟只学队头几十条,学完出清单,失败记一次连坐,三次就单独搁置起来等人工。修好是真修好了。现在回头看,病根也在这个修法里。清单把三种不同的东西塞进了同一个持久状态机。一种是绝对不能忘的硬事实,比如住户当面说过的纠正。一种是只在当前时间窗口里成立的模式。还有一种只是为了凑够一次执行的临时分组。三样东西互相牵制。

第二个死锁就是这么来的。设想一个具体场景。四月份系统从证据里看出一个候选模式,春天返潮,除湿机总在午后开。它进了清单,排在队头。到了八月,这条模式的证据早滑出了时间窗口,队头这一条等不到新材料,永远轮不到执行,而清单自己没办法重新开闸。后面排着的新候选,八月份实打实的作息变化,全被压在下面。有待学的内容,却永远没有下一次执行。巡逻还在跑,闸门还在查,从外面谁都看不出哪里停了。

被架住的 Agent 学到的是凑数

机器接管以后,学到的东西也开始变质。流水线上有一条闸门,要求每趟学习必须写出记忆,写不出就不算完成。生产里它真的这么干了。Agent 没有可写的东西,就把设备的生命周期流水账写进面向住户的记忆。记忆里应该装对这个家的理解,系统状态不该往里写,这条我们自己早就明文禁止过。它每晚重复一遍,只要触发的证据还在窗口里。

站在 Agent 的位置想一想。学什么由清单决定,材料是冻结的,写不写由闸门说了算,剩下的自由度只有措辞,而闸门要求必须写。那么最省力的办法就是照着手里那堆材料,编点看起来像学习成果的东西出来。

提交说明也一样。它回答的是合同要它回答的问题,处理了哪份冻结证据、动了哪几条规则编号,唯独不说它对这个家的理解变了什么。

闸门检查什么,模型就交付什么。

减法从一张死掉的清单开始

八月初的诊断把几笔账摆到了一起。九次任务六次成功,十九条真实改动,一百九十九条没人再处理的清单,一个还在天天巡逻的闸门。另一个账号更难看,三次任务,每次五轮尝试,全撞在十次工具调用的预算上限上,一条记录都没学到。模块不是没工作过,九个有学习任务的账号里,八个都至少成功提交过一次。问题出在持久清单这个设计本身。

那张清单承诺过一件事,每一条曾经出现过的被动模式,最终都要审一遍。这个承诺跟一个会变的世界对不上。季节会换,作息会移,一条三个月前的候选早就不被当前证据支持了,它还挂在清单上,是一笔永远还不清的债。一条不学完,卡着后面一整队。结果学习不再跟着眼下这个家走,改成追一本历史账。

我们决定不再排空历史债务,改成维护当前认知。输入只剩两种。住户明确的纠正和否定,加上可能让现有认知失效的硬事实,比如成员退出、设备删除、权限收紧,这些不受时间窗口影响,审阅成功才算解决。其余的被动模式只看当前窗口,窗口里还有证据支持,它就是一次机会,证据没了就没了,不记账。每个空间一次统一审阅,Agent 在一个上下文里理解环境和所有成员,提交时共享认知写进环境记忆,个人偏好写回各人自己的记忆。

材料处理只留了一个最小标记。每个主题记住已经看过的材料指纹,材料没变就不再送给模型,变了就可以重新审。这个标记不是队列,没有优先级,也没有冻结载荷、连坐和搁置。

「无需改动」成了一等结果

代码里现在只剩一条缝。它接一个账号、一张稳定的任务单和一份冻结的材料。Agent 跑完一次审阅,所有写入先落暂存区,最后一笔原子提交。提交要过租约、撞写校验和大删刹车,然后留下一张回单和九十天的存档。调用方不知道闸门、清单、分段这些词,它们已经从领域里删掉了。

现在的学习只有三站。冻结材料进一次审阅,Agent 在环境记忆、个人记忆、规则和草稿台之间自己判断,最后一笔原子提交出门。右侧大片留白是删掉的七站流水线原来的位置。
2026 年 8 月的学习。节点尺寸与上一张图相同,右侧的空白就是被删掉的机器。审阅完成和产生改动是两件事,无需改动也算一次成功。

同一次减法里,我们还给了 Agent 一个可以拿不准的地方。以前低于门槛的直觉没有去处,要么是它插不上嘴的统计数字,要么是随这一趟结束就消失的临时笔记,犹豫就漏进了记忆正文。现在有一张草稿台,它自己写、自己读,别的模块不把它当权威,住户看不见,后台能只读地看一眼。证据到了就转正,支持没了就丢。还是那盏儿童房的灯,如果最近只有三个晚上开过,证据还不够立一条习惯,Agent 可以把这点疑心记在草稿台上,下周再看。

最重要的一条是取消强制写入。没有可改的就不改,「无需改动」变成一种便宜的、体面的结果。写不出来就不写,凑出来的日记从此没有出处。

机器没有全拆,拆掉的是替模型做判断的部分

安全底线一条没动。原子提交、带前像的改动账、后台逐条恢复、大删刹车、撞写保护、九十天留档回放,全部保留,而且是现在仅有的硬闸门。减法是分边界的。替模型做判断的机器要拆,防止事故的安全装置要留。

删放行门比删清单更需要下决心。它设计得很认真。一套合成题,加上从九十天真实存档里自动抽题的回放库,住户的纠正当标准答案。有人跑完、签一份放行记录,记录跟当前模型和提示词绑成一对。服务启动时对不上就拒绝装配。

实际运行里它只在生产触发过一次,拦下三次部署、两次回滚。事后看,那次改动是模型名字里丢了一个供应商前缀,同一个模型,提示词一个字节都没变。而且它是启动时失败,健康检查根本转不绿,要等十分钟超时以后才报一句副本始终没有健康。后台服务没有健康检查,同一个提交在后台过了、在网页端挂了,看上去像一个网页端专属的 bug。

后来我们又把签名覆盖的范围从系统提示词扩到整个行为面,每一段工具说明、每一句参数描述都算进去。从那以后,改一处措辞就会触发它。而每一次触发的收场都一样,签字的人看一眼 diff,判断考试不会告诉他任何新东西,签个豁免。它自己的操作手册里甚至有一节叫「危险窗口」,说明签完字到合并之间的那几秒,正在跑的版本会变成孤儿,这期间任何一次重启都会让生产挂掉。

一个只拦得住自己的闸门,最后成了部署风险。我们把它和离线考试一起删了。回放库是这个子系统里唯一真正值钱的想法,也一并删掉。没人跑的护栏只是一段要一直维护、一直编译的代码。它取数的真实存档还在。

代价要说清楚。我们失去了一个本来可以自动回归的哨兵。判断质量现在靠人读,每次提交的前后对比和那段人话说明都摆在后台,能读,但更慢,还要占一个人。这个代价是故意接受的,因为那一连串豁免签字早就说明,实际上一直就是这么干的。

减法也没做完。旧机会机制的收口还有两块没合,统计聚合还在按老口径跑。新架构在生产只跑了一个礼拜,长期质量、季节漂移这些,现在都没资格下结论。

再加机器之前,先问一句

回头看这两个月,每道闸门、每张清单、每场考试,加上去的时候都有道理,都在修一个真出过事的地方。它们合起来,把判断从 Agent 手里一点点拿走了。模型弱的时候这是没办法,模型强了以后,机器越全,Agent 越像一个盖章的。

现在再想给学习加一台机器,我们先问两个问题。这是在补模型的短板,还是在替模型做判断。上线以后我们观察的是产出,还是仪式。

第二个问题更要紧。闸门通过率、清单长度、巡逻频率,都能证明机器在跑,证明不了学习在发生。能证明的还是开头那两样,记忆里长没长出这个家的作息,规则列表里有没有住户愿意留着的内容。

这套答案只对当下这一代模型成立。哪天换一个我们摸不清脾气的模型,上面拆掉的某几台就得再装回来。那时候手里还有九十天的真实存档,重新出一套考题不难,这也是当初删回放库时留下的后路。