ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Persome屏幕捕获管线深度解析:Accessibility事件、本地OCR与截图加密存储

Persome屏幕捕获管线深度解析:Accessibility事件、本地OCR与截图加密存储

【免费下载链接】personal-model

Build your HUMAN.md.

项目地址:https://gitcode.com/gh_mirrors/pe/personal-model
点击查看免费下载

Persome(开源项目 personal-model)的屏幕捕获管线是整座个人模型的"眼睛":它通过 macOS Accessibility 事件感知你的窗口切换与输入,用本地 OCR 兜底读取无法获取文字的应用,并用 AES-256-GCM 加密存储截图,最终把每一次屏幕观察沉淀为构建HUMAN.md的证据链。

一、捕获管线在 Persome 中的位置

Persome 把活动数据组织成由浅入深的五层结构:Point(带来源的观察)、Line(随时间的关系)、Face(被证据支持的图案)、Volume(跨项目的更高阶结构)、Root(你当前整合后的个人模型)。

而屏幕捕获(Capture)是唯一直接接触外部世界的层——它每次观察生成一个 JSON 文件写入~/.persome/capture-buffer/,上层模块从不直接触碰 macOS。这正是"如何把屏幕活动变成个人模型"这条链路的第一环,官方说明见 docs/capture.md。

二、两个信号源:事件驱动 + 心跳兜底

管线由两种信号共同驱动,代码位于 src/persome/capture/watcher.py 与 src/persome/capture/scheduler.py:

信号源工作方式适用场景
mac-ax-watcher(主力,事件驱动)一个随包分发的 Swift 可执行文件,订阅所有运行中应用的 Accessibility 通知:窗口聚焦、内容变化(打字)、标题变化、应用激活,每个事件输出一行 JSON精确捕捉"你正在做什么"
心跳定时器(兜底)每heartbeat_minutes(默认 10 分钟)强制触发一次捕获长时间空闲也留下痕迹

事件流随后进入 src/persome/capture/event_dispatcher.py 做语义分类:

  • AXFocusedWindowChanged(窗口切换)、UserMouseClick(点击)→立即捕获
  • AXValueChanged(内容变化,如打字)→3 秒防抖后才捕获,避免每敲一个键截一帧
  • AXTitleChanged(标题变化)→直接跳过,噪声太大

三、四层去重:把"事件洪水"变成"有效观察"

事件源天生高噪。Persome 用四个时间维度的旋钮层层过滤,再叠加一个内容维度的指纹去重:

  • 防抖(默认 3 秒):窗口内的AXValueChanged事件合并,只触发一次
  • 事件去重(1 秒):相同(事件类型, 应用)对在窗口内直接丢弃
  • 最小捕获间隔(2 秒):任意两次捕获之间的硬性下限
  • 同窗口去重(5 秒):同一应用同标题窗口的非聚焦事件合并;聚焦切换永远放行

最关键的是内容指纹去重:调度器对每次构建的捕获计算hash(bundle + title + focused_element + visible_text + url),与上一次相同就直接不写盘。这能抓住时间旋钮抓不住的场景——锁屏过夜、暂停的视频、闲置的 IDE 会无限产生同样内容的 AX 事件;没有内容去重,缓冲区会被撑爆,当前会话也永远无法"闲置收尾"。

默认配置下,一个工作日产生几百条捕获,足够构建模型又不浪费磁盘。

四、capture_once:一次捕获的完整七步

所有信号最终汇入capture_once(定义于 src/persome/capture/scheduler.py),一次捕获依次执行:

  1. 调用一次性mac-ax-helper抓取当前窗口的 Accessibility 树,按ax_depth剪枝
  2. 从 AX 树提取focused_element(光标所在元素)、visible_text(屏幕上正在读的内容,约 10k 字符上限)、url
  3. 若前台是 cmux 终端,通过本地 socket RPC 注入真实终端文本
  4. OCR 兜底:AX 树读不出可用内容时,对聚焦窗口截图并提交本地 OCR 工作进程
  5. 截图(除非include_screenshot = false)
  6. 记录应用名、标题、bundle_id
  7. 以 ISO-8601 时间戳命名写入缓冲区,如2026-04-21T17-07-32p08-00.json

一个值得注意的细节:AX 深度是头号"坑"。原生 Cocoa 应用的 AX 树很浅(5–15 层),而 Electron 应用(VS Code、Slack、Notion 等)把用户内容嵌套在 20–60 层深的 UI 之下。Persome 默认ax_depth = 100,就是因为诊断发现某次重要对话在深度 30 时完全读不到。

