
我记得第一次把 WorkBuddy 容器版跑起来的时候心里其实有点复杂一方面桌面 Agent 这种东西终于不用再窝在 Windows 里能像微服务一样被拉起来、调度脑子里的确兴奋另一方面又忍不住琢磨这玩意儿和一堆 RPA 工具到底是不是同一赛道凭什么值得我折腾大半天去做容器化迁移。后来用熟了 Crayfish 的视觉模块把一套原来要写两百多行坐标逻辑的自动化流程换成自然语言描述加视觉锚点定位我才慢慢想明白RPA 解决的是“按剧本演戏”而桌面 Agent 解决的其实是“看懂桌面再演戏”。这篇我不打算堆概念直接从 Crayfish、WorkBuddy 容器版、桌面 Agent 和容器运行时这几个词出发把架构逻辑、部署过程、和 RPA 的真实差异都摊开说清楚。适合正在做 RPA 迁移、想搞桌面自动化、或者单纯对 Agent 落地感兴趣的开发者读完能有大致的选型判断和一套可复现的玩法。1. 桌面 Agent、容器运行时与 RPA 的底层差异1.1 RPA 的工作模式录制、编排、按脚本执行RPA 的核心思路很多已经接触过像影刀这类工具本质上是把人的重复操作拆成“步骤”打开网页、填表单、点按钮、读取表格每一步对应一个组件组件之间有明确的流转顺序。这套模式的优点是稳定、可控、好审计。只要页面结构不变流程可以跑几百次不出错。缺点也很突出只要是“脚本写死了”的流程页面一改、弹窗一多、验证码一换整个链路就可能挂掉。更麻烦的是遇到没有固定规则、需要临场判断的场景RPA 基本无法处理因为它压根没有“理解”桌面上发生了什么只是在机械执行按键和取色。所以 RPA 更适合流程极其规范、变动极小、规则明确的场景比如批量录入、报表下载、Excel 处理这类操作。在这里它像一个极其听话但不懂变通的实习生你告诉它每一步它就能精确执行但你让它自己想办法它就懵了。1.2 桌面 Agent 的进化能看、能理解、能自我决策桌面 Agent 的思路则完全不同。它不再依赖“录下来回放”的逻辑而是把 LLM 作为决策核心把屏幕里的东西转化成模型能理解的信息再根据用户的目标描述自己规划执行步骤。这里面最关键的组件就是“视觉理解层”也就是 Crayfish 这类模块。它负责把截图、控件树、OCR 文本变成结构化的语义表示让 Agent 知道“当前屏幕上有一个登录按钮”“右上角弹出了一个错误提示”“表格第三列数据格式不对”。举个例子同样做一个电商订单导出RPA 的逻辑是“点击左侧菜单栏第 3 个按钮等待 5 秒点击导出等待文件下载完成”。桌面 Agent 的逻辑则是“帮我把今天的订单导出成 Excel”然后它自己去看菜单结构、找导出按钮、处理弹窗中途遇到意外情况还能随机应变比如“提示登录过期就重新调用登录流程再继续”。这是根本性的差异RPA 是复读机Agent 是实习生能听指令但没有全局视野而现在的桌面 Agent 更像是“有经验的实习生”——不仅听指令还知道哪里找工具、怎么随机应变。1.3 容器运行时为什么对 Agent 重要桌面 Agent 有个天然痛点环境依赖太多。Python 版本、UI 自动化库、屏幕分辨率、权限模型、各种 DLL稍有动静就起不来。如果只做单机工具还好一旦想要批量部署到多台机器或者给别人交付一套可复用的环境就麻烦了。容器运行时恰好在解决这个问题。把 WorkBuddy 和 Crayfish 相关的模型包、依赖库、运行配置全部打进镜像里推到目标机器上直接用环境一致性就保住了。更进一步可以把 Agent 放到隔离沙箱里跑不让它在生产系统上裸奔这比直接在宿主机装一个什么都能干、什么权限都有的 Agent 要安全得多。我最早尝试把 Agent 部署到 Docker 时最大的顾虑是“容器没有图形界面桌面 Agent 怎么操作桌面”这个问题的答案分两层要么通过 x11 转发 / VNC 暴露虚拟桌面要么把 Agent 设计成“无头模式”只做后台识别和任务调度把操作结果同步到宿主桌面。WorkBuddy 的容器版两种方式都支持这也是我最终决定把它作为主力方案的原因之一。一句话总结RPA 是把人工操作“录”成脚本执行桌面 Agent 是让机器“看懂”屏幕后自己规划执行容器运行时则让后者有了标准化交付、隔离运行和批量调度的可能。2. 老实说Crayfish 在 WorkBuddy 里到底是干嘛的2.1 被忽视的视觉模块屏幕感知层很多人第一次接触 WorkBuddy注意力都在怎么和 Agent 对话、怎么编排技能上往往忽略了一个基础事实没有 CrayfishAgent 就是个睁眼瞎。Crayfish 在我理解里就是 WorkBuddy 容器版的“视觉感知模块”负责把桌面内容变成模型可消费的数据。它至少要处理三类信息一是屏幕截图通过 OCR 抽取出界面上所有可见文本二是 UI 控件树拿到按钮、输入框、列表等控件的位置和属性三是视觉特征匹配也就是用截图找到特定图标、特定区域在屏幕上的坐标。这三件事分开看不稀奇RPA 工具也都做。但 RPA 里这些东西是“死”的取坐标就定坐标识别出文本也就是个变量。而 Crayfish 的意义在于把识别结果喂给 WorkBuddy 的模型上下文让 Agent 动态理解界面状态。比如弹窗出现时Crayfish 不只是检测到“有一个窗口”而是能识别出“这是一个文件覆盖确认框有两个选项替换和跳过”然后由模型决定接下来点哪个。2.2 为什么视觉理解比坐标定位更抗折腾有过 RPA 实战经验的朋友应该都懂那种被坐标支配的恐惧昨天还好好的脚本今天因为浏览器缩放比例变了所有按钮都偏移了几十个像素流程挂掉。排查半天发现只是分辨率变了那种感觉真的很崩溃。Crayfish 这种视觉驱动的方案解决的就是这个问题。它不依赖固定坐标而是依赖视觉语义识别。按钮位置变了但只要视觉上还是“那个蓝色按钮”模型就能找到它。哪怕整个页面的布局重新洗牌只要按钮还在Agent 还是能完成操作。当然也不是说视觉方案万能。它的问题是识别有延迟需要调用模型推理比直接读坐标慢了个数量级而且如果界面长得特别复杂、控件堆叠严重视觉模型也会有眼花的时候。所以在 WorkBuddy 的设计里Crayfish 识别结果会和控制树信息做交叉校验能拿到原生控件信息就优先用控件信息拿不到才走纯视觉定位。这个混合策略是我觉得比较聪明的做法。2.3 Crayfish 和 WorkBuddy Skill 的关系WorkBuddy 有一个很重要的设计是 Skill类似给 Agent 装插件或工具箱。每个 Skill 定义了一类能力比如“操作 Excel”“发送邮件”“抓取网页数据”等Agent 可以根据任务目标自行决定调用哪个 Skill、怎么组合调用。Crayfish 在这里扮演的角色是“感知层共用底座”所有 Skill 需要看屏幕的时候都会调 Crayfish 的接口。比如一个表单填写的 Skill需要先让 Crayfish 找到某个输入框在屏幕上的位置然后把焦点移过去填入内容。又比如一个自动化测试的 Skill每执行一步都要调用 Crayfish 做截图对比确保操作没有偏离预期。用大白话说Crayfish 像是给 Agent 配了一双眼睛而 WorkBuddy 本体是大脑Skill 是手和工具。三者配合才是完整的桌面 Agent 体验。少了任何一块另两块的用处都大幅打折。3. WorkBuddy 容器版部署实录从拉镜像到跑通桌面任务3.1 容器版整体架构与前置准备WorkBuddy 容器版不是简单把一个 Python 程序塞进 Docker而是有一套完整的运行时结构。我梳理下来大致包括四层交互层CLI / API / WebSocket、调度层任务规划、Skill 调度、会话管理、感知层Crayfish 视觉模块和执行层桌面操作、文件系统访问、浏览器控制。在动手部署之前有几个前置条件需要确认。机器最好是 LinuxUbuntu 22.04 亲测最稳内存至少 8G推荐 16G。如果要跑本地视觉模型建议独显或 Apple Silicon纯 CPU 虽然能跑但识别速度会比较感人比如一次截图识别要等十几秒业务上难以接受。另外容器版跑桌面任务有两种方式一种是给容器配置 X11 转发或 VNC 服务让 Agent 在虚拟桌面里操作一套与宿主机隔离的图形环境这种方式适合跑不受控的外部应用另一种是直接共享宿主机的 X11 Socket让 Agent 直接操作宿主机桌面上的软件这种方式更贴近真实场景但安全边界要自己想清楚。3.2 一步一步先定义镜像构建文件下面是一个参考用的 Dockerfile我实际跑通过注释写清楚了每个阶段在干什么。你可以根据自己的需求调整基础镜像和工作目录。FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04 ENV DEBIAN_FRONTENDnoninteractive \ LANGC.UTF-8 \ LC_ALLC.UTF-8 # 系统基础依赖Python、图形库、输入法、中文字体 RUN apt-get update apt-get install -y --no-install-recommends \ python3.10 python3-pip python3-dev \ libgl1 libglib2.0-0 libsm6 libxext6 libxrender-dev \ xvfb x11vnc fluxbox \ fonts-noto-cjk unzip curl wget \ rm -rf /var/lib/apt/lists/* # WorkBuddy 运行目录 WORKDIR /opt/workbuddy # 先拷贝依赖声明利用 Docker 缓存加速后续构建 COPY requirements.txt . RUN pip3 install --no-cache-dir -r requirements.txt # 拷贝核心程序与模型配置 COPY . . # 入口脚本负责初始化容器环境并启动 Agent 服务 CMD [bash, entrypoint.sh]这个文件里有几个点值得展开。xvfb和x11vnc是给容器提供虚拟桌面用的xvfb在内存里跑一个无头的 X Serverx11vnc把这个虚拟桌面通过 VNC 协议暴露出来这样即使容器在远端服务器上也能开个 VNC 客户端看到 Agent 在操作什么。fluxbox是一个轻量窗口管理器用来保持虚拟桌面上有基本窗口管理能力不然弹出的窗口可能会没有边框、无法拖动。fonts-noto-cjk是必须装的否则 OCR 识别中文界面大概率会乱码这一点等遇到问题再回头装就晚了。3.3 构建镜像并启动容器依赖文件准备好了之后构建镜像这一步就不复杂了。在项目根目录执行docker build -t workbuddy-agent:0.1.0 .构建过程如果网络状况一般会因为拉取 CUDA 基础镜像而比较煎熬建议配置好镜像源。构建成功之后启动容器要注意几个参数docker run -d \ --name workbuddy \ -p 8080:8080 \ -e DISPLAY:99 \ -e WORKBUDDY_MODEcontainer \ -v /host/task-data:/data \ --shm-size2g \ workbuddy-agent:0.1.0这里重点说明两个参数。--shm-size2g容易被忽略但很重要容器默认的 /dev/shm 只有 64M而 Chrome、桌面截图、模型临时缓存都有可能往共享内存里写东西空间不够就会触发莫名其妙的内存崩溃所以务必显式调大。-v /host/task-data:/data是把宿主机的任务数据目录挂载进去让 Agent 能读取到待处理的文件也方便把处理结果输出到宿主机。如果是想直接操作宿主机桌面需要额外加上 X11 socket 映射。在宿主机先执行xhost local:放行本地连接然后容器启动时加两个参数-v /tmp/.X11-unix:/tmp/.X11-unix \ -e DISPLAYunix$DISPLAY注意这种模式下容器里的 Agent 拥有了宿主机桌面应用的直接控制权操作任何应用之前要想清楚权限边界。我并不建议在信任边界不明的机器上这么干。3.4 验证部署跑通第一段桌面交互容器启动后先看日志确认服务正常docker logs -f workbuddy看到类似“API server listening on 0.0.0.0:8080”的输出说明服务已经起来了。接下来可以做一个最简单的冒烟测试调用 Agent 的接口让它执行“打开桌面上的计算器计算 123 乘以 456输出结果”。用curl的方式大概长这样实际字段名以你的 API 定义为准curl -X POST http://localhost:8080/api/task \ -H Content-Type: application/json \ -d {goal: 打开计算器计算 123 乘以 456然后返回结果}如果走的是虚拟桌面模式你会从 VNC 画面里看到 Agent 一步步操作。这个过程第一次看会有点震撼但也会让你更直观地理解为什么说“Agent 能理解任务目标”这件事和 RPA 脚本有本质差别。整个部署过程如果在网络顺畅、镜像源配置好的前提下大约 20 分钟能完成如果不顺利卡在依赖安装上的话一下午也不是没有可能。4. 相对 RPA 的真实优势从脚本执行到任务理解4.1 用自然语言描述需求而不是写死每一步我见过很多 RPA 项目最花时间的不是执行而是“说服脚本认识页面”。一个简单到“把系统 A 的数据搬到系统 B”的需求转化为 RPA 脚本可能要写几十个组件每个组件都要设计异常分支碰到“系统 B 弹了一个不认识的提示框”脚本就只能干瞪眼。桌面 Agent 的体验完全不同。只需要用一句话描述目标比如“从邮件里找到今天的销售日报附件下载下来提取里面的销售额填写到内部系统的报表页”Agent 自己会拆解步骤先看邮件列表找到主题含“销售日报”的最新邮件下载附件用 Excel Skill 读取数据再打开内部系统定位报表输入区域填入数据。这个过程并不总是完美——模型可能会走弯路也可能误判。但它的价值在于“动态调整”。RPA 脚本写完了就固定了而 Agent 会在执行中持续观察结果发现步骤不对会尝试修正。这种容错能力恰恰是处理真实业务场景最需要的。4.2 抗界面变更能力强维护成本大幅下降做过 RPA 维护的都懂脚本上线只是开始真正的考验在第一个月。前端页面改版、按钮文字调整、新增了一个弹窗提示每一个小改动都可能让脚本失效需要人工重新录制或修改组件参数。用 WorkBuddy 这类 Agent 方案维护重点从“改脚本”变成了“检查模型是否理解了新页面”。因为 Crayfish 的视觉层是语义理解而不是坐标记忆页面样式变化通常不影响识别。比如一个按钮从“确认”改成了“好的”对 RPA 是灾难因为文本匹配规则失配了对 Agent 影响就小一些模型能根据上下文推断“好的”可能就是原来的“确认”按钮。这不代表 Agent 不需要维护。模型的误判、任务规划的偏差、Skill 调用错误都是需要人工 review 的点。但对比下来维护频率和工作量确实比传统 RPA 低尤其在系统变更频繁的业务线里这个优势会越来越明显。4.3 上下文感知和异常处理能力RPA 的异常处理靠的是“预设分支”写的时候就要预料到可能出现的各种情况然后逐个添加处理逻辑。可惜真实世界的问题往往超出预设范围比如系统突然卡死、网络延迟导致页面加载到一半、某个数据格式和预期不同等。Agent 的方式是“用模型理解异常”。Crayfish 把异常界面截图给模型模型会说“这看起来是系统繁忙页面等待 10 秒再重试”“这是一个数据校验错误提示问题在于日期格式不对需要修正后重新提交”。这种判断能力在 RPA 里几乎不可能实现因为它要的是语义理解而不是简单的条件判断。当然模型误判的风险也要正视。Agent 可能在面对复杂异常时给出错误的处理决策造成连锁反应。所以 WorkBuddy 这类系统在设计时需要支持“人工确认”模式在关键步骤卡住让用户确认后再继续。在自动化程度上做取舍而不是一味追求全自动。4.4 应用场景对比选型参考从实际项目选型的角度我把 RPA 和桌面 Agent 的适用场景做了个粗略的对比可以参考维度传统 RPA如影刀桌面 AgentWorkBuddy 容器版流程明确度要求极高必须提前定义所有分支中等目标明确即可路径可动态生成界面稳定性敏感度高界面一变脚本就容易挂较低视觉语义识别抗变更能力强异常处理依赖预设条件分支超出预期就失败依赖模型推理可应对未预见的简单异常开发门槛低拖拽组件 简单逻辑中高需要理解 Prompt、Skill、视觉模型部署形态通常为 Windows 客户端或 Server 端容器化可批量部署、环境一致性好运行成本主要是授权和虚拟桌面机器成本模型推理需要 GPU算力成本较高安全可控性脚本逻辑清晰审计直观模型决策有不确定性需要人工 review 关键节点这不是说 Agent 全面优于 RPA。如果你的业务场景是极度标准化的、流程几十年不变的RPA 的稳定性和低成本仍然是最优解。但如果你面对的是流程经常变、需求描述比较模糊、系统迭代快的场景桌面 Agent 的灵活性和适应性会明显胜出。5. 常见问题与排查技巧实录5.1 启动慢到怀疑人生很多人在 WorkBuddy 容器版刚启动时都会遇到一个问题容器起来了但接口迟迟没有响应日志半天不输出仿佛卡死了。我第一次遇到也以为是构建出问题了。后来排查发现启动慢的常见原因有三个。第一是首次启动需要加载模型文件如果模型有几 GB从磁盘读进内存确实需要时间这个只能等。第二是 OCR 语言包初始化比较慢尤其装了多种语言包的时候启动时会逐项扫描加载。第三是容器共享内存太小导致某些组件初始化时频繁 GC内存一紧就表现成整体卡顿。第一种情况没有太好的办法只能提前做模型预加载第二种可以删掉不需要的语言包只保留中文和英文第三种就是前面说的务必设置--shm-size2g以上。如果启动时间持续超过 3 分钟还没任何响应先看 CPU 和内存占用再决定是等待还是重启。我自己的经验是第一次启动慢很正常后续如果每次启动都慢才需要去查日志。5.2 Crayfish 识别不准怎么办视觉识别不准是桌面 Agent 落地过程中最头疼的问题之一。常见症状有明明界面上有某个按钮Agent 说找不到某个按钮的位置识别对了但点击的事件没触发两个相似图标的区分度低识别结果总是在两个之间横跳。这类问题的排查思路是“从环境到模型逐层筛选”。先检查截图质量虚拟桌面分辨率太低的字体渲染发虚的识别肯定受影响再检查颜色空间和缩放比例有些界面在高 DPI 下渲染逻辑不同Crayfish 拿到的是 DPI 缩放后的截图视觉特征可能变化最后才是检查模型选择可以试用不同参数的模型在延迟和准确率之间找到平衡点。有一个比较实用的小技巧部署时把 Crayfish 的原始识别输出开启 debug记录每次识别到的元素框、置信度和 OCR 文本。这样定位问题时会直观很多不用靠猜。5.3 容器里跑不了图形界面程序如果你走的虚拟桌面方案在里面启动 GUI 应用时发现起不来大概率是缺了几个关键的图形库。常见的报错是libGL.so.1: cannot open shared object file或者libXkbCommon.so找不到解决方法是把libgl1、libglib2.0-0、libxkbcommon-x11-0这些库装全。另一种情况是应用需要 GPU 加速渲染而容器里没有配置 GPU 直通导致进程直接崩溃或者渲染成黑屏。这个问题相对麻烦要么配好 Docker 的 GPU 运行时参数要么在应用层面强制使用软件渲染。对大多数桌面自动化场景来说软件渲染够用了性能影响主要体现在视觉效果上对操作逻辑影响不大。5.4 宿主机桌面控制没有响应共享宿主机 X11 的方式如果没反应先确认宿主机是否放行了 X 连接也就是之前提到的xhost local:是否执行了。其次确认容器里的 DISPLAY 环境变量是否和宿主机一致。很多人在这一步踩坑容器里写的 DISPLAY 是宿主机当前的显示编号结果对不上X 客户端根本找不到 Server。如果你用的办法是 SSH 到宿主机再进容器还要注意 SSH 会话可能带了独立的 X11 forwarding跟本地桌面的 display 编号不同容器继承的是 SSH 会话的环境变量自然连不上本地桌面。这类问题排查的关键是统一环境变量最好在启动容器时显式指定 DISPLAY不要依赖继承。实际经验是如果宿主机有物理显示器在跑共享 X11 的方案稳定且高效如果是纯远程无头服务器还是建议用 VNC 虚拟桌面方案省去大量环境层面的麻烦。6. 落地建议与个人使用体会6.1 什么时候值得引入 WorkBuddy 容器版结合我这段时间的折腾我觉得有这样几个信号出现时可以考虑引入桌面 Agent 方案。第一现有的 RPA 维护成本已经超过了开发成本说明脚本和业务变化之间的摩擦力太大脚本化的路子走到头了第二流程描述很难做到精确业务方只能给出目标无法给出步骤但人工操作又确实重复枯燥第三需要在多台机器上快速部署一致的自动化能力容器化的环境一致性优势能发挥出来。同时也要对 Agent 的能力边界有清醒认识。它不是一个“把需求灌进去就自动全搞定”的黑盒。没有清晰的 Skill 设计、没有合理的提示词、没有对视觉识别结果的 reviewAgent 一样会给你带来一堆莫名其妙的错误。想省前期设计工作的后面只会花更多时间在调试上。6.2 我踩过的坑和相对稳妥的建议第一个建议是先跑一个极小的场景只验证“看得到、点得到、返回对”这个闭环再扩展复杂流程。很多人一上来就想让 Agent 操作 ERP 全流程结果模型在某个环节理解偏了排查起来特别费劲最后归因都困难。但如果先从“打开一个网页、记录标题、点击一个按钮、返回结果”这种小闭环开始你能更快理解 Agent 的脾气。第二个建议是重视 Skill 的设计。Agent 的基础模型能力其实都差不多真正拉开差距的是你给了它哪些工具。Skill 定义得越清晰、越原子化Agent 的任务规划效果就越好。一个“处理销售数据”的 Skill不如拆成“读取 Excel”“清洗数据”“写入报表”三个 Skill模型组合它们的灵活度会高很多。第三个建议是永远保留人工确认关键步骤的能力。Agent 自动化执行时在删除、提交、转账这类不可逆操作前加一道确认是成本很低但非常必要的安全措施。别为了追求全自动把自己逼到不可控的境地。WorkBuddy 容器版和 Crayfish 这套组合目前来看给我的最大感受就是把“桌面自动化”从一个脚本问题变成了一个模型理解问题。它带来了不少灵活性也逼着你换一种思考方式去设计流程。如果你正好也在 RPA 维护的泥潭里挣扎或者想把桌面自动化能力容器化交付不妨先用一个 2 到 3 天的实验跑通一个真实小场景再决定要不要全情投入。