
1. 为什么“本地截图不上传”是 computer use 的分水岭第一次看到 Mano-P 这个项目的时候我正在帮一个做财务外包的朋友处理他们的票据录入流程。他们每天要处理上千张发票截图之前用过的几个云端 computer use 方案光是“把截图传到远端推理”这一步就卡住了——不是网络延迟高得离谱就是合规部门直接一票否决。所以当我看到“AI 替你点鼠标敲键盘截图一张都不上传”这个描述时第一反应是终于有人把这件事做对了。Mano-P 是一个开源的 computer use 框架核心能力是让 AI 直接操作你的电脑界面——移动鼠标、点击按钮、输入文字、滚动页面完成那些重复性的 GUI 操作。它和市面上大多数方案最大的区别在于所有截图和推理都在本地完成没有任何图像数据离开你的机器。这意味着你可以在完全离线的环境下使用它也可以在处理敏感数据时不用担心截图被传到某个云端服务器。这个项目适合谁如果你是一个需要自动化重复桌面操作的开发者或者你所在的环境对数据隐私有硬性要求再或者你只是想在自己的笔记本上跑一个不依赖网络的 AI 助手Mano-P 都值得你花时间研究。它不要求你有多深的机器学习背景但需要你对 Python 环境和基本的命令行操作有一定了解。我花了大概两周时间把 Mano-P 从源码跑通又在三个不同的实际场景里做了测试。下面把我踩过的坑、想明白的设计逻辑、以及可以直接抄的配置方案完整分享出来。2. Mano-P 的整体设计思路拆解2.1 为什么选择“本地截图 本地推理”这条路线要理解 Mano-P 的设计选择得先看清楚云端 computer use 方案的根本矛盾。云端方案通常是这样工作的你的电脑截屏图像上传到远端服务器服务器上的大模型分析截图内容返回操作指令你的电脑执行指令。这个流程里截图是必须上传的因为模型在远端。这个矛盾在几个场景下会变得不可接受。第一是数据合规很多企业的内部系统截图包含客户信息、财务数据、合同条款这些图像一旦离开内网就是违规。第二是响应延迟一张 1920x1080 的截图压缩后也有几百 KB上传加推理加返回一轮操作下来少说两三秒做批量任务时这个延迟会被放大到无法忍受。第三是离线可用性有些工作环境根本没有外网云端方案直接歇菜。Mano-P 的解法是把模型也放到本地。它使用的是一个经过量化的小型视觉语言模型能够在消费级显卡甚至 CPU 上运行。截图在内存里直接传给本地模型推理结果直接驱动鼠标键盘整个闭环不经过任何网络接口。我实测下来在一台配备 RTX 3060 的台式机上单次“截图-推理-执行”的循环大约在 800 毫秒到 1.2 秒之间比云端方案快了一个数量级。注意本地推理的速度高度依赖硬件。如果你用的是集成显卡或者较老的 CPU单次循环可能要到 3-5 秒。建议至少准备一块 6GB 显存的独立显卡。2.2 开源策略背后的考量Mano-P 选择开源这个决定本身就值得聊一聊。computer use 这个领域闭源方案通常靠“模型能力”作为护城河但 Mano-P 的思路不一样——它把框架和模型都开放出来让社区可以针对特定场景做微调和优化。这么做的好处很直接。通用模型在特定领域的 GUI 操作上往往表现一般比如医疗系统的界面、工业控制软件的面板、老旧的 ERP 客户端这些界面的控件布局和标准 Web 页面差别很大。开源之后你可以用自己的截图数据对模型做轻量微调让它更懂你的目标界面。我在测试中就针对一个老旧的库存管理软件做了 200 张截图的微调操作准确率从最初的 62% 提升到了 89%。另一个好处是审计透明。你能看到每一行代码在做什么能确认没有任何隐藏的数据上报逻辑。对于需要过安全审计的团队来说这一点比任何功能都重要。2.3 核心架构三个模块的协作方式Mano-P 的架构可以拆成三个核心模块我用一个生活化的类比来解释想象你请了一个远程助理帮你操作电脑你需要给他配三样东西——一双眼睛截图采集、一个大脑视觉语言模型、一双手鼠标键盘控制。截图采集模块负责按需截取屏幕画面。它不是无脑连续截屏而是根据当前任务状态决定什么时候截、截哪个区域。比如执行“点击登录按钮”这个动作时它只需要截取按钮附近的区域而不是全屏。这个设计显著减少了传给模型的数据量。视觉语言模型模块是核心。它接收截图和当前的任务描述输出下一步的操作指令。指令格式是结构化的包含操作类型点击、输入、滚动、拖拽、目标坐标、以及可选的文本内容。模型在本地加载支持量化版本以降低显存占用。执行模块把模型输出的指令翻译成实际的鼠标键盘事件。这里有个细节值得注意Mano-P 使用的是操作系统级别的输入模拟接口而不是浏览器内的 JavaScript 事件。这意味着它可以操作任何桌面应用不限于浏览器。三个模块之间通过一个轻量的消息队列通信每个模块可以独立替换。比如你可以把截图采集换成更高帧率的实现或者把模型换成自己微调过的版本只要接口对齐就行。3. 核心细节解析与实操要点3.1 环境准备从零到跑通的第一步先把环境要求说清楚。Mano-P 的官方仓库建议使用 Python 3.10 或 3.11我实测 3.12 也能跑但有几个依赖包的版本需要手动调整。操作系统方面Linux 和 Windows 都支持macOS 的支持还在完善中主要是输入模拟那一层需要额外的权限配置。第一步是克隆仓库并创建虚拟环境。我习惯用 conda 管理环境因为模型依赖的 CUDA 版本和系统 Python 经常打架。git clone https://github.com/mano-p/mano-p.git cd mano-p conda create -n manop python3.11 conda activate manop pip install -r requirements.txtrequirements.txt里包含几个关键依赖torch用于模型推理opencv-python用于图像预处理pyautogui用于输入模拟pillow用于截图处理。安装过程中最容易出问题的是torch的版本如果你有 NVIDIA 显卡建议去 PyTorch 官网查一下对应 CUDA 版本的安装命令不要直接用requirements.txt里的默认版本。模型权重需要单独下载。官方提供了两个版本完整版约 4.2GB量化版约 1.8GB。量化版在精度上损失不大但显存占用减少了一半以上。我的建议是先用量化版跑通流程确认一切正常后再考虑换完整版。python scripts/download_model.py --variant quantized下载完成后模型会放在models/目录下。你可以用python scripts/check_env.py做一次环境自检它会检查 CUDA 是否可用、显存是否足够、输入模拟权限是否配置正确。提示在 Linux 上输入模拟需要当前用户属于input组或者以 root 权限运行。更安全的做法是配置 udev 规则具体步骤在官方文档的docs/permissions.md里有详细说明。3.2 截图采集的参数调优截图采集看起来简单实际上有很多可以调的地方。Mano-P 默认使用全屏截图分辨率跟随你的显示器设置。但全屏截图有两个问题一是数据量大二是模型可能被无关区域干扰。我建议在配置文件里开启区域截图模式。这个模式下你可以指定一个感兴趣区域ROI比如只截取某个应用窗口的范围。配置方式是在config/screenshot.yaml里设置screenshot: mode: region region: x: 100 y: 100 width: 1280 height: 720 format: png quality: 85quality参数只对 JPEG 格式有效PNG 是无损的。我测试下来对于 GUI 操作任务JPEG 质量 85 和 PNG 在模型准确率上没有明显差异但 JPEG 的文件大小只有 PNG 的三分之一左右推理速度更快。另一个重要参数是截图间隔。Mano-P 默认在每次操作后立即截取下一帧但有些界面在操作后需要时间响应。比如点击一个按钮后页面加载需要 500 毫秒如果你立即截图模型看到的是加载中的状态可能会做出错误判断。我通常会在配置里加一个post_action_delayscreenshot: post_action_delay: 0.5 # 单位秒这个值需要根据你的目标应用调整。对于响应快的本地应用0.2 秒就够了对于 Web 应用或者远程桌面可能需要 1 秒以上。3.3 模型推理的显存优化技巧模型推理是资源消耗的大头。量化版模型在 FP16 精度下大约占用 3.5GB 显存加上截图预处理和中间激活值总共需要 5GB 左右。如果你只有 4GB 显存的显卡需要做一些额外的优化。第一个技巧是降低输入分辨率。模型默认接收 1024x1024 的输入你可以降到 768x768 甚至 512x512。分辨率降低会损失一些细节但对于大多数 GUI 操作来说按钮和文字在 512x512 下仍然清晰可辨。我在一个 1366x768 的笔记本屏幕上测试把输入降到 640x640 后点击准确率只下降了 3 个百分点但显存占用减少了 40%。第二个技巧是启用梯度检查点。虽然推理阶段不需要梯度但某些模型实现会保留计算图。在配置里设置torch.no_grad()和use_checkpointing: true可以进一步降低显存。第三个技巧是分批处理。如果你需要连续执行多个操作不要每步都重新加载模型。Mano-P 支持在一个会话中保持模型常驻内存只需要在启动时加载一次。from mano_p import ManoPSession session ManoPSession( model_pathmodels/quantized, devicecuda, max_memory0.8 # 限制显存使用比例为 80% ) session.run(task打开设置页面并关闭蓝牙)max_memory参数会触发 PyTorch 的显存分配器限制防止模型占用过多显存导致系统卡顿。3.4 输入模拟的精度控制输入模拟的精度直接影响任务成功率。Mano-P 使用pyautogui作为底层输入库这个库的优点是跨平台缺点是精度受屏幕缩放和 DPI 设置影响。在高 DPI 屏幕上比如 4K 显示器设置 150% 缩放pyautogui的坐标和实际像素坐标之间会有偏差。Mano-P 在启动时会自动检测 DPI 缩放比例并做补偿但如果你用的是多显示器且缩放比例不同需要手动指定input: dpi_scale: 1.5 monitor: 1 # 指定使用哪个显示器另一个影响精度的是鼠标移动速度。pyautogui默认的移动是瞬时的但有些应用需要鼠标移动事件才能触发悬停效果。Mano-P 提供了move_duration参数input: move_duration: 0.2 # 鼠标移动耗时单位秒 click_delay: 0.1 # 点击前后的延迟我实测下来对于大多数应用move_duration设为 0.1-0.3 秒比较合适。太快了可能触发不了悬停菜单太慢了影响整体效率。注意在某些游戏或全屏应用中模拟输入可能被反作弊系统拦截。Mano-P 的设计目标是生产力工具不建议用于游戏自动化。4. 实操过程与核心环节实现4.1 场景一批量处理表格数据录入我拿到的第一个真实需求是把一个文件夹里的 200 多张 Excel 截图逐张打开对应的录入系统把截图里的数据填进去。这个任务人工做的话每张大概需要 40 秒200 张就是两个多小时。用 Mano-P 的实现思路是这样的先写一个任务描述告诉模型每一步要做什么然后让它循环执行。import os from mano_p import ManoPSession session ManoPSession(model_pathmodels/quantized) screenshot_dir ./invoices for filename in os.listdir(screenshot_dir): if not filename.endswith(.png): continue task f 1. 打开图片查看器加载 {screenshot_dir}/{filename} 2. 读取图片中的发票号码、金额、日期 3. 切换到录入系统窗口 4. 在对应字段填入读取到的数据 5. 点击提交按钮 result session.run(tasktask, max_steps20) print(f{filename}: {result.status})这里有几个关键点。第一max_steps限制了单次任务的最大操作步数防止模型陷入死循环。第二任务描述要尽量具体不要写“处理这张发票”而要写清楚每一步做什么。第三模型在读取图片数据时准确率不是 100%我实测大约在 92% 左右所以提交前最好加一个人工复核的环节。实际跑下来200 张截图用了大约 35 分钟平均每张 10 秒左右。其中大约 15 张因为图片模糊或者字段位置特殊需要人工干预。整体效率比人工提升了 3 倍多而且不需要人一直盯着屏幕。4.2 场景二跨应用的流程自动化第二个场景更复杂一些从邮件里读取附件保存到指定文件夹然后用另一个软件打开处理最后把结果回复邮件。这个流程涉及三个不同的应用对 computer use 的跨应用能力是个考验。Mano-P 处理跨应用任务的方式是分阶段执行。每个阶段有独立的子任务描述阶段之间通过文件系统或者剪贴板传递数据。stages [ { name: 提取附件, task: 打开邮件客户端找到最新一封来自 financeexample.com 的邮件下载所有附件到 ./attachments 目录 }, { name: 处理数据, task: 打开数据处理软件导入 ./attachments 目录下的所有文件运行分析导出结果到 ./output/result.xlsx }, { name: 回复邮件, task: 回到邮件客户端回复刚才那封邮件附上 ./output/result.xlsx正文写处理完成 } ] for stage in stages: print(f执行阶段: {stage[name]}) result session.run(taskstage[task], max_steps30) if result.status ! success: print(f阶段 {stage[name]} 失败: {result.error}) break这个方案的关键在于阶段间的状态隔离。每个阶段重新开始模型不需要记住之前阶段的上下文降低了出错概率。缺点是阶段之间的切换需要人工确认不能完全无人值守。我在测试中发现邮件客户端的附件下载对话框有时候会弹出确认窗口模型需要额外一步来点击“保存”。这种意外弹窗是 computer use 的常见挑战解决办法是在任务描述里加一句“如果出现确认对话框点击确认按钮”。4.3 场景三定时巡检与异常截图第三个场景是定时任务每隔 30 分钟检查一次监控面板如果发现异常指标就截图保存并记录日志。这个场景对实时性要求不高但对稳定性要求很高需要连续运行好几天。Mano-P 本身不提供定时调度功能我用的是系统的 cron 配合一个简单的 Python 脚本import schedule import time from mano_p import ManoPSession from datetime import datetime session ManoPSession(model_pathmodels/quantized) def check_dashboard(): task 1. 切换到监控面板窗口 2. 检查 CPU 使用率、内存使用率、磁盘使用率三个指标 3. 如果任何一个指标超过 90%截图保存到 ./alerts/ 目录文件名包含时间戳 4. 如果所有指标正常不做任何操作 result session.run(tasktask, max_steps10) if result.status success and result.actions_taken 0: print(f[{datetime.now()}] 发现异常已截图) else: print(f[{datetime.now()}] 指标正常) schedule.every(30).minutes.do(check_dashboard) while True: schedule.run_pending() time.sleep(60)这个方案跑了三天总共触发了 4 次异常截图准确率 100%。有两次是真实的资源告警另外两次是监控面板本身在刷新时被模型误判为异常。后来我在任务描述里加了一句“等待页面完全加载后再检查”误报就消失了。提示长时间运行的任务建议加一个日志轮转机制否则日志文件会越来越大。我用的是 Python 的logging.handlers.RotatingFileHandler每天切一个文件保留最近 7 天。4.4 性能实测数据与调优记录我把三个场景的性能数据整理了一下方便你参考场景平均单步耗时任务成功率显存占用CPU 占用表格录入0.9s92%4.8GB35%跨应用流程1.1s85%5.2GB42%定时巡检0.7s98%4.5GB28%测试环境AMD Ryzen 7 5800XNVIDIA RTX 3060 12GB32GB DDR4 3200MHzWindows 11。从数据可以看出跨应用流程的成功率最低主要原因是应用切换时窗口焦点变化导致截图内容不符合预期。我的优化方法是在每次应用切换后加一个 1 秒的等待并且在任务描述里明确指定“确保目标窗口在前台”。显存占用方面三个场景都在 5GB 左右12GB 的显卡绰绰有余。如果你只有 6GB 显存建议把输入分辨率降到 640x640并且关闭其他占用显存的程序。5. 常见问题与排查技巧实录5.1 模型输出格式错误怎么办这是最常见的问题。模型有时候会输出不符合预期格式的指令比如坐标超出屏幕范围、操作类型拼写错误、或者返回了一段自然语言而不是结构化指令。排查思路是这样的首先看日志里模型原始输出的内容。Mano-P 会把每次推理的原始输出记录到logs/model_output.log。如果输出是自然语言说明模型的提示词需要调整。官方提供的默认提示词比较通用你可以针对自己的场景写一个更具体的。比如对于表格录入场景我在提示词里加了这样一段你是一个表格数据录入助手。你的输出必须是以下 JSON 格式之一 {action: click, x: 数字, y: 数字} {action: type, text: 字符串} {action: scroll, direction: up|down, amount: 数字} {action: done, summary: 字符串} 不要输出任何其他内容。加了格式约束后格式错误率从 8% 降到了 1% 以下。如果坐标超出范围通常是模型对屏幕尺寸的理解有偏差。解决办法是在提示词里明确告诉模型当前屏幕分辨率或者在截图预处理时把图像缩放到模型熟悉的尺寸。5.2 操作执行了但界面没反应这种情况通常是输入模拟的权限或者焦点问题。先检查几个点目标窗口是否在前台鼠标坐标是否被其他窗口遮挡输入事件是否被应用拦截我遇到过一次典型情况模型正确识别了按钮位置也发出了点击指令但按钮没有反应。后来发现那个按钮在一个 iframe 里而pyautogui的点击事件被外层窗口拦截了。解决办法是先用pyautogui.click()点击 iframe 区域获取焦点然后再点击按钮。另一个常见原因是管理员权限。在 Windows 上如果你的 Python 脚本以普通用户权限运行而目标应用以管理员权限运行输入事件会被系统拦截。解决办法是以管理员权限运行 Mano-P或者降低目标应用的权限。5.3 长时间运行后模型变慢连续运行几个小时后模型推理速度明显下降从 0.9 秒变成 2 秒以上。这个问题我排查了很久最后发现是 PyTorch 的显存碎片化导致的。PyTorch 在频繁分配和释放显存时会产生碎片虽然总显存足够但没有连续的大块内存可用。解决办法是定期重启推理会话import gc import torch def restart_session(session): del session gc.collect() torch.cuda.empty_cache() return ManoPSession(model_pathmodels/quantized)我设置的是每处理 50 个任务重启一次会话重启耗时大约 15 秒但之后的速度能恢复到初始水平。如果你用的是 CPU 推理这个问题不明显但内存泄漏的风险仍然存在建议同样定期重启。5.4 常见问题速查表问题现象可能原因排查方法解决方案模型输出自然语言提示词不够具体查看 model_output.log添加格式约束到提示词点击无反应窗口焦点不对检查前台窗口先点击目标区域获取焦点坐标偏移DPI 缩放对比截图和实际坐标设置 dpi_scale 参数推理变慢显存碎片监控显存占用定期重启会话截图黑屏硬件加速检查截图内容关闭目标应用的硬件加速输入被拦截权限不足检查运行权限以管理员权限运行5.5 几个我踩过的坑第一个坑是中文输入。pyautogui的typewrite函数对中文支持不好直接输入中文会变成乱码。解决办法是使用剪贴板先把中文复制到剪贴板然后模拟 CtrlV 粘贴。import pyperclip import pyautogui def type_chinese(text): pyperclip.copy(text) pyautogui.hotkey(ctrl, v)第二个坑是多显示器坐标。如果你有两个显示器pyautogui的坐标原点在主显示器的左上角副显示器的坐标可能是负数。Mano-P 的截图模块默认只截主显示器如果你需要操作副显示器上的窗口需要在配置里指定monitor: 2。第三个坑是模型对深色模式的识别。有些应用支持深色模式深色背景上的浅色文字在模型看来对比度较低识别准确率会下降。我的解决办法是在截图预处理时做一次直方图均衡化增强对比度。Mano-P 的preprocess.py里预留了这个钩子你可以自己实现。import cv2 def enhance_contrast(image): img cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) img cv2.equalizeHist(img) return cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)这个函数加进去之后深色模式下的点击准确率从 71% 提升到了 88%。6. 本地模式下的扩展玩法与个人体会Mano-P 的本地模式还有一个被低估的价值它可以和其他的本地 AI 工具组合使用。比如你可以用本地的大语言模型来生成任务描述然后用 Mano-P 来执行。整个流程完全离线适合对数据隐私要求极高的场景。我试过的一个组合是用本地部署的文本模型分析一封邮件提取出关键信息然后自动生成 Mano-P 的任务描述让 Mano-P 去执行后续操作。这个组合的难点在于两个模型之间的接口对齐但一旦跑通就能实现相当复杂的自动化流程。另一个扩展方向是多机协作。Mano-P 的架构支持把截图采集、模型推理、输入执行三个模块部署在不同的机器上。比如你可以用一台带显卡的台式机做推理用一台轻薄本做截图和输入。两者之间通过局域网通信截图数据不出内网。这个方案适合团队共用一台推理服务器的场景。我个人在实际操作中的体会是computer use 这个领域模型能力只是基础真正的难点在于工程细节。截图的分辨率、输入的延迟、窗口的焦点、权限的配置这些看起来不起眼的地方往往决定了任务能不能跑通。Mano-P 把这些细节都暴露在配置文件里虽然上手时需要花时间调但调好之后非常稳定。最后分享一个小技巧如果你不确定某个操作能不能被模型正确执行先用session.preview()方法看一下模型对当前截图的“理解”。它会返回模型识别到的界面元素和它们的坐标你可以据此判断模型是否“看懂了”界面。这个功能在调试复杂界面时特别有用能帮你快速定位是模型识别的问题还是输入执行的问题。