屏幕上的大箭头(big-arrow-on-the-screen)是一个 Mac操作系统(macOS)命令行工具,其命令为大箭头(bigarrow),并为克劳德代码(Claude Code)与代码克斯(Codex)提供技能,可在每个窗口上方绘制箭头与标牌;点击会穿透到下方应用,键盘焦点保持在原处,箭头会自行消失,项目采用 MIT 许可证。你的人工智能代理可以重构单体仓库、编写迁移并解释 monads,但当它需要你点击一个按钮时它……
正文
big-arrow-on-the-screen(bigarrow)是一个 macOS 命令行工具,外加一个面向 Claude Code 和 Codex 的 skill,它在每个窗口之上绘制一个箭头和指示牌。点击会穿透到下面的应用,键盘焦点保持原地,箭头会自行消失。采用 MIT 许可。

你的 AI 智能体能重构单体仓库、写迁移脚本并解释 monad,但当它需要你点某个按钮时,只会把你没在看的一个终端里打印“please click Allow in the dialog”。
bigarrow给了它一根手指。

bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow: Ghostty may control your Mac"
箭头位于自己独立的透明窗口中,高于其他所有窗口,出现在每一块显示器和每一个 Space 上。点击目标会落到下面的应用里,而绘制完全不需要任何 macOS 权限。它是一个 Swift 二进制文件:没有守护进程,没有菜单栏图标,没有账号,没有遥测;而且我们检查过两次,里面没有 AI。它就是一个箭头。
这到底是干什么用的?
问得好。箭头大约从旧石器时代就有了。变化在于:软件智能体现在在你的 Mac 上做真正的工作,而它们迟早会碰到一个只有人类能做、或者人类想学着做的步骤。
- “点 Allow。” macOS 权限提示、OAuth 同意界面、“用……打开?”对话框。智能体能找到按钮,但不能或不该替你按。现在它可以指过去。
- “该你了。” 2FA 验证码、CAPTCHA、passkey、支付确认、签名、法律勾选框。这些是智能体绝不该代表你点击的东西。它指出来,你决定,它继续。
- “是这个窗口,不是那个。” 你有 14 个 Chrome 窗口。智能体知道它指的是哪个:
--window "Google Chrome:Pull request"。它甚至能选中正确的标签页:--app "Google Chrome:Pull request"。 - “我需要你,而你在泡咖啡。”
--say会把指示牌念出来。你的 Mac 会真的把你叫回桌前。 - “演示给我看。” 问智能体如何在 Keynote、Blender 或系统设置里做某件事,它会依次指向每个控件,而不是描述它们:
start,等你操作完,stop,下一步。就像产品导览,只是没有产品。完整示例:如何在 Mac 上允许屏幕录制,其中每一张截图都是智能体用 bigarrow 画的箭头。 - 帮助别人。 把它装在父母的 Mac 上,那里的智能体就能教他们如何把文档存成 PDF。指一下胜过“顶部那个按钮,不,另一个顶部”。
- 远程协助。 “不,是另一个网格图标。”直接指那个图标,而不是描述它。
- 演示、录屏、文档。 录制时高亮重点,或用
--png把箭头直接渲染进 PNG 用于文档。 - 调试坐标。 不确定 Accessibility、截图或 Peekaboo 的坐标对不对?指一下看看。
--dry-run --json会告诉它原本会指向哪里,而不实际绘制。
它不是什么:不是给人用的屏幕标注工具,不是点击机器人,也不是截图工具。它从不点击、输入或捕获任何东西。它只指。这是刻意为之。
真实应用,真实用例
这次没有假对话框。测试 Mac(macOS 27)上的真实应用、中立演示内容、全新的浏览器配置,以及由 scripts/real-scenes.sh 编排的真实 bigarrow。下面每条命令都是实际运行过的;脚本只为截图额外加上 --no-animation --json。

open "x-apple.systempreferences:com.apple.preference.security?PrivacyAccessibility" bigarrow start --element TerminalToggle --app "System Settings" \ --text "Franz, switch this on: Terminal may control your Mac" --from right
引导人类完成一次权限操作:深链接打开对应面板,箭头找到那一个开关,指示牌说明它的作用。(在 macOS 27 上,这个面板叫“设备控制与数据访问”。按旧名字没人找得到。)

