你的 Agent 终于有了一台 Mac:browser-use 开源 macOS Harness,只给 6 个原始原语
配套媒体
本页对应的 PPT 与演示视频
下载没反应?点这里复制直链
侧边栏预览窗口(Electron webview)会拦截下载,把下面的链接复制到 Chrome / Edge 地址栏打开即可保存。
../../macos-harness-recommend.pptx../../macos-harness-recommend.mp4本文目录
你的 Agent 终于有了一台 Mac:browser-use 开源 macOS Harness,只给 6 个原始原语
金句:当所有桌面 Agent 都在给每个 App 写专用工具时,browser-use 反手把"控制 Mac"压成了 6 个动词——剩下的,让模型自己写。
8 月 17 日晚上 10 点,browser-use 创始人 Gregor Zunic 在 X 上发了一条推文:"Introducing: macOS Harness. A persistent Python harness for virtually any Mac task. 它自己 vibe-launch 到了 GitHub 和 PyPI,还自己起草了这条推文,我根本没参与。100% 开源。"
这条推文不到一天就冲到 5.9 万浏览。但比起数字,真正值得玩味的是它背后的设计直觉:最好的桌面 Agent 工具,不是多给你装几个 App 专属工具,而是少到只剩 6 个原始原语,然后把"怎么干活"这件麻烦事,交还给模型自己。

为什么这篇值得写?
过去半年,桌面 Agent / Computer Use 是圈内最卷的方向之一。OpenAI 的 Codex computer use、Anthropic 的 Claude 操作电脑、Google 的 Gemini 操控浏览器……大家的路子出奇一致:给模型预置一堆专用工具——一个 Slack 工具、一个 Spotify 工具、一个 Final Cut 工具。
macOS Harness 偏偏反着来。它一句话把"为每个 App 写工具"这件事拒绝掉,只给模型 6 个最底层的原语,让 Agent 在任务进行到一半时,自己用普通 Python 把缺的逻辑补出来。
这不仅仅是少写几个函数那么简单。它触及一个正在被反复讨论的架构之争:Agent 到底该"预装一堆窄工具",还是"给一小撮通用原语 + 一个脚本环境"? browser-use 用一台 Mac 把这个问题摆到了桌面上。
先看图:6 个原语是什么
macOS Harness 把"控制一台 Mac"拆解成 6 个动词,README 的原话是:think in see, key, type, click, ax, and script。

see(app):读取某个 App 的窗口画面(截图)或可访问性树key(combo, app):向指定 App 的进程直接发送键盘事件type(text, app):向指定 App 输入文本click(x, y, app):向指定坐标点击,直达目标进程ax:调用 Apple 无障碍(Accessibility)API,读取/操作结构化 UI 元素script:跑 AppleScript / shell,直接驱动原生应用
注意一个细节:这些原语都带 app= 参数,意思是输入不是发给你整个系统,而是精准送到某个 App 的进程 ID。换句话说,它绕开了"必须先点开窗口、把窗口提到最前"这套人类操作习惯。
它是什么:一个进程,三张面孔
macOS Harness 的本质,是一个常驻的 Python 进程,从同一个进程里伸出三个能力面:

mac.*:用 CGWindow 截屏、用 CGEvent 把输入直接打到目标 App 的进程、用 Apple 的 Accessibility(AX)和 Apple Events API 读写原生 UIbrowser.*:通过 CDP 控制你真实登录的 Chrome——这复用的是 browser-use 自家的 Browser Harness 项目Path/subprocess:同一个 Python 进程里的普通文件和 shell 访问
三张面孔都能同时够到原生 macOS App 和 Electron App。一个最妙的例子:它可以在不把后台窗口提到最前的情况下,截到那个后台 App 的窗口;它甚至画了一个半透明、可点击穿透的虚拟光标,永远不会动你真实的鼠标——这样你能在自己机器上继续干活,Agent 在后台窗口里另起炉灶,两者不会抢同一个光标。
和 Codex computer use 差在哪?
有人直接在 X 上问 Zunic:"这和 OpenAI 的 Codex computer use 有什么区别?" 他的回答很实在:"Well it's open source that's for one haha."(主要就是它开源了)。

