Typesafe-computer-use 以每步 1/50 美分的成本驱动 Mac 达成目标
摘要
typesafe-computer-use 是一种工具,通过使用经济高效的 AI 决策来驱动 Mac 达成目标,从而自动化 Mac 的使用,其成本和速度远优于使用大型语言模型。
查看缓存全文
缓存时间: 2026/09/19 06:23
awlevin/typesafe-computer-use 来源: https://github.com/awlevin/typesafe-computer-use
typesafe-computer-use 通过你输入的简单英文指令驱动一台Mac完成目标,每一步的成本约为五十分之一美分。它从不向大型模型发送截图,而是通过确定性方式读取屏幕,询问一个小型分类器接下来该执行哪个操作,仅在真正需要自由文本输入的字段中才调用文本生成模型。
clicker "go to techcrunch and take me to the checkout page for the cheapest tickets to their next upcoming event" --act
为何前沿模型计算机使用功能强大但昂贵:每一步都发送截图并等待数秒以获取计划。
大多数步骤并不需要一个计划。它们只需要从一个简短列表中快速、低成本地做出一个选择,并附带一个可用于条件判断的置信度数值。
TypeSafe (https://docs.typesafe.ai) 正是提供这样的服务:一个决策模型,能在几百毫秒内回答一个针对最多255个选项的Choice请求,返回完整的概率分布和经过校准的置信度,并且输出令牌免费。
本项目是一个围绕该模型构建的计算机使用循环。
在相同截图和目标下测量,每次一步决策:
| typesafe (jev) | Claude Opus 5, 裸截图 | 倍数 | |
|---|---|---|---|
| 输入令牌 | 4,882 | 4,785 | 相同 |
| 每次决策成本 | $0.0002 | $0.032 | 便宜155倍 |
| 每次决策成本(带历史记录的真实循环) | $0.0002 | $0.035 至 $0.08 | 便宜170倍 至 390倍 |
| 每12步任务成本 | $0.003 | $0.40 至 $0.90 | 便宜130倍 至 300倍 |
| 模型延迟 | 0.13 至 0.38 秒 | 5.2 秒 | 快14倍 至 40倍 |
| 端到端步骤(含捕获和OCR) | 约 1.5 秒 | 约 5.5 秒 | 快3.7倍 |
坦诚的注意事项:大型模型直接从像素中读取事件日期并独立进行比较。分类器则需要下文描述的日期解析功能。前沿模型免费完成的每一步推理,在这里都必须重建为确定性的状态。
安装
需要 macOS 14 或更新版本、Python 3.12 或更新版本、uv (https://docs.astral.sh/uv/)。
git clone https://github.com/awlevin/typesafe-computer-use
cd typesafe-computer-use
uv sync
cp .env.example .env # 填入密钥
| 变量 | 必需 | 用途 |
|---|---|---|
TYPESAFE_API_KEY | 是 | 每次决策 |
ANTHROPIC_API_KEY | 否 | type_text、写手提议的URL和最终答案 |
CLICKER_EMAIL | 否 | 启用 type_email 操作 |
CLICKER_BROWSER | 否 | 默认为 Google Chrome |
CLICKER_WRITER_MODEL | 否 | 默认为 claude-haiku-4-5 |
CLICKER_ANSWER_MODEL | 否 | 读取最后屏幕以生成最终答案;默认为 claude-sonnet-5 |
在“系统设置 > 隐私与安全性”中,为你的终端授予屏幕录制和辅助功能权限。没有前者,捕获的内容将是墙纸。没有后者,合成点击会被静默丢弃,且 --act 无法启动。
使用
uv run clicker "open the Playground" # 干运行:一步,打印将执行的操作
uv run clicker "open the Playground" --act # 驱动机器,最多100步
uv run clicker "log in" --act --steps 20 --delay 3 # 更长更慢
uv run clicker-inspect "any goal" # 3-2-1,捕获,打开标注后的屏幕及载荷
请先清空终端。它位于屏幕上,因此其文本是OCR输入的一部分。
停止正在运行的任务。 在终端获得焦点时按 Ctrl-C,或从任何应用将鼠标猛甩到屏幕左上角。循环也会在遇到 done 或 none、置信度低于 --min-confidence(0.4)、连续两次无操作后,或达到 --steps 时自动停止。
答案生成。 当循环自行停止时,写手会读取它停止时的屏幕并打印结果:目标要求的信息,或者如果屏幕不包含该信息,则说明现状及下一步。若本应执行操作的干运行或中止的运行,则不会打印答案。
一个步骤的工作原理
screencapture ─► Vision OCR ─► 将行合并为块 ─► 丢弃重复目标的行
│
辅助功能 ─► 可操作元素(角色、标签、框),修剪至显示范围内,标记的可按压项保留为屏外控件 │
│
└─► 一个带编号的项列表,每项携带其来源
│
辅助功能 ─► 聚焦字段(角色、标签、占位符、值、框)
AppleScript ─► 前台应用及进程ID,活动标签页URL
时钟 ─► 本地日期和时间
dates.py ─► 在任何包含日期的块上标注 "dated 2026-10-13 (in 27 days)",在其相邻块上标注 "near a line dated ..."
│
▼
一次 TypeSafe 请求,三个 Choice,若包含屏外控件则为四个
┌────────────────────────────────────────────────────────────┐
│ kind : click_item | use_browser | type_text | scroll... │
│ item : 哪一项(仅用于 click_item) │
│ site : 哪个网站(仅用于 use_browser) │
│ offscreen : 哪个隐藏控件(仅用于 press_offscreen) │
└────────────────────────────────────────────────────────────┘
│
▼
确定性操作 ─► 等待 ─► 下一步
项携带了其来源:文本块为 ocr,应用声明的控件为 ax,两者同时找到同一项时为 ax+ocr。一个 ax 项在标准中读作 button 'Share' (top-right),这样分类器就能区分真正的控件和一行文本。
将决策拆分为三个问题,可以将屏幕噪声排除在动作选择之外。构建此系统时发现的所有停滞,都源于两个含义相同的选项。置信度衡量的是集中程度,因此重叠的选项总是会被视为不确定。请确保动作集互斥。
OCR成本
视觉识别约占一个步骤的三分之二,其费用按文本量而非像素数计算,因此唯一真正的节省在于读取更少的屏幕内容。
-
裁剪。 每一步读取带有8点边距的前台窗口,加上相同列上方的菜单栏条带,并限制在显示范围内。桌面上和后台窗口中的文本对决策而言是噪声。将条带裁剪至窗口宽度是裁剪在全高窗口上生效的关键。代价是:时钟和窗口右侧的菜单附加项将不会被读取。它们仍然可以通过辅助功能树被点击。
-
重用。 捕获的图像与前一次捕获的1/8缩放版本,在256像素的块中进行比较。未改变的块保留上一步生成的行。改变的块被聚类成斑点,边和角视为相连,每个斑点成为一个独立读取的矩形。分散的变化是常见情况,比如时钟数字加上一处重绘,而一个跨越两者的矩形将横跨整个显示区域。每个矩形都会扩大,直到没有已知行跨越其边缘,因为裁剪穿过的行只会返回其可见部分;扩大后相遇的矩形会合并,超过四个时则按最近配对合并至四个。当变化块超过60%、区域累计矩形面积超过60%、或应用切换或窗口移动时,则直接读取整个区域。计时行会显示读取量及分块数:
ocr 0.31s (22% of screen, 2 rects)。重放(--image)始终读取整个图像且从不重用,因此离线重放与原始运行匹配。
辅助功能树
OCR无法看到图标。辅助功能树可以,因此每一步还会遍历前台进程中带有标签的、屏幕上的控件。覆盖率不均匀,在一台Mac上的十个应用中测量:Finder 100%的屏幕控件带标签,Chrome 88%,Slack 85%,Notion 68%,Spotify 0%(其CEF外壳仅暴露三个窗口按钮,无其他)。终端将网格暴露为一个文本区域。因此AX是一个额外来源,而非替代。标签存在于 AXDescription(Web和Electron)、AXTitle(AppKit),或较短的 AXValue(其他情况)中。装饰性图片使用其周围控件的标签;列表行则从浅层的 AXStaticText 获取标签。框架信息可能不准确,因此遍历会严格修剪:
- 跳过任何实际框架不在显示范围内的子树(备忘录会报告向下200个屏幕的行,Chrome会将滚动出视口的节点停在上方)
- 跳过宽度或高度小于4点的任何节点(Chromium会将滚动出视口的网页节点限制为细条)
- 跳过
AXMenu子树,它们是关闭菜单后面的成千上万个零尺寸项 - 跳过无名的
AXGroup布局框,即使可按压 - 达到4000个节点或0.6秒时停止,并予以说明
此处测量的遍历:Finder 152个控件用时0.08秒,Chrome 172个控件用时0.59秒。辅助功能握手属性(AXManualAccessibility、AXEnhancedUserInterface)在此macOS上不受支持,因此不依赖它们。
屏外控件
AXPress 不需要元素可见。备忘录会选择停在显示区域下方数千点处的行,Chromium会将点击传递给一个因页面滚动而被限制为1像素细条的链接,而一个自动隐藏的Dock会从底部边缘下方5点处交出其所有37个项目。因此,相同的遍历会保留其修剪掉的、标记的、可按压节点,并将它们作为一个单独的上限列表提供,而不是混入项列表中:捕获中没有任何内容指向它们,鼠标点击会落在完全不同的地方。列表按角色和标签去重,删除可见项已有的标签,并在120个控件后停止,之后这些子树会像之前一样被修剪,因此遍历成本与以往相同。仅在列表非空时提供,作为一个 press_offscreen 动作加上一个 offscreen 问题,步骤日志会将其计在 ax= 旁边。拒绝即结束:没有像素可以回退,因此被视为无操作。遍历发现的内容取决于应用,且节点和时间上限首先对大树生效:备忘录和Chrome将所有4000个节点用于已在屏幕上的内容,并报告无隐藏项。
动作空间
| 键 | 功能 |
|---|---|
click_item | 当项来自辅助功能树时,通过辅助功能树按压元素,使按压落在控件上而非覆盖其上的内容;否则在方框中心鼠标点击,作为按压被拒绝时的备选方案 |
press_offscreen | 对应用暴露但不显示的标记控件执行 AXPress,从屏外列表中选择;仅在该列表非空时提供,且拒绝计为无操作,因为没有像素可回退 |
use_browser | 进入浏览器,显示 site 答案指定的网站:none 将其带到已打开该页面的前台,SITES 目录键通过AppleScript open location 打开该URL,other 打开写手提议的URL |
type_text | 写手组合字符串;通过辅助功能树设置到聚焦元素上,当值无法回读时使用按键输入作为备选,然后TypeSafe Noul检查字段值 |
type_email | 以相同方式填写 $CLICKER_EMAIL;除非聚焦的是文本字段,否则拒绝 |
press_enter、press_escape | 键盘 |
scroll_down、scroll_up | 10行,将光标停在前台窗口上之后 |
wait | 屏幕仍在加载 |
done、none | 停止 |
自由文本的来源
分类器从不生成文本。写手模型在三个地方运行,每个都有一个小数据包和结构化回复:
type_text接收目标、最近的操作、聚焦字段的标签和占位符,以及字段附近的OCR行。它返回{fill, text}。凭证字段返回fill: false,不会输入任何内容。输入后,一个Noul会评估字段当前是否持有合理的值。低于0.5则清空字段。use_browser并带site: other时接收目标并返回{ok, url}。代码会拒绝任何不是带有主机名的干净https URL的内容。- 答案生成,一次,在循环自行停止时。它接收目标、所有采取的操作、运行停止的原因、最后屏幕的文本以及捕获本身(因为OCR有时会误读字母并丢失布局)。它返回
{achieved, answer},并被告知仅从屏幕获取答案。当操作使上一步的捕获过时,会先再次捕获屏幕。此调用使用CLICKER_ANSWER_MODEL,一个比逐步写手更强的阅读模型。
密码永远不会被输入。请依赖浏览器的密码管理器或OCR可读取的SSO按钮。
运行文件夹
每次运行都会写入 runs/<timestamp>/,以便可以重放停滞并进行离线修复:
| 文件 | 内容 |
|---|---|
run.log、run.json | 所有打印内容;目标、结果(done、nothing helps、low confidence、stalled、step limit、dry run、aborted、crashed)、answer 和 goal_achieved、秒数、每个操作、配置和 timing(每个阶段的平均和最大秒数,附 steps_timed) |
answer-raw.png | 读取答案时的捕获(当操作使上一步捕获过时时) |
step-NNN-raw.png | 捕获 |
step-NNN.png | 蓝色编号的项,辅助功能项为橙色,选定项为红色,聚焦字段为绿色 |
step-NNN-payload.txt | 发送到TypeSafe的确切 state 和标准,然后是每个项(含来源、角色、框、点击点、置信度),接着是屏外控件 |
step-NNN-answers.json | 分类器返回的每个概率,它被提供的屏外控件,加上该步骤的 timing |
每个步骤也会记录其成本,因此慢的阶段一目了然:
timing: capture 0.31s screenshot 0.28s app 0.01s window 0.02s field 0.01s url 0.01s ocr 0.31s (22% of screen) ax 0.06s decide 0.21s act 0.05s total 0.95s
capture 涵盖其下的四次往返;当步骤未执行操作时,act 会被省略。
重放保存的捕获,如同实时运行,无需触碰屏幕:
uv run clicker "same goal" --image runs/<timestamp>/step-003-raw.png --app "Google Chrome" --url "https://example.com/"
代码结构
typesafe_computer_use/
macos.py 唯一触及Quartz、AX、AppleScript的模块(平台适配器),包括用于可操作元素的有界遍历
perception.py 捕获、OCR、读取区域和变更块缓存、块合并、目标回声过滤器、辅助功能项源,以及两者的合并
dates.py 日期解析和 "in N days" 提示
decide.py 状态、标准、三选一请求、Noul检查
writer.py 写手模型、结构化回复、URL验证、最终答案
actions.py 每个操作一个处理程序,每个返回一行历史记录
runner.py 步骤循环、运行文件夹、停止规则、答案交接
report.py 日志记录、标注截图、载荷转储
timing.py 阶段计时器、计时行、运行摘要
cli.py `clicker` 和 `clicker-inspect`
tests/ 纯逻辑:日期、合并、阅读顺序、回声过滤器、配置、决策、使用假树遍历树
Linux移植版将 macos.py 替换为xdotool和AT-SPI,并将Vision OCR替换为PaddleOCR或RapidOCR。树遍历本身通过可调用对象获取子节点、属性和动作,因此只有这三个绑定需要更改。其他部分不感知平台。
已知限制
- OCR只能看到文本,辅助功能树仅覆盖发布了树的应用。在终端、画布或Spotify中,仅图标的按钮两个来源都不可见。
- 两个相同的标签只获得一个粗略的区域提示并平分选票。
- 仅捕获主显示器。
- 在
--act运行期间使用机器会与它争夺焦点和光标。 - 网站目录故意很小;写手覆盖其余部分。
开发
uv run ruff check . && uv run ruff format --check .
uv run pytest -q
CI在macOS上运行相同命令。参见 CONTRIBUTING.md。
许可证
相似文章
我们构建了一个 computer-use API,在重复任务上最多可削减 90% 的 token 消耗,可接入 Claude Code、Codex、Cursor 或你自己的代码
Agent S(ICLR 2025)团队开源了 Sai——一个 computer-use API,它会将计划编译成可自愈的代码,而不是每次从截图重新推理,从而在重复任务上将 token 消耗削减最多 90%。Sai 以 73% 的得分、每任务 $15.70 的成本登顶 OSWorld 2.0,超过 Claude Opus 5(70.6%,$23.70)和 GPT-5.6 Sol(62.6%,$26.62)。
@injaneity:我逆向了 @OpenAI 的 Codex Computer Use,做了 pi-computer-use:一款模型无关的 macOS 电脑自动化工具,送给所有 π 爱好者
一位开发者逆向 OpenAI 的 Codex Computer Use,开源打造 pi-computer-use:支持任意模型的 macOS 自动化工具,优先走 AX 导航,并为兼容模型提供视觉回退。
Typeahead
Typeahead为你Mac上的每个应用带来AI驱动的自动补全,提升打字速度和效率。
@kentcdodds:我知道我们大家都对计算机使用功能及其强大之处感到非常兴奋,但这也是为什么 @OpenAI 和其他公司在 WebMCP 和 MCP 上投入巨大,原因在于计算机使用的成本非常昂贵。
由于截图产生的高token成本,使用大语言模型的计算机使用成本比结构化API高出约45倍。建议采用混合方案:大多数任务使用结构化API,仅在必要时才使用计算机使用功能。
Macuse
Macuse 让您的 AI 在 macOS 上拥有超能力,通过 AI 功能提升生产力。