bigarrow start --element Animate --app Keynote --role radiobutton --text "1. Click Animate" --from right bigarrow start --element "Add an Effect" --app Keynote --text "2. Add an Effect" --from right
教用一个应用:“我在哪里添加过渡?”两个编号步骤同时留在屏幕上,位于一个已经放弃文字的工具栏里。

bigarrow start --element PDF --role button --app TextEdit \ --text "Mom, click PDF, then Save as PDF" --from bottom
通过屏幕共享帮助父母,不用再花二十分钟解释“左下角那个小按钮,不,左边”。

bigarrow start --app "Google Chrome:Sourdough" --element "Sourdough - Wikipedia" --role radiobutton \ --text "It's this tab, not the other 13" --from top
--app "App:tab title" 会先把对应窗口带到前台并选中标签页,然后再指。智能体本来就知道是哪个标签页,现在你也知道了。

bigarrow start --element Group --role menubutton --app Finder \ --text "No, the other grid icon. This one." --from top
针对 macOS 27 更新的远程协助:齿轮图标没了,但现在有两个网格图标,而且永远都是另一个。
不是玩笑应用:如何在 Mac 上允许屏幕录制,这是一个真实的逐步指南,其中每一张截图都是智能体用 bigarrow 画的箭头。
安装
brew install franzenzenhofer/tap/bigarrow bigarrow install-skill # teaches Claude Code (~/.claude/skills) and Codex (~/.agents/skills)
从源码构建:swift build -c release(需要 Xcode 16 或更高,macOS 14 或更高),二进制文件位于 .build/release/bigarrow。该二进制是纯 Swift;scripts/ 里的 shell 和 Python 文件只用于录制截图和运行测试。
智能体需要的三个命令
bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow" # by label bigarrow point --at 760,500 --text "Franz, click HERE" # by coordinate bigarrow start --window "Safari:Inbox" --text "This window" && bigarrow stop # until stopped
每个箭头都会自行结束。没人需要替一个忘记收尾的智能体打扫:
| | |
| --- | --- |
| 时间限制 | bigarrow point ... --duration 10(默认 8 秒;start 为 300 秒;--duration 0 表示无限制) |
| 开始和停止 | bigarrow start ... 立即返回;bigarrow stop(或 stop --all)移除它 |
| 智能体退出时 | 当绘制箭头的智能体进程退出时,箭头结束(CLAUDE_PID,或 BIGARROW_OWNER_PID) |
| 人类回应后 | 作为 Claude Code UserPromptSubmit 钩子的 bigarrow stop --hook 会清除该会话的箭头 |
| 人类关闭它 | --close-button 在指示牌上放一个可点 X(可选开启) |
目标:--at X,Y、--rect X,Y,W,H、--mouse、--window App[:title]、--element Label --app App、--peekaboo ID --snapshot see.json(来自 Peekaboo 的 see --json)。坐标是全局左上角逻辑点,也就是 Accessibility、CGWindowList 和 Peekaboo 报告的坐标系。--display N 让 --at 和 --rect 相对某一显示器。
箭头与它所指向的应用绑定。使用 --app App[:window or tab title](或 --window)时,bigarrow 会先把该应用、窗口或 Chrome/Safari 标签页带到前台,因为指向一个藏在终端后面的窗口是一种特别的没用。如果之后另一个应用盖住了目标,箭头会隐藏,直到目标再次可见。--no-raise 让你的窗口保持原样。bigarrow elements --app X 列出 --element 可匹配的内容。bigarrow doctor 显示权限、权限归属者以及你的显示器。
每条命令都支持 --json。退出码:0 正常,2 输入错误,3 未找到目标,4 缺少权限。智能体喜欢退出码,人类则容忍它们。
外观
它就是一个箭头,所以我们在它的外观上花了不合理的大量时间。


在一台干净的测试机上的真实截图,六种外观分别覆盖白色、macOS 灰、深色、黑色、红色和一个杂乱的网页:


