别再做终端界面了
摘要
作者主张用原生用户界面替代终端界面,并展示了几个借助AI以极少量代码创建的应用程序。
暂无内容
查看缓存全文
缓存时间: 2026/08/21 07:22
# 别再做终端界面了
来源:https://sockpuppet.org/blog/2026/08/20/stop-making-tuis/
**我们行业对终端和命令行界面的态度一直很奇怪。现在是时候重新审视一下了。**
最近我热衷于让朋友们尝试构建原生用户界面。几个月前我开发了第一个正式的 Mac 应用程序,此后做的原生 UI 项目比我之前整个职业生涯做的还多。我们来快速浏览一下。
MDV.app,一款原生 macOS Markdown 查看器
这是 MDV.app(https://github.com/tqbf/mdv),世界上最好的 Markdown 查看器,直到有人写出另一个更专业的 Markdown 查看器为止。我之前已经写过一些关于 MDV 的内容(https://sockpuppet.org/blog/2026/05/12/emacsification/),就不在这里多做推销了。不过它确实很棒。
我几乎没怎么手写这个界面的代码。为什么要手写?和大多数用户界面一样,MDV 没有什么开创性。这不是什么难题。但构建好的 UI 非常困难:这类代码既繁琐又重复,要求精确,而且需要掌握平台的概念知识。要擅长这类工作需要多年时间。这就是为什么我绝不会手写这个程序。相反,我把它“召唤”出来了。
继续往下看:
SageMath 的原生计算器风格前端
过去一年我一直在用 Math Academy(https://www.mathacademy.com/),从 Foundations I 到 Machine Learning,可以简单概括为“我自学了微积分”。我非常喜欢 Math Academy,有很多想说的,但在这里它只是我凭空创造的另一个 SwiftUI 应用的背景:一个原生计算器风格的前端,用于 SageMath(https://www.sagemath.org/),这是密码学家的默认数学系统。
这个应用为我做了三件大事:它自动将 Sage 输出渲染为 LaTeX,这在你深入学习多元微积分时变得越来越方便;它通过点击就能暴露向量、矩阵和表达式等对象的 Sage 方法(这比反复输入 `trig_simplify` 好多了);它还提供了一种“小语言”式的简写输入,使得常见操作(比如“求这个表达式的梯度”)能快速输入。在这个系统里 `\[1,2;3,4\]` 就是一个矩阵;你听了应该已经心动了。
我不会打包这个应用。如果你想要,直接截图这部分内容给 Claude 看就行。它会构建出有用的东西。你明白我的意思了吧。
DJ Roomba,我的 Apple Music 播放器
(如果我整理一下所有的流派标签会更有用,大部分标签可以追溯到 1997 年我第一次抓取 MP3 的时候)。这是 DJ Roomba,我的 Apple Music 播放器。流派映射是个可疑的功能。不可疑的是内置的 LLM 代理,它能调用工具读取我的音乐库、上次播放列表和接下来要播放的曲目。“我要去地下室工作室做一个相框;给我一个不会跳歌的播放列表,符合这个心情就行”。结果心情是“很多 Kurt Vile 和 Tom Petty 的歌”。没毛病。
它背后是一个 SQLite 数据库,一个合理的数据库,有着合理的 schema,这也是一个非常有用的功能。
我其实不知道该怎么看待这类程序。这是一个 AI 辅助的音乐播放器,包含了 Music.app 90% 的界面。Music.app。我永远的个人计算宿敌。这相当于在个人计算领域屠龙。但我没在里面写一行代码。我这是在开发软件,还是只是在配置我的电脑?
先记住这个想法。
Self Driving Wiki.app,我的 LLM 维基百科
这是我的 LLM wiki。应该有人写一篇广泛传播的文章,讲讲一个自动驾驶的维基百科有多有价值:你给它喂资料,向它提问,它就能为你编写维基。这个想法非常有用,我很高兴我想到了它。
写 Self Driving Wiki.app 很有趣。与直接嵌入 Responses API(https://developers.openai.com/api/reference/responses/overview)客户端的 DJ Roomba 不同,这个应用在底层调用 `claude -p`。因为我假设代理在有文件系统可探索的情况下工作得更好,所以我召唤了一个 macOS 虚拟文件系统扩展,它在应用的沙盒内将后端 SQLite 数据库的只读视图挂载为一个文件系统。
这可能不必要吗?它会让应用更难安装吗,比如要求它必须从 `/Applications/` 运行?是的,而且也是肯定的。但这种为了理顺事情的琐碎探险是前 LLM 时代软件开发的乐趣,我很高兴发现今天我还能体验到。
一个半自动化的食物宏量追踪器
(在 2.5 剂量下超级反应者,零副作用,这东西真棒)这是我经常使用的东西:一个半自动化的食物宏量追踪器。我和大家一样在注射 tirzepatide(https://en.wikipedia.org/wiki/Tirzepatide)。这个应用是另一个简单的代理,接入了 GPT5,接收非常简短的餐食描述,比如“猜猜我吃蛋糕糊和奶油奶酪糖霜(但我没吃蛋糕)摄入了多少卡路里”,并将其转化为摄入量估计值。
Thermite,一个菜单栏温度计
这是一个菜单栏应用程序,使用那些便宜的 TP-Link 温度传感器追踪我房子周围的温度,这些传感器正在让中国共产党访问我的 Apple TV。通常在完成这类东西后,我能告诉你更多关于它们用来通信的协议和 HTTP API,但我没有花时间去弄清楚,所以我只能告诉你,有两条不同的登录路径可以从它们的云端和直接从小传感器荚获取信息。
一个菜单栏 Apple TV 遥控器
最后,说到我的 Apple TV,我带来了 macOS 原生桌面软件开发的圣杯:一个可用的菜单栏 Apple TV 遥控器。几年前,我会为此付很多钱,因为我就是那种人:和配偶一起看《忍者之家》时,腿上放着一台打开的 MacBook。
(还有我的 Roku TV 和 Denon 功放,因为这是个万能遥控器)直接与 Apple TV 对话很麻烦。但事实证明,人们已经解决了这个问题,并编写了 Python 库来实现。我并不“使用”那些库,因为这是一个原生 Swift 应用,但这没关系:任何用 Python 写的东西,也都可以用 Swift、C# 和 Brainfuck 实现。对前沿模型来说都一样。
我有一定自我意识。对我生成的这些 SwiftUI 界面进行挑剔,显然会招致对其视觉设计毫不留情的临床批判。放马过来吧。但是:作为 App Store 的长期用户,我敢说这些设计都高于平均水平。五年前,如果我的团队里有一位 macOS UI 设计师,能得到这种质量的输出我会欣喜若狂。
事实是,我几乎不把它们当作“应用”(我没打算分发它们)。它们是我让计算机按我想要的方式为我做事的产物。作为一个 Unix 极客,我总是能用命令行语言做到这一点。现在,用图形界面做这类工作同样容易了。
❦
我们构建终端界面是因为必须,而不是应该。
**但首先,谈谈 CLI 和 TUI:** 命令行界面和终端用户界面都是 1970 年代的产物,受限于电传打字机接口和哑终端。两者都倾向于过时(http://www.mutt.org/)、不友好(https://jqlang.org/),并且相比图形界面功能受限。但这些倾向是 TUI 的固有属性,而非 CLI 的。CLI 有其不可替代的用途。构建 CLI 几乎总是一个好主意。构建 TUI 几乎从来不是。
早在 1999 年,尼尔·斯蒂芬森写了一篇关于命令行界面的文章,使整个人机交互领域倒退了大约 20 年。在文中,他将 Unix 极客们描绘成掌握 CLI 的强大莫洛克人,肩负着整个计算机行业的重担。伊洛伊人(https://en.wikipedia.org/wiki/Eloi)使用像 Microsoft Word 这样的 GUI。因为这是顶级的粉丝服务,“In The Beginning Was The Command Line”(最初是命令行)已经成为我们领域的神圣文本之一(https://hn.algolia.com/?q=in+the+beginning+was+the+command+line),尽管 25 年后它已站不住脚。
实际上,终端界面的存在并非因为它们能在计算机和操作者之间创造某种特殊的共鸣。相反,TUI 存在的原因只有两个:调制解调器,以及 Unix 极客们不想学习 Motif。
我不能怪他们。我 90 年代中期不得不做一点 Motif(https://seclists.org/bugtraq/1997/May/198)工作,这让我接下来 29 年都对 UI 开发敬而远之。Curses 库也不怎么样,但你能在 5 分钟内学会它。我没开玩笑:你今天不会选择用原始 curses 来做 TUI,但去问问 ChatGPT,让它简要概述(“别浪费时间解释概念”)编写 pico 编辑器所需的最低限度知识。拿它给你的代码(https://gist.github.com/tqbf/064b87a76ce000bcdd4b366ed141d9bc)编译;能用。很清楚该如何继续。它本身并不复杂。
代理可以可靠地构建一个合理的原生 macOS 界面,方法是按照 Apple 的要求使用 SwiftUI 框架。这是原生应用和 Web 界面之间的区别:同质性是件好事:原生应用就应该看起来像其他原生应用。
但 TUI 存在一个问题:即使有很好的框架,如 Ratatui(https://ratatui.rs/)、Textual(https://textual.textualize.io/)或 Bubbletea(https://github.com/charmbracelet/bubbletea),你也要与终端抗争,才能渐进接近每个原生框架开箱即有的功能。滚动和滚动定位是一个明显的例子。拖放是另一个。文本选择——当你使用带内信令绘制窗口边框时,事情就变得棘手了!多浮动窗口。在我们开始处理图像之前,这些都是问题。
你可以在 TUI 框架中花一个小时为许多标准控件构建一个不错的版本:日期选择器、安全文本字段、进度条、文本编辑器。但大多数都不会像系统提供的相同部件那么好,而且它们组合起来不会很好,需要更多工作。
所有这些东西在原生 UI 中都是开箱即用的。
你即将明确地告诉我,为什么到 2046 年我们都会使用和享受 TUI。请允许我预判一下你的几个论点。
TUI 是经济且快速的界面,信息密度高。极客们喜欢它们不仅仅因为复古美学。他们欣赏能用几次击键在几秒钟内完成复杂任务。
这些都是正确的陈述,但要说服你,我需要在段落开头加上“只有”这个词,而如果我那样做,我就在撒谎。图形界面通常不经济、不密集、也不是键盘优先的。但那通常是因为它们不是为极客设计的(即使在 Linux 上,图形界面也经常是面向理想化的普通 Linux 桌面用户设计的)。没什么能阻止你设计一个密集而经济的 GUI。已经有人做到了!(https://professional.bloomberg.com/products/bloomberg-terminal/#terminal-in-action)
对我来说,这些 TUI 的优点是强有力的理由,让我们去做更多图形工作,因为现在实验这些东西变得容易且廉价,我想看到原生 UI 被构建出来,捕捉 Magit 或 Lazygit 的所有优点(而不用我自己构建)。
其次:TUI 可以通过 SSH 连接工作。如果你需要在生产环境上有个用户界面,那它一定是 TUI。
这个论点的问题在于,你可能并不需要在生产环境上有个用户界面。你需要的是一个命令行界面在生产环境上,而你 Macbook 上的用户界面可以驱动它。任何用过 bpftrace(https://bpftrace.org/)的人应该都刻骨铭心地明白这一点,至少在他们第三次用井号画条形图时是这样。幸运的是,有先例可循:看看 Emacs TRAMP(https://www.eldelto.net/articles/emacs-tramp-is-awesome),它有效地隐藏了 SSH 连接,并为远程文件提供了原生(并且是图形化的,如果你喜欢的话)编辑器体验,甚至支持 LSPs(https://news.ycombinator.com/item?id=27822867)和 Magit。
人们会告诉你 TUI 有无障碍性。
这个论点的问题在于它可能不正确(https://www.osnews.com/story/144892/the-text-mode-lie-why-modern-tuis-are-a-nightmare-for-accessibility/)。我想谨慎对待这个论点,因为我不是无障碍功能的用户。我只能依据做无障碍工作的人的经验。就像这位演讲者(https://www.youtube.com/watch?v=jdF0TkZpMvk&t=991s)描述屏幕阅读器如何读取 TUI “界面”的所有逐行更新;`井号,井号,井号,井号,破折号,破折号`。听起来很糟糕!
现代原生 UI 框架从一开始就设计为能很好地支持无障碍性。SwiftUI 维护两棵 UI 树,一棵是视觉树,一棵是语义无障碍树。有一些 TUI 框架,令人钦佩地,试图做对这件事(https://github.com/charmbracelet/huh)。我不是来告诉你 TUI 不能具有无障碍性;而是说无障碍性不是选择 TUI 而不是 GUI 的理由。
最后,我能想到一个支持 TUI 的有力论点:它们是跨平台的。
我可以让代理为我在 Windows 和 Linux 上构建原生 UI,并且我相信最终会得到合理的东西。但我没有 Windows 和 Linux 桌面来测试这些界面,虽然形势确实在变化,但我认为我们都能同意,氛围编程和氛围发布之间仍然存在重要区别。很快就会有人发布一个他们根本没看过或用过的应用。但那个人不会是我。
同时,如果我构建一个 TUI,我可以合理地确定 Linux 用户会得到和我一样的体验。这并非没有意义。但记住:我并不是真的在为别人构建应用。我是在为自己构建。为了获得 Linux 用户(我甚至不想发布我的程序给他们)而接受 TUI 的功能限制,代价太大了。
几年前,这些论点会显得非常可笑。不是因为 TUI 好,而是因为原生 UI 不是一个合理的要求。作为证据,请观察我们花了近十年时间忍受 Electron 应用。那是因为原生 UI 很难做好。但现在不再是这样了,我们应该多做一些。
❦
我只能为 MacOS 开发说话,然后假设 Linux 中的 GTK 4 和 Windows 中的 WinUI 3 也同样容易。如果我引起了你的兴趣,我很高兴地说,构建一个像样的原生 MacOS 应用并不难。
我所做的是去搜寻技能,最终采用了这个 macOS 设计技能(https://github.com/ceorkm/macos-design-skill),一个基础的排版技能(你在 Github 上找到的任何一个都比我用的好),以及 Paul Hudson 的 SwiftUI 技能(https://github.com/twostraws/swiftui-agent-skill)。我还采用了 Airbnb 的 Swift 语言技能(https://swift.airbnb.tech/skill),因为我仍然在意我生成的代码是否符合惯用写法。
你需要确保启用了 `computer-use`,或者 Codex 对此的称呼。你需要能启动它,去做午饭,然后回来面对一个足以让你愉快调试的应用。当代理能看到并驱动应用时,效果要好得多。
我最大的生活质量提升是再也不用打开 Xcode 了。谢天谢地,我的朋友 Josh 构建了一个纯……
相似文章
@jakevin7: 发表个暴论,TUI 会逐渐式微甚至被淘汰。 我已经很久没有用 claude code 了。基本都是用 slock。 对于临时任务,现在用的更多的是 codex desktop,偶尔用 claude desktop。 让我开始重新思考 TU…
文章讨论了TUI(终端用户界面)在AI编程工具中逐渐式微的趋势,作者认为随着模型能力增强,TUI将被CLI+server架构或Web UI取代,并分享了从Claude Code转向Slock、Codex Desktop等工具的个人体验。
@PrajwalTomar_: 别再怪AI导致界面丑陋了。AI不是问题。你跳过了最关键的一步。每个发布AI应用的开发者……
认为丑陋的AI应用UI是由于缺少结构化的设计系统,而非AI本身。推荐使用Moonchild创建基于token的组件,让Codex能够读取以实现一致的界面。
忽视界面无法解决计算机使用问题
本文认为,当前的人工智能计算机使用代理通常通过直接访问API或编写脚本绕过实际用户界面,导致基准测试结果虚高,实际表现不可靠。文章指出,忽视界面是一种有缺陷的方法,无法泛化到杂乱的GUI环境中。
你是自己写代码,还是让AI代理来做?以及如何获得好的UI设计
探讨手动编写代码与使用AI代理之间的权衡,并提供关于如何实现良好UI设计的建议。
AI代理真的在杀死UI吗?(9分钟阅读)
这是一篇观点文章,认为AI代理并没有杀死UI,而是将产品转向混合界面:既需要面向代理的引导,也需要面向人类用户的控制,用于批准、审查和编排。