每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/

"它是文本的,所以它是可访问的"这一神话
在有视力的开发者中,存在一种根深蒂固的误解:只要应用运行在终端中,它就天然是可访问的。这种逻辑认为,由于没有图形界面、没有复杂的 DOM,也没有 WebGL 画布,内容不过是原始的 ASCII 文本,因此屏幕阅读器可以轻松解析。
现实却完全不同。大多数现代文本用户界面(TUI)往往比设计糟糕的图形界面更不友好。那些本应提升开发者体验(DX)的终端工具------例如 Ink(JS/React)、Bubble Tea(Go)或 tcell------实际上正在破坏盲人用户的使用体验。
架构缺陷:流 vs 网格
要理解这一失败,我们必须区分两种常被混淆的概念:"终端应用"中的 CLI 和 TUI。
CLI(流):基于标准输入/输出(stdin/stdout),用户输入命令,系统将结果按顺序追加在下方,光标持续向下移动。这种线性、按时间排列的结构,对于屏幕阅读器(尤其是内核级阅读器如 Speakup)来说是理想的。
TUI(网格):将终端窗口视为一个二维字符网格,每个字符单元就像一个像素。它放弃了时间顺序,转而使用空间布局。
案例研究:gemini-cli 的混乱
以一个具体例子来看:gemini-cli,这是一个基于 Node.js 并使用 Ink 框架开发的工具。表面上它看起来像一个简单的聊天界面,但实际上,Ink 正在尝试将 React 组件树渲染到终端网格中。
当你使用 Speakup(Linux)或 NVDA(Windows)时,这个应用不仅无法正常工作,甚至会"骚扰"用户。
由于框架将屏幕视为一个响应式画布,每次更新都会触发重绘。当 AI 在"思考"时,工具会更新计时器或加载动画。为此,它不断移动硬件光标到计时器位置,写入新时间,然后再移回。
对于有视力的用户,这几乎是瞬间完成的。但对于屏幕阅读器用户,你听到的却是:
"正在响应......已用时1秒......正在响应......已用时2秒......[聊天记录片段]......正在响应......"
这种体验会让屏幕阅读器"发疯"。光标在屏幕各处跳跃,阅读器试图读取当前光标所在位置的内容,结果就是你听到的是杂乱的对话片段与计时信息混合,根本无法专注于输入内容。
更糟糕的是,如果你尝试在不同环境之间切换,例如使用 NVDA 粘贴错误信息到远程终端,结果往往是屏幕阅读器崩溃或系统严重不稳定。
原因在于,每次输入或粘贴都会触发状态变化,框架会重新渲染界面。由于聊天历史是状态的一部分,应用会尝试即时重绘数千行内容。对话越长,问题越严重。而且,即便使用抑制动态内容朗读的快捷键,也无法避免。
延迟循环
此外,像 Ink 这样的单线程框架在处理大量历史记录时性能会严重下降。如果粘贴大段文本,系统需要计算成千上万行的差异。
这会导致输入延迟:按下一个键,可能需要等待数秒才显示。系统忙于重绘界面,而无法及时处理输入。
为什么"老工具"反而有效(nano、vim、menuconfig)
有视力的开发者常问:"如果 TUI 不好用,那为什么你们还使用 nano、vim 或 menuconfig?"
答案并不是这些工具默认处理光标更好,而是它们允许隐藏光标。
- 隐藏光标(nano、vim)
在这些工具中,如果启用显示光标位置等功能,体验同样会变差。当光标更新被优先处理时,屏幕阅读器会读出"列2""列3",而不是用户输入的字符。
这些工具之所以可用,是因为它们允许关闭这些视觉噪音,使阅读器依赖输入流,而不是光标位置。现代框架通常不提供"无光标"或"无头模式",默认假设视觉光标是必要的。
- 单列焦点(menuconfig)
像 Linux 内核的 menuconfig 之所以有效,是因为它强制单列布局。光标始终停留在列表中,不会跳到其他区域更新状态信息,从而避免空间复杂性带来的混乱。
- 滚动区域的艺术(Irssi)
Irssi 是可访问聊天工具的典范。它利用 VT100 滚动区域:
定义滚动区域;
向终端发送滚动指令;
仅在底部绘制新文本。
关键在于,它利用终端硬件能力,而不是重新绘制整个屏幕。相比之下,现代框架通过"差异计算"重写字符,既耗性能,又破坏可访问性。
"僵尸问题"的借口:忽视的案例
一些项目表面上声称重视可访问性,但实际上却忽视问题。例如 gemini-cli 的关键可访问性问题长期未被处理,甚至被自动关闭。
关闭这些问题并不是"清理",而是掩盖问题,使软件对盲人用户不可用却看似"健康"。
结论
如果你正在为终端开发应用并关心可访问性,请停止使用将终端视为画布的声明式 UI 框架。
现代 TUI 技术栈优化的是开发者写代码的体验,却牺牲了机器高效渲染文本的能力。
如果你的应用无法让用户隐藏光标,或者依赖频繁重绘来显示动画与状态,那么它就是不可访问的。
对于盲人用户而言,一个简单、线性的 CLI 流,远胜于一个"智能"但充满延迟、噪音和混乱光标的 TUI。