--shape bend|straight|zigzag|spiral(zigzag用于真的很紧急时;spiral在指向前先绕指示牌转一圈,用于绝不能漏掉时)--style arrow|ring|box;ring 和 box 只有边框,所以你仍能看到下面的内容--size S|M|L,--corners round|sharp--color red|orange|yellow|green|teal|blue|purple|pink|black|white|#RRGGBB--border shadow|white-black|black:默认是带阴影的白边(浅色上为深色);white-black在白边外侧加一圈细黑边而不是阴影;black只有一圈细黑轮廓- 每种颜色都能自定义:
--border-color、--text-color、--edge-color,以及 X 的--close-color和--close-x-color。省略时,各自会选一个可读的颜色 --close-button在指示牌右端放一个 X(白圈,X 为箭头颜色),它永远不会遮住文字或移出屏幕--follow跟随窗口或元素移动,--until-click在点击目标时结束,--say朗读指示牌- 同时出现多个箭头时,它们的指示牌会互相避开
箭杆通过一个外扩的接头从指示牌上长出来,这个接头永远不会撞上圆角。scripts/gallery.py 在离屏渲染每一种组合,并放大查看每个接缝(junctions),因为接头处出现接缝显然是让人无法接受的。
创意箭头
用中立演示对话框编排,并在干净的 CI runner 上用真实的 bigarrow 录制(BACKDROP_ARGS=--cover scripts/funny-scenes.sh)。对话框是假的,感受是真的。

--color green

--shape zigzag --color orange:zigzag,用于真的很紧急时

--shape spiral:先绕指示牌一圈,再指向按钮

--color purple

--close-button,因为人类拥有最后决定权

三次 start,一个按钮,零歧义

