给 AI Agent 一台云主机:基于 noVNC 的云桌面架构与最小实现

AI Agent 真正跨过"会回答"到"会办事"的那一步,往往不是再加一个提示词,而是给它一台可以持续运行、可以看见、也可以随时接管的电脑。

很多 Agent Demo 能打开网页、点击按钮,但一进入真实业务就会遇到新的边界:任务可能跨越浏览器、终端、文件管理器和桌面应用;登录状态需要保留;执行过程需要让人看见;关键操作还必须由人确认。

这时,一个"Agent 云主机"就有了意义。

什么是 Agent 云主机

可以把它理解成一台专门交给 AI 使用的远程电脑:

  • 云端运行 Linux 桌面、Chrome、终端和业务应用;
  • Agent 通过截图或结构化状态观察桌面;
  • Agent 发送鼠标、键盘或命令行操作;
  • 用户通过浏览器实时查看,并在必要时接管;
  • 系统保存任务状态、操作记录和产物。

它不是"在服务器上跑一个大模型"这么简单,而是把模型、执行环境、远程桌面和会话生命周期组合成一个可控系统。

不过先说一个重要边界:如果任务只发生在网页里,并且 DOM 稳定,优先使用 Playwright 一类浏览器自动化。云桌面更适合必须操作桌面应用、保留完整系统环境、连续运行很久,或者需要人工接管的任务。

整体架构

最小架构可以画成这样:

text 复制代码
                  用户
                   │
             Web 控制台
                   │
                noVNC
                   │ WebSocket
              websockify
                   │ TCP
              VNC Server
                   │
        Linux Desktop / Chrome / App
                   ▲
                   │ 截图 + 鼠标键盘事件
             Agent Runtime
                   │
             LLM / Tools

这里有两个方向的数据流:

  1. 桌面画面从 VNC Server 传到 noVNC,最终绘制在浏览器 Canvas 中;
  2. 用户或 Agent 的鼠标、键盘事件反向发送到云端桌面。

noVNC 在里面负责什么

noVNC 是浏览器端的 VNC 客户端,不负责创建桌面,也不是 Agent 本身。它主要做四件事:

  1. 通过 WebSocket 接收远程桌面数据;
  2. 解析 RFB/VNC 协议;
  3. 将桌面内容绘制到 Canvas;
  4. 将鼠标和键盘事件传回 VNC Server。

浏览器不能直接连接传统 VNC 的 TCP 端口,所以通常还需要 websockify 做一层桥接:

text 复制代码
浏览器 ── WebSocket ──> websockify ── TCP ──> VNC Server

这套链路解决的是"人如何在网页里看到并控制远程桌面"。至于 Agent 如何思考、何时点击、任务如何恢复,需要由上层运行时负责。

Agent 的控制循环

一个最小 Agent 不需要复杂框架,核心就是"观察---决策---执行---校验"循环:

python 复制代码
async def run_task(session, goal):
    while not session.finished:
        frame = await session.desktop.screenshot()
        context = await session.recent_events()

        action = await model.plan(
            goal=goal,
            screenshot=frame,
            context=context,
        )

        if action.requires_confirmation:
            await session.pause_for_user(action)
            continue

        await session.desktop.execute(action)
        await session.record(action)

        if await session.is_goal_reached():
            session.finished = True

动作协议也可以保持简单:

json 复制代码
{
  "type": "click",
  "x": 816,
  "y": 492,
  "reason": "打开搜索结果"
}

常见动作只需要覆盖:

  • click(x, y)
  • type(text)
  • key(name)
  • scroll(delta)
  • wait(ms)
  • shell(command)
  • finish(result)

真正重要的不是动作种类多,而是每次执行后重新观察,确认界面是否真的发生了预期变化。

会话管理:让任务可以持续运行

云主机与一次性脚本最大的区别,是它有会话生命周期。最少需要下面几个状态:

text 复制代码
CREATING → READY → RUNNING → PAUSED → FINISHED
                         └──────→ FAILED

一个会话通常包含:

python 复制代码
class AgentSession:
    id: str
    goal: str
    status: str
    desktop_id: str
    owner: str
    created_at: datetime
    last_active_at: datetime
    result: dict | None

创建任务时,系统启动隔离环境和桌面服务;运行中持续写入事件;完成后保存产物;空闲超时则回收机器。这样 Agent 才能离开用户电脑继续工作,又不会让云资源无限占用。

必须设计"人工接管"

Agent 操作桌面时,人和 Agent 不能同时争夺鼠标。最简单的做法是维护一个控制权状态:

text 复制代码
controller = agent | human

