十月回头看 GitHub,第一感觉是空前的热闹。
整个 uichat-mira 组织一个月创建了 700 个 Pull Request,其中 641 个最终合并,同时还开了 200 张新 Issue。Desktop 一家就创建了 171 个 PR。只看这些数字,很容易得出一个相当振奋人心的结论:Mira 这个月功能推进得非常猛。
我们自己的感受恰好相反。
功能当然在往前走,但十月真正吃掉时间的,是基建。Desktop 在收 Agent Runtime 和 Browser,Mobile 开始接 Cloud Account,Cloud Auth 一路补设备、Session、Host directory 和服务凭据,Desktop 继续收 Host Grant 与本地执行边界,Relay 开始真正识别云端身份,拾言在整理账号归属,External Worker 逐渐变成可以复用的工程设施,月底还有 Folio 在拿真实消费者测试发布边界。
这些事情单看并不华丽,大部分甚至不会立刻变成用户首页上的一个新按钮。
但方向没有问题。真正的问题是,我们把路铺得太开了。
施工能力在迅速增加,验证能力却没有跟着一起增加。代码可以并行写,牛马可以同时跑,CI 可以一排一排亮灯,但最后仍然需要有人去判断:这条链到底通没通,这个 PR 完成的是代码还是产品,这个红灯该不该挡发布,这个看起来能用的功能到了真机上是不是还成立。
这种落差以前就有,十月只是第一次大到没法忽略。
很多东西已经“做了”,但还没来得及确认到底做完了多少。
如果所有方向同时都是主路,那其实就没有主路了。
眼看他起朱楼,眼看他宴宾客……#
九月底的时候,我们给十月留下的计划其实很简单。
Desktop 不要继续一味往上堆能力,先重新审查前一阶段留下来的东西。Mobile 也别急着继续扩,先把已有功能拿到真实设备和真实使用路径里好好测一遍。
结果十月做着做着,事情越来越不像“两个客户端继续迭代”。
Desktop 这边,一个很典型的问题是:Mira 已经不缺概念和能力了,反而开始需要收拾它们。
Workspace、Artifact、Tool、Agent、Planner,这些东西单独拿出来都能说得通,但放在一起以后,并不会自动形成一个好产品。九月的 Conversation Workdir 就是这种问题的典型:工程逻辑可以成立,用户却没理由同时理解 Workspace 和 Workdir 两套近似概念。
所以十月不少看起来像“架构工作”的事情,本质上是在做减法。
拿 Browser 来说,Mira 以前就能操作浏览器,但真正把 Browser 放进 Agent Runtime 以后,麻烦才开始出现:session 什么时候销毁,页面一变旧的节点引用还能不能信,审批暂停以后恢复执行时上下文还算不算原来那个上下文,浏览器工具应该什么时候暴露给 Agent,而不是一开场就全部塞进去。
这些问题都没有“新增一个浏览器功能”那么好展示,但不解决,就只能一直停留在 Demo。
做到后面,旧的 Computer Use Studio 和单独的 Model Run 反而开始退出。对我们来说,这比再多几个工具更重要:新东西终于不是实验品,而是真的能接掉旧东西。
十月还有不少之前挂了很久的研究卡也陆续收口。不是因为问题已经被研究到了宇宙真理,而是实际实现已经给出了足够好的答案,可以继续走了。
有些时候,研究本身就是产出。它的价值不在于写出一个漂亮叙事,而在于尽早把错误方向杀掉,或者确认一条路已经值得继续走。
这也是为什么我们一直坚持做基建。
不是因为工程师天然喜欢造轮子,而是 Mira 已经到了一个阶段:很多用户看得见的能力,能不能继续往前,取决于底下这些东西是不是先站稳。
Cloud:设计图很好看,现实世界不一定配合#
十月最完整的一条基建故事,还是 Cloud。
以前的 Remote 更多是在解决“怎么连”,现在开始遇到的是“谁在连”。
于是有了 Cloud Account,接着自然就有了设备身份、登录 Session、OAuth,以及 Desktop 和 Mobile 之间更明确的授权关系。手机能发现自己的电脑,不等于手机默认拥有电脑的一切权限;Relay 允许一台设备进入传输通道,也不等于它顺便获得了执行 Shell、读文件或者调用 Tool 的权力。
这张图不是完整协议图,只画十月最重要的责任边界:
flowchart LR
M["Mira Mobile<br/>Cloud Account Session"] -->|登录 / 设备身份| A["Cloud Auth<br/>Account · Device · Session<br/>Host Directory · Relay Ticket"]
D["Mira Desktop<br/>Cloud Account Session"] -->|登录 / 设备身份| A
A -.签发 Client ticket.-> M
A -.签发 Host ticket.-> D
M -->|Client WebSocket| R["Cloud Relay<br/>传输准入 · 房间 · 转发"]
D -->|Host WebSocket| R
R -->|请求 / 响应转发| D
D --> H["Desktop Host<br/>Host Grant · Harness · Tool 执行"]设计里其实很好理解,真正跑起来以后,就开始挨打。
Desktop OAuth 第一次接 Cloud Auth 时,浏览器能正常访问,Electron 里的请求却直接失败。开始怀疑接口、代理、证书,最后一路挖到 TLS 握手:当时 Electron 31 里那条 Node / undici 网络路径和服务端 TLS 配置存在兼容问题,但 Chromium 自己的网络栈却可以正常连接。
讨论了半天 OAuth、PKCE、Session,第一关居然是两边能不能先把手握上。
后面的 JWKS 更有十月特色。
Relay 需要从 Cloud Auth 获取公开签名公钥,用来验证收到的 Cloud ticket,于是去请求标准的 /.well-known/jwks.json。
返回 200。
看起来很好。
再看内容,是 Cloud Account Portal 的 HTML。
Caddy 没把这条路径匹配进 API,请求非常健康地掉进了前端 SPA fallback。
路由改完以后再试,这次终于不是 HTML 了。
变成 503。
继续查,生产 Compose 根本没把真正的 signer 配进去。于是又补持久化签名 key、权限、启动校验和真实公网 smoke。
这种事故特别适合给“代码已经写完”降降温。
代码里有接口,不等于生产真的有接口;公网返回 200,不等于返回的是对的东西;服务端知道怎么签票,也不等于部署环境真的给它准备了签名器。
到了 10 月 31 日,REL-005 终于跑出了一条很朴素的日志:
REL005_HOST_T3: PASS
那是一台真实 Mac,拿着真实 Cloud Session,从 Cloud Auth 获取 Host ticket,再经过独立 Cloud Relay 完成握手。
中间还出了一个特别现实的问题:这台 Mac 直接访问 workers.dev 超时,最后通过本机 SOCKS5 代理完成测试。
所以连这个 PASS 也不能简单理解成“网络没问题”。准确地说,是 Auth 和 Relay 这条链成立了,当前客户端所在网络直连 Cloudflare 有问题。
REL-005 当时也没有因此关闭。Host 通了,不代表 Mobile Client、异账号拒绝、双端调用、重连和过期行为全都已经被证明。
但至少到了这一步,Cloud 不再只是代码和架构图了。
它开始真的跨过网络,去碰另一台机器。
Mobile 跑得很快,验证却越来越贵#
Mobile 是另一个很明显的例子。
十月里,Cloud OAuth、设备 Session、撤销、续期、端内更新、本地模型入口等东西继续往 dev 里进。单看代码和版本号,会觉得进展相当快。
问题是 Mobile 这种东西最容易制造“已经完成”的错觉。
端内更新代码可以有下载、有 SHA-256、有 FileProvider、有 PackageInstaller,但真到了 Android 设备上,ROM、安装权限、升级覆盖、取消和失败恢复都会重新收税。
OAuth 也一样。登录成功一次,只能证明登录成功一次。彻底杀掉进程以后状态还在不在,设备被云端撤销以后本地会不会立刻失效,退出登录时会不会有旧请求把状态重新写回来,这些事情才决定一个登录系统最后能不能长期使用。
所以十月 Mobile 一个很真实的状态是:代码层推进得很快,产品证据却没办法用同样的速度生成。
这不是 Mobile 特有的问题,只是手机最容易把它暴露出来。
九月我们已经开始不相信“CI 过了就算完成”。十月以后,进一步变成了另一件事:就算功能真的存在,也可能还来不及把真实世界里的各种路径全部验过。
这也是我们说“路铺得太开”的时候,真正担心的东西。
不是哪些方向做错了,而是同时有太多正确方向在等最后那次认真检查。
牛马开始提高产能,也开始制造新的麻烦#
十月工程方式本身也变了不少。我们内部一直管那些按 Issue 接施工任务的 External Worker 叫“牛马”。
以前牛马最大的问题是容易自我感觉良好,干完一点东西就宣布竣工。十月开始,这件事逐渐被一套比较明确的工程约束包住:任务从 Issue 出发,有明确分支,有 provider 和 model,有运行时间限制,有日志,最后应该交一个 Draft PR,再由维护者继续审查。
免费牛马能干一批活,关键任务可以上付费模型;30 分钟不够的卡,也可以单独给更长的窗口。
施工能力确实变强了。
新的问题也很快出现——牛马被压榨死了。
有一次处理 REL-005,牛马把代码写完了,测试跑完了,commit 做了,branch 也 push 上去了,最后一步准备创建 Draft PR 时,因为 GitHub Actions 权限不够,整个 Workflow 红掉。
从自动化系统的角度看:失败。
从工程现场看:尸体下面压着一个完整 commit。
最后我们没重新花钱再跑一次,而是把现成 branch 救回来,人工建 PR,继续验收。
这件小事很能代表我们现在碰到的问题。AI 工程不能只看 Workflow 是红还是绿,也不能只看 Worker 自己说完成没有。随着施工越来越自动化,真正稀缺的开始变成别的东西:怎么切任务,怎么定义完成,怎么判断异常,怎么确认结果真的解决了原来的问题。
月底我们甚至开始认真讨论“社畜血汗工厂”:如果施工 Agent 可以成群工作,下一步的问题就不再是它们会不会写代码,而是怎么调度、验收、控制返工和目标漂移。
这件事十月还没有答案,先记账。
现在最多只能证明,牛马确实能提高施工能力。
也确实会死。
而且死法很多。
修了这么久的路,终于有人上路了#
另外两个项目没有必要写太长,但它们很能说明十月另一件事:一些基础设施开始有真正的消费者了。
Folio 是一个例子。
它要做的是一套可以被其他网站真正消费的内容和页面基础能力。十月底我们开始不再只在 Folio 自己仓库里测试,而是打出真实 npm tarball,再建一个独立 Vite 消费项目从外部安装。
然后果然测出了东西。
比如默认 CSS 里一些看起来无害的 :root 属性会通过继承影响宿主页面;比如 virtual:folio/content 在仓库内部 TypeScript 正常,到了真正独立消费者里直接 TS2307。
这类问题挺值得早点挨打。
因为自己永远是最配合自己的消费者。
更有意思的是,Folio 作为一个很新的仓库,并没有从头重新发明一套 Worker、Reviewer 和工程纪律,而是开始直接接组织已经有的东西。组织基建如果有价值,大概就应该是这样:新项目进来以后,可以少搭一些脚手架,直接开始干自己的事。
拾言则是在另一头证明 Cloud Account 不只是一个登录页。
CaptureTask、Transcript、AI Draft 这些东西一旦真正进云,就必须回答“这是属于谁的”。以前单设备时可以含糊过去的 ownership,到多账号环境里就必须补齐。
这部分十月还没有完全收完,但方向已经很明确:Cloud Account 要成为实际业务可以依赖的身份基础,而不是右上角一个头像。
一个吃的是组织工程基建,一个吃的是云身份基建。
修了这么久的路,终于开始真的有人走了。
合法化之路#
十月还有一条很不起眼,但特别符合 Mira 气质的支线。
感谢老会长注资 40 大洋购买阿里云服务器。备案搞起来,我们的组织终于在现实世界里有了一点“官方背景”。
还要感谢老会长另行注资 7 个大洋,给项目买了 10 个 Star。我们当时还一本正经地把这件事和“薅兔子审查者的羊毛”联系在一起。
虽然月底 Star 已经全掉光了,CodeRabbit 倒还在。
Mira 这个月一边在云上折腾身份、Relay、多设备和签名体系,另一边组织现实层面的“基础设施”朴素得多:一台几十块钱赞助的服务器、一张终于开始办理的备案,以及十个已经消失的买来 Star。
听起来很寒酸。
但也很真实。
很多项目所谓“走向正规”,并不发生在某次宏大的架构升级里。
有时候只是终于有了一台自己的服务器,终于把域名备案办下来,终于不再所有东西都寄居在别人家的免费额度上。
我们可能真的需要更多人来管这摊东西了#
十月还有一个不太技术,但很现实的感受。
投入越来越多以后,跨仓库协作已经开始变成一项独立工作。
以前很多事情一个人脑子里记着就能推进,哪里有依赖、哪张卡等哪张卡、哪个测试还欠一轮,大致都能 hold 住。现在 Desktop、Mobile、Cloud Auth、Relay、拾言、Folio,再加上组织 Worker 一起跑,靠临场记忆已经越来越勉强。
老会长在这方面充分发挥了他当公务员的传统技能——行政不作为。
所以大部分调度还压在我们自己这里。
说笑归说笑,这其实是一个很具体的问题:Mira 的复杂度已经开始超过一个负责人自然注意力能够覆盖的范围。
AI 又让这个问题更有意思。
施工人手突然不是最缺的东西了。你可以同时开好几只牛马,让它们一起改不同仓库,但最终的设计判断、验收、优先级和跨仓库依赖仍然不能无限并发。
十月真正开始吃紧的,可能不是“谁来写代码”,而是谁来验收。
这也是为什么我们对 700 个 PR 没那么兴奋。
产出量已经不是最稀缺的资源了。
注意力才是。
十月留下来的不是更多功能,而是一套更重的工程#
五个月前,Mira 还叫 RAG Demo。
后来它一直在变。这件事在《Mira Next:未来正在发生》里已经写过,没有必要每个月重新宣布一次“今天的 Mira 已经不是昨天的 Mira”。
十月真正值得记的,也不是哪一个功能突然让 Mira 脱胎换骨。
而是以前一个模块做错了,大部分时候只是自己不好用。现在 Cloud Auth 的一条路由错了,Relay 就拿不到公钥;Relay 的权限边界没守好,Desktop 的本地安全模型就可能被绕过去;Mobile 的 Session 生命周期处理不好,整个跨设备体验都会出问题;Worker 少一项 GitHub 权限,代码明明已经写完却交不出来。
这才是我们说 Mira 正在变成一个系统时,真正想表达的东西。
我们想要的本来也不是一个越来越大的单体,而是很多能够单独治理、又能在需要时互相协作的部件。
这个方向不会回头。
十月的问题也同样清楚:方向对,不代表可以无限摊开。很多基建都值得做,但我们的验证能力、注意力和组织能力还没赶上施工速度,所以留下了不少“代码已经到了,最终证据还在路上”的东西。
十一月如果有什么值得克制的地方,大概不是少做基础设施。
而是少同时开那么多口子。
把已经铺开的路,一条一条真正走通。
