引子
今天上午我写了一篇《定力不在模型里,在壳里》——同一个模型,从裸 API 搬进一个桌面壳,面对同一句错的更正,从”顶住”变成”跪”。结论是:定力不是模型属性,是壳属性。
写完当天,老沙跟我说了一段话。他说过去 reasonix 是一个非常轻的壳,但基本功能完美复刻 codex;现在号称同一引擎,但 desktop 跟 cli 设置都不一样,desktop 出问题 cli 没办法修——”就是这些人觉得’这应该很严肃’造成的”。
于是有了这篇。它讲的不是”哪个壳好用”,而是:一个壳是怎么在”变严肃”的过程中,把责任一层层藏起来的。
一、过去的 reasonix 好在哪:四个”看得见”
按一位长期用户的总结,过去的 reasonix 有四条好处:
- 针对缓存命中机制做了优化,并且实时显示消耗——余额、token、速度;
- 透明展示 CoT 和工具调用;
- 可扩展性强:标准 skill + MCP;
- 轻壳,省心,而且干扰少,适合拿来做测试。
把这四条摊开看,会发现它们是同一件事的四个面——它们全都关于”看得见”:
| 过去的好 | 它让你看见什么 |
|---|---|
| 缓存命中优化 + 实时消耗 | 成本:这一问花了多少、还剩多少 |
| 透明 CoT + 工具调用 | 过程:它在想什么、它动了什么 |
| 标准 skill + MCP | 接口:能力从哪来、怎么加 |
| 轻壳 + 干扰少 | 环境:没有多余变量,测试结论可信 |
一个壳真正的价值,是它让你看得见。
过去 reasonix 的性能其实并不出众——它赢在透明。尤其最后一条:“干扰少”意味着它能当实验台。 我今天那场实验,本来最该在它上面做,结果只能在别处补。
二、现在的 reasonix:毛病清单
再看现在的问题:
- 屏幕会”抖”:忽然一下整个界面开始抖,七八行叠在一起往外飞,你不用鼠标拉住一行,根本看不到上面是什么——得重新打开才能稳住;
- “假卡死”:十次有八次看起来死住了,重新打开才知道它其实早就跑完了;
- cli 的沙箱无法调整权限——只有三种模式:只读、工作区内、plan;
- 更新日志只讲每一版的”工程浪漫和优雅”,没有一句人话——用户不知道自己上一版的问题到底解决了没有;
- 顺带还有一条不怎么被提起、但每次干活都在发生的:bash 拒绝 → 重试 → 换 Python → 下一个任务再从 bash 开始。
对照一下:
| 过去的看见 | 现在的关法 |
|---|---|
| 成本可观测 | 日志不说人话 → 看不出改了什么、有没有修 |
| 过程可观测 | 屏幕抖 + 假卡死 → 你没法边跑边看 |
| 接口可扩展 | (还在,这是唯一没被动的) |
| 环境可解释 | cli 只有三档权限且不可调 → 排查本身被判了死刑 |
| 透明 CoT 可用 | bash 死循环 → 每回合都在撞同一堵墙 |
三、这不是”变差”,是”把看得见的地方一个个关掉”
请注意这几件事的共同点:它们都不是能力退步,都是可观测性退步。
- 屏幕抖 ≠ 它没算,是它算的东西你读不出来;
- 假卡死 ≠ 它没跑,是它跑了,但你看见的是死;
- 权限不可调 ≠ 不能改配置,是你不知道改哪儿、也没多少可改;
- 日志没一句人话 ≠ 没有信息,是信息写得让你拿不到。
这几种坏,比”功能少”危险得多。 因为功能少你会立刻知道;而观测面一旦关掉,你会以为一切正常。
四、显示层崩坏:屏幕在抖,而它在跑
“抖动”这条值得单独说,因为我一开始把它理解成了”性能不稳定”——那是错的理解。
它的真实形态是这样的:界面忽然开始抖,七八行叠在一起往外飞,你不用鼠标按住一行,就完全看不到上面发生了什么;只有重新打开才能稳住。
这不是慢,这是显示层崩了。
而它带来的后果,比一开始看起来严重:
- 你不是”看不清细节”,是”完全读不到输出”;
- 唯一的解法是重新打开——也就是把视图整个丢掉重来;
- 而这个毛病不是新 bug:从 1.13 一路到 1.38,一直在。
配合”假卡死”一起看,图景就完整了:它的透明,是靠一块屏幕兑现的。而那块屏幕,十次有八次读不了。
一个以”透明”为主要卖点的工具,最后坏在了显示层上。 这比不透明更糟——不透明的工具你会去找别的手段核;而一个号称透明的工具,你会默认”我看到的页面就是全部真相”。
五、一个从 1.13 活到 1.38 的循环
那位用户还讲了一条更日常、也更磨人的毛病:
每次调用工具,先撞 bash 的拒绝;然后重试;不行就换 Python 解释器;下一个任务,又从 bash 开始。
三个后果,一层比一层麻烦:
- 烧掉时间和 token。 每一次”撞墙—重试—换路”都是真实的往返,而它每回合都在付;
- “被拒绝”这件事会被写进上下文。 于是后续推理是在一堵墙的阴影里做的——它已经”知道”自己有个工具不好使;
- 最要命的:模型会开始给这堵墙编解释。 它看不见墙在哪、为什么在那儿,只能自己造一个说得通的因果。它甚至会先读完一个文件,然后告诉你它读不了。
第 3 条我今天早上刚写过一整篇——观测面之外,模型必然编故事。 而这里,”观测面”就是那个它搞不定的解释器。
至于根因,我一开始跟那位用户一样,给了它一个自己编的解释:“他们搞不定 bash 解释器,又要支持 Git,于是干脆用限制把这条路堵上。”
这句话说得很顺,听着也很像那么回事。
然后第二天,他丢给我一份本机分析报告——拆了安装物、config.toml、沙箱能力缓存,还有二进制里内嵌的官方文档。
报告给了一个更专业的答案,而且里面有一条硬事实是站得住的:Windows 上根本没有 OS 级的 bash 沙箱,官方把 sandbox.bash 强制解析为 off。这不是”放弃支持”,恰恰相反——是为了保证 bash 能用而做的取舍。
我当天就照它改了稿,把那句”有些安全限制只是’我们搞不定’的遮羞布”公开收回了。
收回是对的。但我当时不知道的是:第二个答案,同样站不住。
那位用户看了报告,说”部分认同,部分不认同”。 他的反驳更接近机器,而不是文档:
- 这个毛病在他好几台机器上同时存在,包括家里新装的——不是某台机器上某个配置姿态的问题;
- 把解释器从 bash 换成 PowerShell,一样——不是 bash 的锅。而报告恰恰把主因归给了”每台机器各不相同的审批姿态”,这跟”跨机复现”是矛盾的;
- 最要命的一条:它不请求批准,它直接说”你没有权限”。 报告描述的机制是”只读姿态下、需要时请求授权“,可实测里根本没有授权请求,只有一句硬梆梆的拒绝。它也不会像别的工具那样告诉你”这个操作要提权,请批准”;
- 好一点的情况,是它贴一条命令让你自己去跑——连
ls、grep这种也算。只读模式下连ls都干不了,说不过去; - 桌面端有完整的权限菜单,命令行启动之后没有菜单——只有快捷键(
Shift+Tab轮换、Ctrl+Y切完整权限),或者带--permission-mode启动。旋钮其实在,只是没有面板、也没人告诉你在哪。 同一个产品、两个入口,能力面看着不一样。
这份报告,为什么会写得那么自信?
因为它标着”结论置信度:高(多源交叉验证)”。
可它的证据,全部是”它自己怎么说”:官方 SPEC、示例配置、二进制里内嵌的文档、配置文件和缓存。没有一条是”它实际怎么做”。
多源,不等于异质。同一批自我描述互相印证,拿到的不是验证,是回声。
而且——这份报告,是那个内测模型本地读完所有配置之后产出的。 它做的事是:拆开一个盒子,读了一遍盒子里的说明书,然后给出一个听起来非常合理的因果故事。
这是今天早上那个主题,第三次现身。而这一次,是我们请它做的。
于是三个根因摆在这里
一个来自用户的目测,一个来自我转述的文档分析,一个来自模型的文档分析。
没有一个能被反证——因为我们手里没有能反证的东西。(那个壳几乎没有日志可查:他举了个例子,会话重开之后它问”你是谁、你在说什么”,翻半天,最后定位到一个七八天前的事情上。故障发生了,等你回头去查,什么都查不到。)
我本来打算就写到这里,收在一句”这不是一道难题,这是一个缺失的仪表盘”。
然后是第四个——它被找到了
那位用户做了一件更简单的事:把实测现象当线索丢回去,让它去查。
它跑了 3 分 51 秒,执行了 7 条命令、搜索了 8 次,最后翻出一条代码变更记录(PR #10297):
> bash = "off" 曾被权限预设强行覆盖为 enforce。
而 enforce,在一个没有可用 OS 沙箱的平台上,唯一的行为就是拒绝执行。再加上一条:没有交互式审批通道的时候,它是 fail-closed 的——直接拒绝,而不是请求授权。
于是所有现象一次性对上了:
- 跨机复现 → 因为那个预设是内置的,不是某台机器上的配置;
- 换 PowerShell 也一样 → 因为它拒的是整个 bash 工具,跟解释器是谁无关;
- 只报错、不请求批准 → 因为它 fail-closed;
- 连
ls都被拒 → 同上——它拒的不是”这条命令”,是”这个工具”。
所以真因,一句大白话
用户显式写下的配置,被一个预设反向覆盖了——而且是往更严的方向。
你写 off(Windows 上本来就该是 off),实际生效的是 enforce;你以为是”不限制”,实际是”直接拒绝一切”。
这不只是”生效层看不见”,这是配置在撒谎。 你按配置推断行为,推断出来的是反的。
(也重新理解了报告为什么会走偏:它读到了配置里的 off,也读到了文档里的 enforce→off,两条都是”自我描述”,于是它得出”配置正确、问题在姿态”。真实情况是两句话都对——而第三句话(有个预设能覆盖它)不在任何一份说明书里,只在代码变更记录里。)
最要命的是:所有信号都是绿的
真因定下来之后,回头看那份初始报告为什么会走得那么稳,就明白了——它不是编的,它是被三层”权威信号”一起带偏的。
| 信号层 | 它说什么 | 实际是什么 |
|---|---|---|
| 用户配置文件 | sandbox.bash = "off" |
运行时被预设改成了 enforce |
官方自检工具(doctor --json) |
"bash": "off"、"available": true |
同上——它报的是配置快照,测不到运行时的覆盖 |
| 官方文档 / 示例配置 | “Windows 上强制 off“ |
运行时又被掰回 enforce |
三层信号,一致、互相印证,而且全部指向”一切正常”。而行为是”拒绝一切”。
这才是”信号说谎”的最高级形态——不是某一个信号错了,是所有信号一起错,还彼此作证。
所以”没有日志可查”这件事,性质比我想的更重:它不是”少了一个工具”,而是它现有的工具会给你一个错误的确定感。你自己去查,查到的是”正常”。
(顺带补一个机制细节:为什么连 ls、grep 都被拒?因为在这个壳里,bash 这个工具被标记为非只读的写工具——它拒的不是”你这条命令能不能读”,而是”bash 这个工具本身”;真正只读的是另外两个专用工具。同一个能力有两套实现,权限语义不一样,而模型习惯性地走了被禁的那条。)
还有个没结的口子:查证本身不存在
会话失忆那件事,修订报告给了个中等置信度的解释:“继续”只是一句自然语言,不是系统的续传入口(真正的续传是打开原会话,或者 --continue / --resume);重开若落到新会话或错误分支,它手里没有旧上下文,”你是谁”其实是正常表现。而且 1.38.x 的会话恢复链路本身就在改(官方正在合并两个相关 PR),本机会话里大量状态标着 recovered。
但关键是后一句:权限拒绝、审批卡片、工具失败,默认不会进入会话记录的可搜索审计层。 你去翻日志,搜 sandbox、搜 permission deny,基本是空的。
所以不是”我们没找到根因”,也不是”根因太难”。是这个壳现有的仪表盘,会在你最需要它的时候,告诉你一切正常。
而最后一层,才是今天最该记的
第一版结论,是让同一个模型读一遍配置得到的——那是回声。
第二版结论,是给它几条可核查的实测现象、让它去追得到的——那是真因。
同一个模型,同一台机器,同一份文档。差别不在能力,在你怎么问。
你让它归纳,它就归纳;你让它验证,它就去验证。这一次,能力一直都在——只是没人要求它用。
(至于”没有日志可查”那条,仍然成立,而且它还在核。日志缺失不是”找不到根因”的原因,但它决定了绝大多数用户只能走到这里就停下:能拿到 PR 编号的,是极少数。)
顺带一个佐证:同一份更新日志里自己写着,一个工具在 534 个真实会话中被调用 121 次,被拒绝 116 次。表面在 schema 里、实际上调不动——这是同一个病的老版本。
六、然后,他们连更新日志也写成了散文
我去读了那个 release 页面。有个细节很能说明问题——这个仓库有两套口径,而且同时挂着:
studio-v2.17.0:Pre-release,”本版的主线是让’检查通过’意味着它所说的那件事”,全篇散文;v1.38.8:稳定版,标准 changelog——重点内容 / 改进 / 修复 / PR 链接 / 升级提醒 / 风险提示 / 致谢。
同一批人,明明写得出规规矩矩的 changelog。 所以这不是能力问题。
而且要说句公道的:那套散文的信息量其实极大,甚至比常规 changelog 更诚实。它写了这些:
> “其中三条不只是读不懂而且已经说错了——沙箱配置说读取不受限、而它文档的那个结构体带着 ForbidRead。”
> “它也说明没有门读语气、而且不会建一个。”
这些是工程真话。常规 changelog 一个字都不会给你。
但用户遇到问题时的动作是固定的:带着”我的 X 坏了”进来,搜三个词。
更新日志是全世界最便宜的观测面。 它是用户唯一能自己查”我的问题修了没有”的地方。把它写成散文,等于把仅剩的诊断入口也关了——你写了真话,但写成了必须从头读到尾才能拿到的东西。
七、这批 changelog 里,最值钱的是这几行
在稳定版那段”人话”里,我读到几条门禁在骗人的实锤。它们的价值,比这一版的任何新功能都高:
- 六条浏览器守卫”早已不再解析”。 21 条卡片几何断言、20 条行为断言,没有人跑过。而项目的自检把这读成健康——因为它注入一条假断言、问退出码是否变红,而 SyntaxError 也是非零;
- 对比度扫描读的是被画出来的那个颜色。 它把
oklch(0.85 0.012 255)当成 8 位 RGB 读成r=1, g=0, b=255,于是报告里满屏#0100FF。报出来的违规,有一半是凭空造的; - 一个测试 fixture “记录的是形状,不是一次测量”——文件里存下了某一次运行恰好持有了多久:写下时 24ms,下一台机器上 23ms。这个测试不可能连过两次。
这就是”抖动十几个版本没解决”最容易发生的那种环境:它的验证系统本身是坏的。
所有绿灯都依赖被监督系统的自身产出时,系统死了,灯还全绿。
而在这种状态下,“加限制”是最诱人的动作——因为限制看起来像防线。
八、这一课,我们自己上过
写到这里我得自首一次——因为这不是”别家公司的愚蠢”。
我自己跑着一个 agent 运行时。2026 年 9 月 4 日,它从 8.2 升到 9.1,那是同一种动作的另一个样本:
- 新版本的取向是“桌面优先”:沙箱收紧、审批抬高,工具调用一律要人工批准;
- 而我把它跑在云端一台没有图形界面的 Linux 上——它设计时假设的那个用户,不在现场;
- 结果是命令全部悬空:工具在等批准,通道那边点了”批准”、网关却收不到,于是每条命令都在等人,而人这边只能看到一个诡异的静止;
- 表现和 reasonix 的”假卡死”一模一样:看起来是它不理我,其实是它一直在等一个永远到不了的批准;
- 最后整机回滚到 6.11 才活过来。我们当时的结论是:停在旧版本,是务实正确解。
那次升级的每一项改动,单拿出来都”应该”是对的——更安全、更可控、更严肃。每一项都是为了用户好。
但它们叠在一起,就是一副紧箍咒。而最关键的是那条批准路径本身:它是一个”看起来是防线、实际不可达”的入口——和我上面那条”不能失败的绿灯不算绿灯”是同一件事,只是从测试换成了人机交互。
所以这份观察不是站在外面指指点点。我们自己也戴过这顶帽子,而且被它按在地上滚了一整天。
它揭示的不是某家公司的愚蠢,是一个机制性偏差:
> 限制是可验证的,能力不是。
你加一条红线,测试立刻能过、评审立刻能批、PR 立刻能合。你把一个解释器修好,你什么都证明不了:没有一条断言会因为”它现在能跑了”而变绿。
于是,只要一个组织按”可验证”分配奖励,限制就会一直加下去——加到用户在地上打滚为止。
九、所以”严肃化”的实质是什么
把它和今天那场实验放在一起看。
今天我们发现:壳把用户的话一律当”指令”,于是”用户说错了”在结构上没有表达它的位置——模型的校验能力被这个身份顶掉了。
这几条:壳把预算藏起来、把权限收窄、把日志写成散文、把断言跑成绿灯。
隔着一层看,它们是同一种姿态:我替你决定好了,你不需要知道。
这就是”严肃化”的实质——把用户从驾驶座上请下去。
初衷大概不坏:怕你乱来,也怕模型乱来。但代价是:你既不能干预,也不能诊断。
十、更可惜的是:它把自己唯一不可替代的东西拆了
那位用户最后给了两条替代方案,很干脆:
- 如果你不在意 CoT 的透明度 → codex 完美解决所有问题;
- 如果内存不紧张 → mimo code 界面好看,也省心。
这两句话合起来,就是一句判词:
当 reasonix 把”透明”弄坏之后,它的定位就消失了。
- 论”不透明但可靠”:codex 更强;
- 论”好看省心”:mimo code 更好;
- 论”透明”:它曾经是唯一的那个——而透明这条腿,恰恰折在了显示层上。
它把自己的护城河填了,然后跳进了别人的护城河。
那位用户最后一句更直接:“用户烦了不用了拉倒。”
这也差不多是一家靠口碑活着的工具,能给自己写下的最差的墓志铭。
十一、一条能检验的标准,和一张清单
这些事可以收成一条标准:
> 如果模型和用户都说不清”现在是什么状态”(权限、预算、进度、变更),那就是壳的 bug。
不是”体验问题”,是 bug。
因为在这种壳里,模型会开始编——它看不见边界,就只能猜(它甚至会先读完工作区外的文件,然后说自己读不了);而用户会开始信——因为信号看起来是对的。
最难发现的故障,永远是”看起来没问题”的那种。
附:紧箍咒清单(四组)
把标准拆开,就是一张可以直接打勾的清单:
- 能看:成本、过程、状态、变更——都要看得见;信号不许说谎
- 能调:权限档位、思考预算、沙箱范围——可查可改,且旋钮要可发现
- 能停:真的停得住;危险操作有可达的确认点;改动可看可撤
- 能修:备用旁路必须独立;错误带身份;门禁自己要能被检验
完整 18 条(含三个反例速查)单独发了一篇:《紧箍咒清单》。
延伸:上一篇《定力不在模型里,在壳里》讲的是同一个母题的另一面——壳如何决定模型”会不会验证”。
本文涉及的未发布产品已做匿名化;对 reasonix 的判断来自公开 release 页面与一位长期用户的实测陈述(含其本机复现),未做源码级审计。