五、本地 OCR:隐私友好的兜底方案

有些应用(微信、飞书、网易云音乐等)屏蔽 Accessibility API,AX 树里读不到正文。Persome 的 OCR 兜底路径完全在本地运行,图像不出机器:

聚焦窗口截图(临时、不落盘) → 本地 OCR 工作进程 → 文字 + 几何信息 → 应用感知结构化 → 回填 captures FTS 索引

实现细节(src/persome/capture/ocr_local.py):

  • Apple Silicon:运行随包捆绑的 PP-OCRv6(模型见 ocr_models/PP-OCRv6_tiny_det/ 与 ocr_models/PP-OCRv6_tiny_rec/),模型权重从本地目录加载,守护进程永不联网取模型
  • Intel Mac:PaddlePaddle 没有 macOS x86_64 版本,改用编译好的 Swift 助手调用系统 Apple Vision 框架,输出同构的文字、坐标框和置信度
  • 子进程即崩溃隔离边界:原生层崩溃只会让本次 OCR 失败,不会杀死主守护进程;且截图 OCR 结果永不进入 LLM prompt
  • 频控:每个窗口默认 15 秒内最多触发一次 OCR,失败静默降级回 AX-only 捕获

六、截图加密存储:AES-256-GCM 静态加密

截图是捕获中隐私敏感度最高的部分(占每条捕获约 77% 的字节)。Persome 用 src/persome/capture/screenshot_crypto.py 提供静态加密:

  • 密钥来自环境变量PERSOME_SCREENSHOT_KEY(64 位十六进制 = 32 字节),由install.sh在首次安装时自动生成,且跨重装保留
  • 信封格式为带版本魔法前缀的PSOMEGCM1:+ base64(IV(12) ‖ 密文 ‖ Tag(16)),可直接替换 JSON 里的image_base64字段,旧明文捕获保持可读
  • 失败即关闭:密钥缺失或格式错误时,持久化直接省略像素,但保留 AX 文本与元数据——宁可不存图,也不存明文
  • 所有读取方都经过read_screenshot这一个解码收口点,有密钥则解密,无密钥原样返回

配合include_screenshot = false还能彻底关闭持久化像素,OCR 仍可临时截图工作。

七、缓冲区分层保留与 FTS 搜索索引

截图是"重"数据,因此保留策略是分层的(由 timeline 心跳触发清理):

层级条件动作
剥截图mtime 超过 24 小时重写 JSON 去掉screenshot字段,体积降至约 20%,AX 文本保留
整体删除mtime 超过 168 小时(7 天)删除整个 JSON
按大小驱逐总缓冲超过 2 GB从最旧文件开始删除直到低于上限

与此同时,每条捕获写入时都会同步索引进 FTS5 虚拟表captures_fts(见 src/persome/store/fts.py),支撑 MCP 的search_captures和current_context工具——AI 客户端可以直接检索原始屏幕内容,而不用扫描磁盘 JSON。索引失步时一条persome rebuild-captures-index即可全量重建。

八、快速验证你的捕获管线

persome onboard # 权限 + OCR + 守护进程 + 健康检查 + 新鲜捕获证明 persome ocr status # 查看 OCR 配置与运行时状态 persome capture-once # 开发者诊断:立即写一条捕获 persome clean captures # 手动清空缓冲区

想暂停时,persome pause会落一个哨兵文件,捕获即刻短路;persome status的 Index Health 行可以随时告诉你管线是active、paused还是broken。

九、小结:从屏幕事件到 HUMAN.md

整条管线的设计哲学可以概括为三句话:

  1. 事件驱动 + 多层去重:只在"语义上有变化"时捕获,把高频噪声压成有效观察
  2. 本地优先:OCR 在设备上完成、截图静态加密,像素和文字都不出机器
  3. 分层存储:截图 24 小时即剥离,文本证据保留 7 天并进入全文索引,最终由 timeline 与 writer 管线蒸馏进你的个人模型

捕获层不直接生成模型,它负责让模型"有据可查"——每一条 Line、Face、Root 背后,都能追溯到capture-buffer里带时间戳的观察记录。这正是 Persome 构建HUMAN.md的底层保障。

【免费下载链接】personal-model

Build your HUMAN.md.

项目地址:https://gitcode.com/gh_mirrors/pe/personal-model
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进