给 Linux 上的 AI 一套独立桌面

从本机 Computer Use 到 QEMU/KVM 隔离桌面的实践与验证

让 AI 替我操作电脑以后,我还能不能继续用这台电脑?

这次折腾 Linux Computer Use,最后绕不开的是这个问题。AI 能识别窗口、点击按钮、输入中文,当然有用。但如果每做一步都要切走我的窗口、移动我的鼠标,我就得停下手里的工作,看着它完成任务。

我最初给 Codex 的要求只是评估一个 GitHub 项目。后来,我们做了方案比较,在本机跑操作测试,再把 GUI 工作搬进独立虚拟机。到这篇文章写成时,核心需求已经得到验证。我把它看作一套可用的个人工作流,距离通用、免维护的 Linux 桌面自动化产品,还有不少事情要做。

先让它真正操作起来

起点是 agent-sh/computer-use-linux。它把 Linux 桌面能力做成 MCP server 和 CLI,AI 客户端可以通过它读取无障碍树、查看窗口,再执行键鼠操作。

这里的无障碍树值得解释一下。应用如果正确提供了 AT-SPI 接口,工具就能读到输入框、按钮和控件状态,按名称或元素索引定位。界面只提供图像时,仍然要依靠截图和坐标。不同软件提供的信息差别很大,安装成功远远不够,得拿真实控件试。

我的宿主系统是 Ubuntu 22.04.5、GNOME 42.9、X11。这些版本直接影响了后面的选择。项目以 Wayland 为主要方向,对 X11 的支持仍需结合实际环境判断。

我让 Codex 先找更流行、更合适的方案。Cua Driver进入了候选名单。它支持直接操作宿主机,也提供 MCP 接口,部分动作还可以在后台完成。Cua 仓库当时的关注度明显更高,不过那个数字覆盖整个 Cua 项目,不能当成 Linux Driver 的稳定性指标。

于是我们先试了 Cua Driver 0.24.0。

后台按钮、复选框和部分数值设置都能工作。文字输入却出现了两个具体问题。一次把“中文输入测试”输入成了“中文”;另一次指定了测试窗口,文字却落进同一进程的另一个输入窗口。

响应中虽然有 Typed 6 character(s) 这样的描述,effect 同时标成了 unverifiable。应用自己的状态文件给出了更直接的结果。这次试用没有通过关键输入验收,我们撤掉了它。

这是对这台机器、这个版本和这组测试的判断。它不足以推导出 Cua 在所有 Linux 环境下都不好用,也不能代替对后续版本的重新测试。

本机控制跑通以后,问题还剩一半

接下来回到 computer-use-linux 0.5.0。

它的官方预编译程序要求 GLIBC_2.39,本机是 2.35,直接运行会报错。我们在任务目录里使用已有 Rust 工具链编译,得到能在这台 Ubuntu 上运行的版本。宿主系统库没有因此升级。

测试又暴露出几个需要处理的地方。旧 GTK/ATK 在批量读取控件动作时会使目标应用崩溃,GNOME 上游有对应的修复记录。兼容版改成了逐项读取动作。X11 的滚动和拖动复用已安装的 xdotool,非 ASCII 输入加入了 12 ms 间隔,等待临时键盘映射生效。窗口 ID 与指定 PID 不一致时,工具会拒绝发送输入。

截图还给我们上了一课。旧版 X11 工具把窗口边框偏移重复计入位置,裁剪结果会带进旁边的内容。我们改用 xwininfo 读取真实客户区坐标。后来进入虚拟机测试时,又发现相对点击走了一条单独的旧路径,继续使用错误偏移。把这一条也接到同一套坐标换算后,截图与点击才对上。

这些都是本地兼容修改。它们让眼前的环境能用,也留下了后续升级时重新编译和验证的责任。

本机阶段最终通过了 20 项操作检查,覆盖中文连续输入、快捷键、控件操作和真实文件保存。控制器的 272 项单元检查也通过了。两组数字说的是不同事情,前一组检查真实应用行为,后一组检查程序逻辑,不能相加当成一个“全面可靠”的分数。

操作能完成以后,我提出了开头那个问题。AI 还在使用我的主桌面。它每次获得焦点,我就要让出正在使用的界面。

给它第二块显示器,或者放到 GNOME 的另一个工作区,都没有从根本上分开输入。鼠标、键盘和焦点仍属于同一套桌面会话。我需要给它一套独立的图形环境。

最终方案用了哪些项目

调研时,我们也看到了同一作者的 agent-workspace-linux。它的目标很贴切,使用隐藏的 Xvfb 桌面、自己的应用和浏览器,再提供预览与控制入口。

最终这套安装没有使用 agent-workspace-linux 的代码,也没有安装它。 它是调研对象。我们没有做过它与虚拟机方案的同场实测,因此也没有依据说它一定更好或更差。

我们选择了标准 QEMU/KVM 虚拟机,里面安装 Ubuntu 24.04 和 XFCE,再放入已经验证过的 computer-use-linux。新增的本地代码主要负责启动、等待桌面就绪,以及通过 SSH 接入 MCP。预览直接使用 TigerVNC。

各部分的来源与作用可以这样对应。

