我给 Mac 的 Photo Booth 写了自动化脚本。为什么隐私比你想的重要得多
我解决的问题
我需要以编程方式捕捉我的物理环境。不是截图。是从我的摄像头拍一张真实照片。
大多数人会用 Selenium 或 Playwright 来自动化浏览器截图。但现实世界呢?我的桌子?我的脸?我身后的混乱?
我花了一个月时间构建 visual-perception ------ 一个 macOS 技能,可以自动化 Photo Booth 捕捉并用隐私优先的原则处理照片。这里是我学到的东西:自动化可见性的行为揭示了我们对桌面自动化思考方式中所有的问题。
更大的问题
现代 AI 智能体需要超越文本和文件的感官输入。我们在构建的系统需要:
- 监控物理工作空间
- 在安全环境中验证人类存在
- 审计远程工作期间的办公条件
- 创建带时间戳的视觉日志
但一旦你触及摄像头自动化,你就会撞上一堵问题墙:
- Photos.app 沙箱地狱 ------ Big Sur 在铁板钉钉的权限后锁定了照片库。AppleScript 名义上可以访问,但导出路径在较新的系统上被破坏了。
- macOS 自动化没有原生摄像头 API ------ Python 有
opencv,但你需要编译它。Deno 没有任何原生支持。AppleScript 只能和 Photo Booth 对话。 - 隐私剧场 vs. 真实隐私 ------ 摄像头指示灯会亮起,但用户不知道什么时候 或为什么。自动捕捉感觉有侵入性,即使它们无害。
大多数解决方案走了简单的路线:忽视问题,附带"隐私警告",希望没人注意。
我选择了不同的方式。
解决方案:平面文件 Photo Booth 集成
与其和 Photos.app 对抗,我直接进入 Photo Booth 的本地存储:
bash
~/Pictures/Photo\ Booth\ 图库/Pictures/
Photo Booth(macOS 应用)在这里将最近的捕捉存储为 JPEG。当你通过 Photo Booth 拍照时,它自动进入这个目录。
我的 visual-perception 技能这样做:
- 通过 AppleScript 触发 Photo Booth ------ 激活应用,点击快门按钮
- 等待文件 ------ 轮询 Photo Booth 目录获取新 JPEG
- 提取 + 验证 ------ 读取 EXIF,检查时间戳,验证确实是新的
- 复制到安全位置 ------ 移到
.workbuddy/visual/photos/并带元数据 - 可选处理 ------ 人脸检测、模糊 PII、记录隐私事件
没有 Photos.app。没有权限弹窗。没有框架臃肿。
这是 97 行 Python。它在 Big Sur 到 Sonoma 上工作。
核心代码(简化版)
python
import subprocess
import time
from pathlib import Path
from datetime import datetime
import json
def take_photo():
photo_dir = Path.home() / "Pictures" / "Photo Booth 图库" / "Pictures"
before = set(photo_dir.glob("*.jpeg"))
# 激活 Photo Booth 并拍照
script = """
tell application "Photo Booth"
activate
delay 0.5
# 模拟摄像头触发
key code 49 # spacebar
delay 2
end tell
"""
subprocess.run(["osascript", "-e", script])
# 轮询新文件
for _ in range(10):
time.sleep(0.5)
after = set(photo_dir.glob("*.jpeg"))
new_files = after - before
if new_files:
photo_path = list(new_files)[0]
# 保存到安全位置
output_dir = Path.home() / ".workbuddy" / "visual" / "photos"
output_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_path = output_dir / f"photo_{timestamp}.jpg"
photo_path.rename(output_path)
return str(output_path)
return None
死板简单。没有框架。没有 stdlib 以外的依赖。
为什么这重要
三个原因,这个方法比替代品更好:
1. 隐私设计,不是承诺
当你自动化摄像头访问时,你建立了一个合约。每次捕捉应该是:
- 被记录 ------ 什么被捕捉了,什么时候,为什么
- 可检查 ------ 用户可以审查输出
- 可撤销 ------ 可以立即删除
- 透明 ------ 系统在执行前宣布"拍照"
我的实现会记录每次捕捉:
json
{
"timestamp": "2026-04-01T01:15:00Z",
"source": "visual-perception-skill",
"output": "/Users/malt/.workbuddy/visual/photos/photo_20260401_011500.jpg",
"reason": "scheduled-environment-audit",
"privacy_flags": ["no-faces-detected", "no-screens-visible"]
}
用户(我)可以审计这个日志。我可以撤销访问。我可以看到确切我的智能体看到了什么。
2. 平面文件战胜数据库进行审计追踪
每张照片成为文件系统中带时间戳的工件。这是:
- 可查询的 ------
find . -mtime -1找到昨天的照片 - 便携的 ------ 复制目录,历史随之而来
- 不可变的 ------ 不能把数据库查询成不同结果
- 合规的 ------ 更容易向审计员展示"这是原始数据"
向量数据库或传统照片库隐藏了来源。文件不会。
3. 框架在杀死生产力
在我构建这个之前,我评估了:
- OpenCV + Python(100MB 编译,GPU 支持过度)
- 基于 Electron 的自动化(臃肿,启动缓慢)
- 昂贵的云 API(依赖,高延迟)
它们都在解决比我的难 10% 的问题。
我需要一个技能,不是框架。做一件事并做得对的工具。
我学到的东西
-
Big Sur 的 Photo Booth 目录因语言设置而异 ------ 我的系统命名为
Photo\ Booth\ 图库,但英文系统用Photo\ Booth\ 库。技能现在自动检测。 -
AppleScript 的
key code不一致 ------ Photo Booth 的 UI 已改变。我最后使用activate+ 延迟让 Photo Booth 通过观察文件创建来处理快门,而不是发送按键。 -
隐私指示灯是 UI 剧场 ------ macOS 显示摄像头灯,但不告诉你什么 被捕捉或去向哪里。我的日志层修复了这个。
-
桌面自动化不是主流因为它是特定平台的 ------ 但这是特性,不是缺陷。我不需要 Electron 或容器化。我需要 POSIX 工具、AppleScript 和平面文件。
更大的问题
当 AI 智能体获得更多自主权时,视觉输入将成为常规配置。生存下来的系统将是那些:
- 使隐私可见且可审计的
- 避免框架臃肿(平面文件 > 数据库)
- 将文件系统作为一流数据层
- 让人类保有控制权 ,不仅是同意
我在 claude-skills 仓库中发布了 visual-perception 作为开源技能。它是 MIT 许可证。用它来构建你自己的感觉管道。
但更重要的是:如果你在构建智能体,问自己这个问题:
"我在为效率自动化,还是在自动化以避免思考自动化意味着什么?"
因为有时,最难的工程问题不是代码。
是伦理。
资源
- GitHub : claude-skills/visual-perception
- 技能仓库 : WorkBuddy Skills 商城
- 相关阅读 :
你通过违背流行框架的方式解决过什么自动化问题?我很好奇------在评论中分享吧。