用户点击"接管"后:

  1. 暂停 Agent 循环;
  2. 等待当前动作结束;
  3. 将输入控制权切换给用户;
  4. 用户完成登录、验证码或关键确认;
  5. 再把控制权交还给 Agent。

这比让 Agent 处理所有环节更可靠。验证码、支付、发送消息、删除数据等高风险动作,本来就应该停下来由人确认。

最小可用版本怎么做

如果只是验证方案,不需要一开始就做调度平台、容器编排或多 Agent 系统。一个能工作的 MVP 只需要:

  1. 一台 Linux 云主机;
  2. 一个轻量桌面环境和 VNC Server;
  3. noVNC + websockify;
  4. 一个创建/停止会话的 HTTP API;
  5. 一个 Agent 进程,负责截图、规划和输入;
  6. 一个浏览器控制台,用于观看、暂停和接管。

伪代码如下:

python 复制代码
class AgentHost:
    async def create_session(self, goal):
        desktop = await start_desktop()
        vnc = await start_vnc(desktop)
        proxy = await start_websockify(vnc.port)

        session = AgentSession(
            goal=goal,
            status="READY",
            desktop_id=desktop.id,
        )

        asyncio.create_task(run_task(session, goal))
        return {
            "session_id": session.id,
            "viewer_url": proxy.viewer_url,
        }

第一版甚至可以固定一台机器、一次只运行一个任务。等真实任务证明并发、恢复和成本控制确实是问题,再引入容器池、队列和自动扩缩容。

生产环境最容易踩的坑

1. 只看截图,成本和延迟都很高

截图适合通用桌面,但每一步都把整张图交给模型会很慢。浏览器任务最好同时提供 DOM、可访问性树或应用内部状态,让 Agent 优先使用结构化信息,截图负责兜底。

2. 坐标会漂移

窗口大小、缩放、弹窗和网络延迟都会让固定坐标失效。每次动作后都要重新观察;能按元素定位时,不要只记坐标。

3. 会话隔离不足

不同用户的 Cookie、下载文件和剪贴板不能混用。至少要做到独立工作目录、独立浏览器配置、独立凭证注入和任务结束清理。

4. 凭证进入模型上下文

密码、Token 和 Cookie 不应该出现在提示词或日志里。更安全的方式是由宿主系统短暂注入,Agent 只获得"已完成登录"或"凭证可用"的结果。

5. 缺少可审计记录

只保存最终截图不够。建议记录动作、时间、页面地址、关键截图、执行结果和人工确认点,这些信息既用于排错,也用于责任边界。

云桌面与浏览器自动化如何选择

可以用一个很简单的判断:

  • 只操作网页、追求稳定和速度:浏览器自动化;
  • 需要桌面应用、系统环境或人工接管:Agent 云主机;
  • 两者都有:结构化工具优先,云桌面兜底。

最实用的系统通常不是"纯视觉 Agent",而是把浏览器 API、命令行和桌面控制放在同一个运行时里。模型选择成本最低、成功率最高的工具,只有没有结构化接口时才去"看屏幕、点鼠标"。

结语

Agent 云主机的核心并不神秘:一台隔离的远程电脑、一条可视化控制链路、一个持续运行的 Agent 循环,再加上人工接管和审计。

noVNC 很适合承担"看见并控制桌面"这一层,但它只是基础设施的一部分。真正决定系统能否落地的,是会话生命周期、工具选择、失败恢复、安全边界,以及关键动作前能不能稳稳地停下来等人确认。

如果从零开始,我会先做一个单机、单会话的版本,让 Agent 完成一条真实任务链路。跑通之后,再谈并发、调度和规模化。

相关推荐
XM_jhxx1 小时前
机械图纸质检标注的自动化趋势:AI识图如何重塑气泡标注与报表编制流程
人工智能
AI深栈1 小时前
第 12 章 · AI智能体的结构化输出与流式响应
java·人工智能
西索斯coding1 小时前
GPT-5.6-Luna 接入 Cline 教程:base_url 配置、max_tokens 上限与 ZDR 请求头写法
大数据·人工智能·gpt·ai
KKKlucifer1 小时前
跨中台安全业务编排:融合4A平台原子化安全能力的创新实践
运维·人工智能·安全·自动化
qq_199886871 小时前
第5板块·第4节:性能优化中的高级技巧
c++·人工智能·gpu算力
墨_浅-1 小时前
20260917金融科技动向:2027年新春家年华策略
人工智能·科技·金融
正经教主1 小时前
【FDE系列】阶段1Day 19:七阶段行动路径 + 行业经验的价值
人工智能·fde
晨航1 小时前
首尾帧、参考图、参考视频:想控制 AI 视频,到底该给它什么素材?
人工智能·aigc·音视频