读直白点:这是一个真实但"薄"的差异点。Codex computer use 是 OpenAI 做的一个更"托管"、更产品化的控制面,自带移动端操控和线程管理;macOS Harness 走的是更 raw、更"自己写代码"的路——6 个原语加一个常驻 Python REPL,模型得自己写逻辑,而不是在一个预建好的控制面里操作。
没人说 macOS Harness "更好",只是设计哲学不同:一个开放、脚本优先;一个封闭、产品优先。但"开源 + 可自托管 + 代码可审计"这一点,对很多开发者就是刚需。
3 分钟上手:把安装也交给 Agent
macOS Harness 有个很有意思的细节:README 根本没给"人类一步步安装"的教程,而是直接给了一段写给 Codex / Claude Code 的提示词:
用
uv+ Python 3.12 从 github.com/browser-use/macos-harness 安装或升级 macOS Harness。注册macos-harness skill打印出的 skill,然后运行macos-harness doctor。解释缺失的 macOS 权限,申请前先问用户。最后,在不把窗口提到最前的情况下,截一张已经在运行的 App 来验证连通性。
把这段丢给一个已经在跑的编码 Agent,它会自己装包、注册自己的 skill、用 doctor 检查权限、验证连接——全程不需要人敲命令。这本身就是一个信号:工具的入门方式正在从"写给人看"变成"写给 Agent 执行"。
最小可运行片段长这样:
from macos_harness import Mac
mac = Mac()
# 看一眼 Spotify 当前窗口
frame = mac.see("Spotify")
# 用快捷键打开搜索框,输入歌手,点击结果
mac.key("cmd+k", app="Spotify")
mac.type("Alessia Cara", app="Spotify")
mac.click(640, 420, app="Spotify")
# 也可以直接走 AppleScript 驱动原生应用
mac.script('tell application "Spotify" to play')
browser、Path、subprocess 就在同一个进程里待命,文件访问和 shell 调用和 Mac 控制平起平坐,而不是躲在另一个集成后面。
核心点 1:反常识的"不写工具"
整个项目最反直觉的决定,是 README 明确拒绝为每个 App 写专用工具。它的逻辑是:Agent 在任务中途遇到没有现成帮手的情况,就自己用普通 Python 把缺的逻辑写出来,任务完成——没有任何 App 专属工具被加进一个不断膨胀的工具库。
这跟 Mario Zechner 的 Pi harness 在编码 Agent 层的思路一致:先发一个小核心,让扩展去填坑,而不是一开始就把所有功能焊死。macOS Harness 是把这股本能搬到了"桌面控制"这个具体场景上。
核心点 2:它真的尊重"人机共存"
很多 Computer Use 方案一上来就接管你的鼠标键盘,你没法在 Agent 干活时自己用电脑。macOS Harness 的两个设计刻意避开了这点:
- 永远不移动真实鼠标,用虚拟光标代替;
- 永远不把目标窗口提到最前,后台窗口也能截、也能控。
这让"Agent 在后台帮你点东西、你自己在前台继续写代码"成了可能。对日常多任务的人来说,这点比"它能不能点中按钮"更关键。
核心点 3:浏览器控制是"白送"的
因为 browser.* 底层复用 Browser Harness 的 CDP 控制,你真实登录的 Chrome 也能被这个 Python 进程直接驱动。这意味着"桌面原生 App + 网页"可以在同一个 Agent 上下文里打通——比如让 Agent 从 Chrome 里抓数据、写进本地文件、再丢给某个原生 App 处理,一条龙。
一个真实应用例子
设想你要做周报:Agent 自己打开 Chrome 进后台统计页截图(see),把数据写进本地 CSV(Path),再用 AppleScript 打开 Numbers 把表填好(script),全程你的鼠标没被抢,前台你还在回消息。过去这套得靠"专用工具 + 预置流程"硬编码,现在只是 6 个原语的组合。
生产实践经验 / 坑点
别被热度带偏,macOS Harness 现在还是个实验性、单贡献者、仅 macOS 的项目(发布时 v0.1.2,约 11 小时大,1 个贡献者)。上生产前先看清几件事:

- Canvas 绘制的非浏览器 UI 会退化成坐标点击:Apple 无障碍 API 只能暴露系统认识的"结构化 UI 元素",一旦碰到自定义 canvas(原生设计软件、游戏画面),就只能退回截图 + 像素坐标,鲁棒性明显下降。Zunic 的回应是"浏览器里的 canvas 由 Browser Harness 的 CDP 接管,问题不大",但原生非浏览器 canvas 仍是诚实的短板。
- 没有公开 benchmark:官方、README、推文里都没有成功率、延迟、失败率的量化数据,别拿它和成熟产品比可靠性。
- Windows 版未定:有人问会不会有 Windows harness,Zunic 回"看需求多不多",没有明确路线图。
- 别接真实账号和高危文件:先拿一个你不在乎的 App 试水,再考虑接正经工作流。
最适合什么场景?
- 想给自己的 Mac 配一个"后台小弟",帮你跑低频、可重复的桌面杂活
- 想研究"原语优先"的 Agent 架构,而不是被预置工具绑死
- 想把一个编码 Agent(Codex / Claude Code)的能力,从"写代码"延伸到"操作我的电脑"
不适合:关键无人值守流程、跨平台团队工具、对可靠性有硬指标的生产系统——至少现在还不行。
本文重点回顾
- macOS Harness 把"控制 Mac"压成 6 个原语:
see/key/type/click/ax/script,不为每个 App 写专用工具。 - 架构是一个常驻 Python 进程,三张面孔:
mac.*(原生控制)、browser.*(CDP 控 Chrome)、Path/subprocess(文件与 shell)。 - 反常识但务实:让模型在任务中途自己写胶水代码,而不是预装一堆窄工具。
- 尊重人机共存:虚拟光标 + 后台窗口控制,不抢你的真实鼠标。
- 局限要认清:canvas UI 退化、无 benchmark、仅 macOS、实验性——先试水再上生产。
金句收尾:别人在比谁的桌面 Agent 工具更多,browser-use 直接把工具表清空,把"造工具"的权利还给了模型本身。
延伸阅读
- 官方仓库:github.com/browser-use/macos-harness
- browser-use 的 Browser Harness(CDP 控 Chrome 的子项目)
- Mario Zechner 的 Pi harness(编码 Agent 层的"小核心"思路)
- Agent Harness 设计指南(原语优先 vs 预置工具优先的争论)