1. 复盘 Webminal:为什么搜索引擎拼不出 UML 的取舍
Webminal 的 15 年老架构最让复盘者头疼的地方在于:当整个行业都在聊 Kubernetes、云原生和自动扩缩容时,它靠一台 8GB 内存的 CentOS 服务器服务了 50 万用户。想用 Codex 以 Agent 长会话方式逐段拆解这背后的取舍,我建议先准备 TaoToken 的 Key——打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册并创建 API Key,再把 Codex 的 Base URL 指向 https://taotoken.net/api,剩下的 UML 用户态内核、Shellinabox 兼容和内存瓶颈,就能在同一段上下文里串成体系。
1.1 浏览器里那个「真实 Linux 终端」到底是什么
原报道里,Lakshmipathi 的出发点很简单:市面上的 Linux 教程大多是「伪终端」,点一下 Run 按钮,执行一段命令,教学就结束了。Webminal 想要的是完全没有运行按钮的界面,用户敲进去的每条命令,都像在一台真服务器上执行。这个「真实」不是宣传词,而是技术约束——初学者要练 fdisk、LVM、RAID、mkfs 这类底层操作,它们需要一个能真正被修改、甚至被改坏的块设备。
Docker 可以提供 shell,也可以提供隔离环境,但容器给用户的 /dev 和块设备视图是经过隔离、抽象过的,磁盘层大多落在 overlayfs 或 volume 上。fdisk 改分区表这种操作,在容器里只作用于很薄的容器层,用户感受不到「真的有一块磁盘被我改坏了再救回来」的过程。把这段诉求整理成复盘的第一问:「Webminal 为什么坚持不用 Docker?fdisk 和 mkfs 在容器与 User Mode Linux 里有什么区别?」这比直接搜索「UML 是什么」更有价值,因为问题本身就带着决策语境。
1.2 散落的技术决策,长会话才有上下文
搜索引擎能查到 UML 是 2001 年出现的用户态内核,也能查到 Shellinabox 早在 2017 年就停止维护,但它查不到「为什么 2017 年一篇西班牙博客带来 1 万日增用户时,这台 8GB 内存的机器没有崩」;也查不到「2021 年数据中心火灾丢了 15 万账号之后,项目为什么没有顺势迁上云」。这类判断跨越十几年,搜索结果只能给你一堆结论碎片,拼不出决策链。
Codex 的 Agent 长会话正好补上这一块:不急着换话题,让模型在同一个上下文里不断追问「当时为什么不选容器」「后来为什么切回 Shellinabox」「内存瓶颈到底卡在哪一步」。多轮请求之间,上下文是连续的。TaoToken 在这里的角色就是稳定的 API 通道,确保这一整段长会话的每一轮请求都有 Key 可认、有额度可扣,不用频繁重开上下文。
2. 拿 Key 并配置 Codex:TaoToken 官网与 Base URL 各司其职
2.1 在 TaoToken 创建 YOUR_API_KEY
打开 TaoToken 注册登录,在控制台的 API Keys 页面创建一把 Key。为了行文统一,下文全部用 YOUR_API_KEY 指代。注册、创建 Key、查看模型广场、核对用量,都在这个官网落地页完成。
需要特别掰开的两类地址:官网落地页是给人点的,https://taotoken.net/?utm_source=taotoken_aicg_blog_end 负责账号和 Key 相关动作;Codex 配置里填的是接口地址,https://taotoken.net/api,末尾不要加 /v1。一旦填成带 /v1 的路径,Codex 拼接 /models 或 /chat/completions 时会多出一层目录,请求路径就对不上。这是配置环节最容易踩、也最好排查的问题。
2.2 config.toml 里把 Codex 指到 TaoToken
Codex CLI 的原生配置在 ~/.codex/config.toml,不像部分工具那样靠环境变量直接配。把下面这段保存到用户目录下的 .codex 目录里:
# ~/.codex/config.toml model = "YOUR_MODEL_ID" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY"这里的配置逻辑是:Codex 读到 model_provider 是 taotoken 后,会去 model_providers.taotoken 里找 base_url,把请求发到 https://taotoken.net/api;同时读 env_key 指定的环境变量 TAOTOKEN_API_KEY 作为鉴权凭证。所以保存文件后还要先导出环境变量再启动:
export TAOTOKEN_API_KEY=YOUR_API_KEY codexYOUR_MODEL_ID 不能凭记忆填,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 模型广场,以当时列表里显示的模型 ID 为准。启动后先问一句「Webminal 的技术栈有哪些关键组件」,如果 Codex 能答出 Python 2.7、Flask、Shellinabox、User Mode Linux 这些词,说明通道已经通了,可以开始正式的复盘对话。
3. 把原文拆成逐段追问的 Agent 会话
3.1 第一轮:UML 与 Docker 的「真实感」之争
复盘第一轮,把原报道里最反直觉的矛盾抛给 Codex:「Webminal 做在线 Linux 教学,为什么坚持不用 Docker?请从 fdisk、LVM、RAID 和 mkfs 的教学场景解释 Docker 不够真实在哪里,User Mode Linux 的用户态内核为什么能补上这个缺口。」
模型给出的分析会落在两个层面。第一层是块设备的真实性:Docker 容器可以跑命令,但磁盘层是 overlayfs 或 volume,fdisk 改分区表这种操作只在一个很薄的虚拟层上发生,用户感受不到「真的有一块磁盘被我改坏了再救回来」的过程。第二层是运行级别:UML 给每个用户启动的是一个完整的内核实例,它有真实的虚拟块设备,4 个 64MB 的盘摆在那里,分区、格式化、挂载、搞坏、重来,每一步都像在一台独立的机器上操作。
3.2 第二轮:Shellinabox 兼容性为什么会反超 WebSocket
第二轮的提问可以这样写:「Webminal 曾尝试用 WebSocket 终端替换 Shellinabox,上线几小时就出现白屏和 Firefox 兼容问题,最后切回老方案。请分析 Shellinabox 这种 2005 年的工具,凭什么在防火墙、代理和企业内网的环境中反而比新方案更可靠。」
长会话的优势在这一轮开始显现:Codex 会自然引用第一轮得到的 UML 结论——既然每个用户跑的是独立内核,HTTP 层的兼容性优先级就高于交互体验,因为很多初学者是在学校机房、公司代理后面打开这个网页的。Shellinabox 走的是最朴素的 HTTP/HTTPS 通道,不依赖需要额外放行的 WebSocket 端口,所以它能穿透更多网络环境。这个判断单独搜也能得到,但放在 UML 隔离的上下文里,就组成了「因为底层够真实,所以上层必须够保守」的逻辑链。
3.3 第三轮:8GB 内存、50 万用户与 15 万账号丢失
第三轮丢给 Codex 的是时间线:「2017 年单日 1 万用户暴涨、2021 年数据中心火灾丢失 15 万账号、荷兰多次停电,加上累计 50 万用户,全跑在一台 8GB 内存的 CentOS 上。请拆解这台机器能撑住的架构原因,以及 8GB 内存真正的瓶颈出现在哪一层。」
我试过让 Codex 单独分析这三次事件,它会发现一个容易被新闻忽略的事实:火灾丢账号之后,项目依然没有迁移到分布式。原因不是技术评估不过关,而是整个项目由一两个人维护,迁移到多节点的成本主要集中在人,而非机器。UML 的 COW 共享镜像设计则解释了为什么 8GB 能扛住大量并发——基础镜像是全局共享的,用户写入才增加很小一部分存储,这是内存和磁盘都省的关键。这里不建议让模型输出「提速几倍」「并发提升多少」这类拍脑袋数字,公开报道没有给过准确口径,以它自己的推理过程和当前模型广场列表为准就好。
3.4 第四轮:把 eBPF 与 2800 万条命令也丢进上下文
原文里还有一个容易被略过的细节:首页滚动的实时命令流不是模拟数据,而是 eBPF/execsnoop 追踪的真实用户命令,已经累计超过 2800 万条,展示前做匿名化处理。第四轮可以这么问:「Webminal 整个技术栈里唯一现代的是 eBPF,它为什么被保留?UML 的隔离机制对命令流的匿名化展示有什么帮助?」
Codex 的回复会指向一个有趣的对照:越老的架构越依赖 OS 层次的可见性。UML 让用户拥有完整内核,但平台依然需要知道大家在敲什么命令;eBPF 在主机层做轻量追踪,不需要侵入每个 UML 实例,不需要记录参数和路径,只要命令本身。这样一来,2800 万条命令既是教学社区的数据资产,又不会变成隐私包袱。到这一轮,原始报道里的技术点几乎全部被放进同一个上下文了。
4. 用一份含 UML 隔离与 fdisk 练习路径的复盘结论来验证
4.1 让 Codex 输出 UML 隔离与 fdisk 练习路径
四轮追问结束后,追加一条收尾指令:「请输出一份 Webminal 架构复盘结论,需要包含四部分:UML 用户态内核的隔离原理;fdisk/LVM/RAID 在 64MB 虚拟块设备上的练习路径;8GB 内存支撑 50 万用户的关键假设;如果换成容器化,哪些学习场景会失效。」
多轮请求是否真的跑通,看这条结论的完整度就知道。你会看到 Codex 组织出来的答案大致是:每个用户启动一个独立 UML 实例,4 个 64MB 虚拟块设备配合 COW 共享镜像,练习时从 fdisk 查看分区表开始,到 mkfs 创建文件系统,再到 mount 挂载验证;容器化之后,内核共享让「改分区表感受不到物理风险」,教学价值就打了折扣。如果输出能到这一步,说明长会话没有在半路丢上下文,TaoToken 的 Key 在这个过程中正常结算了所有轮次。
4.2 回控制台核对这次长会话的用量
复盘结束后值得打开控制台对一下账。登录 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content= 查看这把 YOUR_API_KEY 在这一段长会话里的调用次数和 token 消耗。这一步不是为了查账,而是确认每一次追问都真实走了 API 通道,而不是本地缓存或离线补全。
5. 跑通之后:Codex 复盘清单与两个排障点
5.1 model not found 多半是模型 ID 问题
Codex 配好后最常见的报错是模型不存在。原因几乎都出在 YOUR_MODEL_ID 填了脑补的名字。模型 ID 必须和 TaoToken 模型广场当时的列表完全一致,别用旧截图里的 ID,也别加日期后缀。打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 模型广场核对,复制列表里的原样字符串再填回 config.toml。
5.2 环境变量没被 Codex 读到
如果报错是密钥无效,先检查环境变量是否真的导出成功。运行 echo $TAOTOKEN_API_KEY,看输出是不是 YOUR_API_KEY 本身。另一个隐蔽问题:config.toml 里 env_key 写的变量名和你 export 的变量名必须完全一致,Codex 不认识其他名字。加了新 Key 之后记得在新终端里重新 export,已经开着的终端不会自动刷新环境变量。
5.3 下一步:先验一遍 Key,再去复盘其他项目
这一套配置跑通后,可以先用 TaoToken 模型对话 发一条测试消息,确认模型 ID 没填错;要跑更长会话,打开 Coding Plan 看套餐是否够用;为不同项目分别建 Key,在 API Keys 管理页 创建。如果之后想让 Claude Code 也走这条兼容通道,环境变量写法见 Claude Code 接入文档。Webminal 的复盘只是起点,同一段长会话思路,可以继续拆解其他「单机扛住海量用户」的案例,把搜索不到的决策链一条条问出来。