--style box --corners sharp,外加一课关于 macOS 权限的内容
常见问题
需要屏幕录制或辅助功能权限吗? 绘制不需要任何权限。某些定位目标的方式需要:
| 你使用的参数 | 权限 |
| --- | --- |
| --at、--rect、--mouse、--window App、--peekaboo、--app App | 无 |
| --element、elements、--until-click、--app App:title(拉起窗口或选择标签页) | 辅助功能 |
| --window App:title(macOS 26 会隐藏窗口标题) | 屏幕录制,外加用于拉起窗口的辅助功能(使用 --no-raise 时不需要) |
macOS 把这些权限授予启动 bigarrow 的应用,也就是你的终端或 IDE(Terminal、iTerm2、Ghostty、VS Code、Claude),而绝不是 bigarrow 本身。所以你要在系统设置里打开的就是那个应用。bigarrow doctor 会告诉你是哪个应用;当缺少权限时,命令以退出码 4 退出,并指出该应用和对应的设置面板。
它从不抢焦点。那它怎么会在最前面? 在 macOS 上,位于最上层和拥有键盘焦点是两回事。箭头的窗口处于屏幕保护程序窗口层级,高于普通窗口、对话框和全屏应用,但它永远不会变成活动窗口,所以你正在输入的内容仍会去它原本要去的地方。使用 --app 时,被指向的应用会先被带到前台。
我打字时它会抢焦点吗? 不会。这是项目中最难的 bug:NSApplication.run() 会悄悄激活一个没有终端的进程,于是分离出去的箭头抢走了焦点。bigarrow 改为自己泵送事件,并且测试会检查最前面的应用永不改变。
我能点穿它吗? 能,除了指示牌和箭杆之外的任何地方都可以:点在那里会移除箭头(指针下会稍微变暗以示说明)。点击目标,或箭头头部附近的任何位置,都会直接穿透到应用。点击箭头永远不会抢焦点。
多显示器?全屏应用?台前调度?Space? 支持,支持,支持,支持。包括位于主显示器左侧或上方的显示器(负坐标)。当箭头上正显示时拔掉显示器,箭头会礼貌离开。参见验证矩阵。
一个脉冲箭头占用多少 CPU? 在 CI runner 上测得 1.4%。实际工作由 Core Animation 在渲染服务中完成。
--element 在网页内部能用吗? 在 Electron 应用中可以。在 Chrome 中,只有当 Chrome 以 --force-renderer-accessibility 启动时(或开启 VoiceOver)才可以;Chrome 会忽略暴露页面内容的常规请求,2026 年 10 月在 Chrome 上验证过。Chrome 自己的工具栏始终可用。否则就按页面坐标来指,skill 里会说明。
智能体能用它来骗我吗,比如盖住 Decline 按钮? 它确实可以画在按钮上面。但一个能以你的身份运行 shell 命令的智能体,本来就已经能读你的文件、运行任何程序,所以 bigarrow 并没给它新能力。bigarrow 自身保证的每一点都有测试覆盖:box 和 ring 是轮廓,所以目标始终可见;只要目标周围有空间,指示牌就会避开目标放置,若没有空间(目标占满大部分显示器),它会尽量少地遮住目标;点击指示牌或箭杆会移除箭头;每个箭头都会自行结束。它从不点击、输入或捕获任何东西。而且当智能体要你批准某件事时,skill 会让它在指示牌上写明这次点击的作用,让你根据面前的事实做决定。
为什么要做成 skill?这会不会很耗 token? 智能体始终只看到 skill 的描述,约 190 token。完整说明约 2,200 token(用 Anthropic 的 token-count API 针对 Claude Opus 5.5 统计),只在智能体决定要指的时候才加载。它们教会智能体何时指、如何找目标、以及在指示牌上写什么。你也可以跳过 skill,自己调用 bigarrow。
为什么不直接用[某个屏幕标注应用]? 那些是给人在屏幕上画用的。而这是给程序从 shell 里指向东西用的,还带退出码。在写第一行代码前检查了 26 个工具(调研)。没有一个能做到这一点。
它是 AI 吗? 不是。它是你 AI 技术栈里最不智能的部分,并对此感到自豪。
我们如何确认它能工作
- 91 个自动化测试:几何、放置、接缝平滑度、一张黄金图像、录制的 window-server、Accessibility 与 Peekaboo 4.9.0 fixture,以及针对真实 window server 的测试(窗口层级 1000、点击穿透、焦点从不移动、分离与停止计时)。CI 在 macOS 15 上运行它们;它们在 macOS 26 和 macOS 27 上也通过。
- 17 项在干净 runner 上的行为检查(visual.yml):真实点击 X、
--until-click、--follow、拉起(以及--no-raise)、被覆盖时隐藏、选择 Chrome 标签页、随拥有者进程结束、stop --hook、--say、全屏应用、台前调度、切换 Space、第二块显示器、2x 显示器、箭头显示中拔掉显示器、CPU。上面的演示 GIF 由同一工作流在一台没有个人内容的桌面上录制。 - 一个只拿到 skill 和“给 Franz 指出 Chrome 里 Reload 按钮在哪”的新智能体,通过标签找到了它并构造出正确命令(记录)。它还发现了一个 bug,现在已变成一个测试。
给智能体(以及配置它们的人)
skill/big-arrow/ 里的 skill 同时适用于 Claude Code 和 Codex(一个 SKILL.md,Agent Skills 格式,外加给 Codex 的 agents/openai.yaml)。它告诉智能体何时指、如何选目标、要在指示牌上写完整句子、当你大概率没在看时加上 --say、并在你操作后 stop。
计划、决策、调研
docs/plan/PLAN.md(目标、架构、风险)、docs/plan/TICKETS.md(由 docs/plan/tickets.json 生成)、docs/decisions/、docs/research/(带链接的已验证事实)、docs/verification/、docs/skill-tests/、CHANGELOG.md。
先前工作与致谢
Peter Steinberger 的 Peekaboo visualizer(https://github.com/openclaw/Peekaboo)和 Nameplate(https://github.com/steipete/Nameplate)展示了覆盖窗口的做法和智能体 skill 的打包方式。两者都不画带标签的指向箭头,而这正是本项目填补的空白。bigarrow 可读取 Peekaboo 的 see --json 作为可选目标来源。
许可证
MIT。请负责任地指。
评论
讨论整体偏向质疑:不少评论认为它只是又一篇 LLM 生成的糟粕,或认为箭头只解决“点哪里”、未解决“该不该点”与弹窗焦点等真正问题。另一批人则看到远程协助、文档指引、帮助非技术用户以及 AI 代理视觉交互的价值,少数人还警告覆盖层可能遮挡“拒绝”按钮、架空同意。
认为这是 LLM 生成的低质量糟粕,不该上首页
- 多条评论直接把它归为 LLM 生成、围绕 LLM 糟粕的低质内容,有人讽刺“和别的 LLM 生成项目一样令人印象深刻”,也有人直接劝提交者别再把这种内容发上来。(较多人) > 又是一个由 LLM 撰写、围绕 LLM 糟粕的项目。(@einpoklum)
- 也有人用夸张玩笑列出“彩虹滴血箭头、火焰粒子文本框、覆盖静音强行播放气笛声”等荒诞功能,嘲讽它当前完成度低、完全不可用。(少数人)
认为箭头只解决“点哪里”,未解决“该不该点”和弹窗焦点
- 批评者指出,被指的元素本身已有说明文案,再画箭头等于“给标签再加标签”;更关键的是它只告诉用户点哪里,却不帮用户理解后果,而人类本该先读懂再同意或中止。(较多人)
- 若只是替机器人点一下授权按钮,那还不如直接给它 root 权限;也有人认为真正该修的是让确认弹窗自动获焦,而不是再加一个同样会失焦、同样打断操作的箭头。 > 箭头只解决“点哪里”,不解决“这件事该不该发生”;人类本该先读懂后果,再同意或中止。(@tilemarch)
认为做成专门项目是过度设计,直接让模型标注截图即可
- 有评论反问:既然模型已经能看懂界面,为什么不直接让它“在截图里用带编号的样式箭头标出操作”,而要把这件事做成一个技能、并烧掉大量上下文?(少数人) > 直接让模型在截图里用带编号的样式箭头标出操作即可,没必要专门做成技能、烧掉大量上下文。(@m-s-y)
认为用四种语言画箭头是过度设计,示例也完成度不足
- 有人质疑在 Mac 上画个指示图形根本不需要用到 Swift、Shell、Python 和 Objective-C 四种语言;示例箭头本身也被批评画得歪扭、不自然,README 里关于录屏与辅助权限的说明更是含糊到读不懂。(少数人) > 在 Mac 上画个东西,真的需要 Swift、Shell、Python 和 Objective-C 四种语言吗?(@TekMol)
担心覆盖层会遮挡或篡改确认按钮,架空真正的同意
- 若它真能画在权限弹窗之上,理论上也能画个框遮住“拒绝”按钮、改写“同意”按钮的文案;结合“人类确认正是为了拦住代理擅自操作”的观点,这种能力会架空真正的同意。(少数人) > 既然它能画在权限弹窗上面,那也能画个框遮住“拒绝”按钮、改写“同意”按钮的文案。(@hn8726)
认为它适合远程协助、文档指引和帮助非技术用户
- 很多人从实际场景看到价值:文档截图里常写“点击 X”,但用户仍要肉眼搜索;远程帮父母操作时常要在电话里反复纠正“不是那个齿轮图标”;它也能帮非技术用户指认唯一正确的下载按钮,或在 iPad 上引导完成银行转账。(较多人) > 远程帮父母操作时常要在电话里反复说“不是那个齿轮图标”,直接指出来比描述更省事。(@ghm2180)
认为它展示了视觉化 AI 代理交互的潜力,甚至可用于代理间通信
- 支持者认为,这类视觉指向不止用于人机之间:AI 代理之间或 AI 代理与自身运行框架也能借它传递注意力,比只读侧边栏或开弹窗更有想象力;本质上是把人类“指出、高亮”的能力交给 LLM。(少数人) > 我们人类能在纸上指出、用荧光笔标出重点,为什么不能也让 LLM 拥有指向和高亮的能力?(@melvinroest)
有价值的补充
- DonHopkins 补充了一个冷知识:1989 年他就用 PostScript 为 NeWS 和 PSIBER Space Deck 的 Pseudo Scientific Visualizer 写过“手指”注释覆盖层,屏幕指向并不是新概念。(@DonHopkins)
- satyanash 从焦点机制指出:确认弹窗通常绑定在触发它的终端上,而终端不会自动获焦;如果箭头也躲在后面不获焦,那么让弹窗自身自动获焦才是更直接的修法,画箭头和弹窗打断程度其实差不多。(@satyanash)
- melvinroest 以 WebMCP 为例说明:要让 LLM 可靠地指向界面元素,前端可通过 WebMCP 之类方式提升可发现性,而不是让模型把代码全读一遍;再配合高亮,会比只读侧边栏更可用。