部分 实际使用的组件 负责的事情
桌面隔离 QEMU/KVM 运行另一套 Linux 系统
虚拟机桌面 Ubuntu 24.04、XFCE、X11 打开应用,管理窗口和输入焦点
GUI 操作 computer-use-linux 本机兼容版 读取控件、截图、执行键鼠动作
接入与预览 本次编写的 agent-desktop 启动脚本、SSH、TigerVNC 管理生命周期,把 MCP 接到虚拟机,并提供查看窗口

桌面控制和虚拟化都复用了现有项目。agent-desktop 是这次安装里的本地入口名称,与上游 agent-workspace-linux 是不同的东西。

宿主机保留了两个 MCP 入口。agent-desktop 操作虚拟机,原来的 computer-use-linux 操作真实主桌面。对应的 Skill 规定,能在独立应用实例里完成的 GUI 任务优先使用虚拟机。明确要求操作当前主桌面窗口时,才使用宿主机入口。虚拟机操作失败也不应该自动切到主桌面。

这条规则负责选择工具,实际的桌面分离由虚拟机承担。只在提示词里写一句“不要抢鼠标”,并不能改变键鼠事件最后送到哪里。

我怎样确认它没有打扰主桌面

虚拟机先分配了 4 GiB 内存和 2 个虚拟 CPU,磁盘上限 40 GiB,按需增长。安装完成时,系统增量磁盘实际约 1.2 GiB,基础镜像约 253 MiB。KVM 也经过实际创建虚拟机和运行状态检查。

独立 Linux 虚拟机中的 XFCE 桌面和文本编辑器

这张图来自实际预览窗口。里面是虚拟机的桌面,关闭预览以后,它仍然可以继续运行。

验证时,Codex 在虚拟机内打开专用 GTK 测试窗口,连续做了三轮完整中文输入,点击按钮并滚动列表。应用自己记录收到的文字、按钮计数和滚动位置。宿主机上的另一个观察程序只读取主窗口 ID 与鼠标 X/Y 坐标,不向主桌面发送输入。

最终记录有 193 次宿主机采样,窗口焦点和鼠标坐标都没有改变。虚拟机内的指针正常移动,三轮文字均完整写入,另一个测试窗口的输入框也保持为空。

采样时保持主鼠标和焦点不变,用来观察 Agent 有没有改动它们。这个约束只用于测试,平时可以照常操作主桌面。193 次是同一轮验证中的观察次数,不能解释成 193 个独立测试,更不能证明任意软件、任意时长都不会出问题。

生命周期也单独检查了。关闭 TigerVNC 预览以后,虚拟机 PID 未变,SSH 仍然可达。正常关机,再由 MCP 连接触发冷启动,桌面和无障碍服务恢复,之前写出的文件仍然存在。

预览默认只读,双向剪贴板同步也关闭了。我可以打开它看进度,也可以直接关掉,继续使用主桌面。需要亲自操作虚拟机时,再切到手动模式,并暂停同一个虚拟桌面里的 AI GUI 任务。

MCP 连接启动时会自动启动虚拟机,新任务加载这个工具也可能让它开机。关闭预览不会释放虚拟机占用的资源,不用时需要单独关机。

文件从哪里进,结果从哪里出

我们只共享了两个目录。

主机上的目录 虚拟机里看到的位置 权限
文档目录下的 AI-Desktop/Inbox /mnt/inbox 只读
文档目录下的 AI-Desktop/Outbox /mnt/outbox 可写

需要编辑的输入先复制到虚拟机自己的工作目录,完成后再输出到 Outbox。测试中,虚拟机可以读取 Inbox,尝试修改输入文件时被拒绝;它在 Outbox 写出的内容,也能从主机读到。

这个安排让文件交接很直观。我的现有窗口和浏览器登录状态仍留在主机上,虚拟机使用自己的应用实例和账号。它也没有直接挂载我的整个主目录。

这套本地安装提供了几个日常入口。

agent-desktop status   # 查看状态,不启动虚拟机
agent-desktop view     # 打开只读预览,必要时启动虚拟机
agent-desktop control  # 手动操作虚拟机
agent-desktop stop     # 保存工作以后,正常关闭虚拟机

这些命令来自本次编写的启动脚本,读者单独安装 QEMU 或 computer-use-linux 后不会自动获得它们。这篇记录介绍选型和验证经过,尚未整理成可以跨机器安装的发行包。

到这里解决到了哪一步

我现在可以让 AI 在独立桌面里执行经过验证的 GUI 操作,同时保留主桌面的使用权。对最初提出的并行工作需求,这已经是一个可以开始使用的结果。

我还没有把所有常用软件都验证一遍。WPS、Obsidian 等应用的具体控件,后续仍要按任务测试。虚拟机中的软件需要单独安装和登录;如果任务必须接着操作主机上那个已有窗口,仍然需要明确交接。

一套虚拟桌面也只有一套焦点。两个 AI 同时操作同一个窗口,仍可能互相干扰,目前需要安排好任务顺序。宿主机睡眠或关机以后,这台本地虚拟机同样不能继续执行。

维护也需要算进去。启动脚本带有本机路径,用户级 QEMU 运行时要单独管理更新,控制器还带着兼容补丁。目前没有长时间、多应用的可靠性记录,也没有把故障恢复做成一个通用产品。

接下来更有意义的工作,是拿它做几次真实任务,记录应用、失败位置和恢复办法。网页已经能用浏览器工具完成的,继续走浏览器工具;文件和代码处理仍然优先使用命令或 API。独立桌面留给那些确实需要界面的工作。

标签: Linux Computer Use KVM