OpenClaw Logbook 插件完全指南:基于屏幕快照的自动工作日志
【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw
OpenClaw 内置的 Logbook 插件把"屏幕活动"转化为一份自动维护的工作日志:它以固定间隔从配对的节点抓取屏幕快照,经过视觉模型生成带时间戳的活动观察,再汇总为可回放的当日时间线卡片,并支持站会摘要与"问一问今天"的自然语言问答。本文基于 docs/plugins/logbook.md 与 插件参考页 展开,并对照 extensions/logbook 下的完整源码实现,介绍启用方式、四阶段流水线、双模型路由、全部配置项、Gateway RPC 接口与隐私边界,读完即可在自己的 OpenClaw 环境上部署并排查这套自动工作日志。
插件定位与分发
Logbook 的定位在参考页中描述得很直接:Automatic work journal: captures periodic screen snapshots from a paired node and turns them into a reviewable timeline of your day.(自动工作日志:从配对节点周期性地抓取屏幕快照,并将其变成可回顾的一天时间线。)
- 包名:
@openclaw/logbook,见 extensions/logbook/package.json 中的"name": "@openclaw/logbook"。 - 安装途径:随 OpenClaw 内置分发,无需额外安装,只需启用。
- 默认状态:
enabledByDefault: false,即默认禁用,见 extensions/logbook/openclaw.plugin.json。且启用即代表 Gateway 同意进行屏幕抓取——因为captureEnabled默认值为true。 - 激活方式:
activation.onStartup: true,随 Gateway 启动而激活。 - Surface:该插件不声明任何 channel、provider、command 或 contract(参考页的 Surface 一节明确说明),它完全以 Gateway 后台服务 + 自定义 RPC 方法 + Control UI 标签页的形式工作。
运行架构与数据存放
Logbook 采用"Gateway 集中式"架构:
- 抓取命令由配对的节点执行(应用型节点或 headless node host),快照数据回传 Gateway。
- OpenClaw 拥有的状态统一存放在 Gateway 的
<state-dir>/logbook/目录下:JPEG 帧文件与 SQLite 时间线数据库都在这里。从 extensions/logbook/index.ts 可见dataDir: path.join(ctx.stateDir, "logbook")。 - 模型处理不保证在本机:采样截图走配置的视觉路由,观察文本与时间线卡片文本走默认 agent 模型。若屏幕内容与派生文本都必须留在本机,两个阶段都要配置本地模型路由。
- 本地时区是唯一的时间基准:一天的分界与时间线时钟都使用 Gateway 的本地时区,而非浏览器时区,这决定了"日"与卡片时间的划分口径。
前置条件
启用 Logbook 前需要满足三件事:
- 一个已连接且暴露抓图命令的节点:节点必须支持
screen.snapshot(macOS 应用型节点,需要授予"屏幕录制"权限)或logbook.snapshot(插件为 headless 节点提供的命令,基于系统screencapture工具)。无头 macOS 节点通过openclaw node host run运行,在插件激活后才会通告logbook.snapshot。节点的概念与配对流程见 Nodes 文档。 - 内置 Codex 插件已启用并完成认证:Logbook 依赖 Codex 当前提供的"结构化图像提取契约"(structured image-extraction contract)。认证方式:
openclaw models auth login --provider openai,其他认证路径见 Codex harness 文档。 - 一个可用的默认 agent 模型:视觉通道产出观察之后,卡片合成、站会摘要与当日问答都由默认 agent 模型完成。
快速开始
启用 Codex 与 Logbook 两个插件:
openclaw plugins enable codex openclaw plugins enable logbook为了让启动行为确定,建议在配置中显式指定视觉模型:
{ plugins: { entries: { codex: { enabled: true, }, logbook: { enabled: true, config: { visionModel: "codex/gpt-5.6-sol", }, }, }, }, }如果配置了plugins.allow白名单,必须同时包含codex与logbook。修改插件配置后重启 Gateway,然后检查注册与节点状态:
openclaw gateway restart openclaw plugins inspect logbook --runtime --json openclaw nodes status --connected openclaw nodes describe --node <idOrNameOrIp> openclaw dashboard节点描述中必须能看到screen.snapshot或logbook.snapshot。headless 节点只有在插件激活后才会通告logbook.snapshot;若命令缺失,参考 节点故障排查。插件管理命令的完整语义见 管理插件文档。
Control UI 中的Logbook 标签页只在"插件已启用 + Control UI 会话拥有operator.write权限"时出现。状态行应显示Capturing且无错误。当分析窗口关闭后会出现时间线卡片;也可以在有活动被捕获后点击Analyze now立即出卡片。
工作原理:四阶段流水线
Logbook 的核心是 extensions/logbook/src/service.ts 中的LogbookService后台服务,它同时驱动三个定时器:抓图循环(间隔由captureIntervalSeconds决定)、分析循环(固定每 60 秒 tick 一次,见常量ANALYSIS_TICK_MS)、清理循环(每小时一次,PRUNE_TICK_MS)。整体分为四个阶段:
1. Capture(抓取)
每隔captureIntervalSeconds(默认 30 秒),服务通过runtime.nodes.invoke调用所选节点的抓图命令,参数包括screenIndex、maxWidth、quality: 0.6与format: "jpeg"(JPEG_QUALITY常量),超时 30 秒,然后落盘一张缩放后的 JPEG 帧。
两个关键实现细节:
- 空闲帧判定:对帧内容计算 SHA-256(
contentHash),若与上一帧哈希相同,则标记为idle并排除出分析批次——连续相同画面视为用户空闲或离开。源码见 service.ts 中captureTick的实现与 store.ts 的insertFrame。 - 节点选择与轮换:抓图命令按优先级排序,
screen.snapshot(应用节点)优先于logbook.snapshot(headless 节点,因为logbook.snapshot只在 macOS 上真正抓图)。未固定nodeId时,若当前节点抓图失败,会轮换到其他合格节点;失败的节点会被放入failedNodeIds集合暂时跳过,直到所有候选都失败一次才整体重试,使瞬时故障能自愈。
2. Observe(观察)
一旦分析窗口(默认 15 分钟)到期,插件会从该窗口的活跃帧中均匀采样最多 16 帧(常量MAX_FRAMES_PER_CALL = 16),连同各自抓拍时间一并交给视觉模型,模型返回带时间戳的活动观察,例如:
VS Code: editing store.ts, fixing a type error
窗口关闭有三种触发条件:目标时长到期、抓图间隔超过两分钟(视为捕获缺口,BATCH_MAX_GAP_MS = 2 * 60 * 1000)、或到达本地午夜——批次永远不会跨越本地午夜,因为所有下游时钟(观察、卡片、day key)都按单一日期解析。窗口划分与采样逻辑位于 extensions/logbook/src/analyze.ts 的selectBatchFrames与sampleFrames。
3. Synthesize(合成)
观察结果连同最近 45 分钟内的既有卡片(CARD_LOOKBACK_MS = 45 * 60 * 1000)一起交给默认 agent 模型,修订为时间线卡片。每张卡片 10–60 分钟,包含标题、摘要、类别、主应用与简短的分心片段(distraction)。这里有两个防止"模型胡说破坏时间线"的机制:
- 覆盖校验:
validateCardCoverage在替换窗口之前校验新草稿必须覆盖"既有卡片时间范围 + 新批次时间范围"的并集,否则触发一次带校验错误的修复往返(buildCardsCorrectionPrompt),而不是静默丢弃旧卡片。卡片间不允许超过 1 分钟的重叠(超出则报错,亚分钟重叠则直接裁剪)。 - 卡片键帧:每张卡片会选取时间中点最接近的帧作为
keyframeId,用于时间线上的快照预览。
4. Prune(清理)
超过retentionDays(默认 14 天)的帧会被删除——帧文件与数据库行一起清理,keyframe_id外键使用ON DELETE SET NULL,避免删帧后卡片指向不存在的行。卡片、观察与缓存的站会摘要会保留。相关实现见 store.ts 的pruneFrames。
模型与数据流
Logbook 使用两条相互独立的模型路由:
| 阶段 | 发送的数据 | 模型路由 |
|---|---|---|
| Observe(观察) | 最多 16 张采样 JPEG 帧及其抓拍时间 | visionModel,或兼容的借用的tools.mediaCodex 条目 |
| Synthesize(合成卡片) | 带时间戳的观察 + 近期时间线卡片 | 插件 LLM 运行时中的默认 agent 模型 |
| Generate standup(站会) | 所选日与前一日的卡片 | 默认 agent 模型 |
| Ask your day(当日问答) | 问题 + 所选日卡片 + 近期观察 | 默认 agent 模型 |
完整的 SQLite 数据库不会发送给任何模型。原始截图只进入观察阶段;卡片合成、站会与问答收到的都是派生文本。代码佐证:service.ts 的runBatch使用runtime.mediaUnderstanding.extractStructuredWithModel(观察阶段,带logbook.observationsJSON Schema 与 180 秒超时),reviseCards、standup、ask则使用runtime.llm.complete(purpose 分别为logbook.cards、logbook.standup、logbook.ask)。
配置详解
所有 Logbook 配置键都可选;数值会被四舍五入取整并夹紧到支持范围。完整的配置解析实现在 extensions/logbook/src/config.ts 的resolveLogbookConfig。
{ plugins: { entries: { codex: { enabled: true, }, logbook: { enabled: true, config: { captureEnabled: true, captureIntervalSeconds: 30, analysisIntervalMinutes: 15, nodeId: "my-mac", screenIndex: 0, maxWidth: 1440, visionModel: "codex/gpt-5.6-sol", retentionDays: 14, }, }, }, }, }各配置项的行为、默认值与合法范围(与 openclaw.plugin.json 的configSchema一致):
| 键 | 默认值 | 范围/取值 | 行为 |
|---|---|---|---|
captureEnabled | true | boolean | 新快照的持久总开关;设为false时时间线仍可查看 |
captureIntervalSeconds | 30 | 5–600 | 两次抓取尝试之间的延迟 |
analysisIntervalMinutes | 15 | 3–120 | 目标观察窗口;缺口与午夜可提前关闭窗口 |
nodeId | 未设置 | 节点 id 或显示名 | 将抓取固定到某个已连接节点;匹配不区分大小写 |
screenIndex | 0 | 0–16 | 从 0 开始的显示器索引 |
maxWidth | 1440 | 480–3840 | 抓取的尺寸上限;headless macOS 将其应用于最大边 |
visionModel | 未设置 | provider/model | 显式结构化视觉路由;格式错误的引用会暂停分析,不支持的 provider 会使整批失败 |
retentionDays | 14 | 1–365 | 删除过期帧;卡片、观察与站会保留 |
关于nodeId的解析顺序,源码显示:未配置时,优先选择暴露screen.snapshot的已连接应用节点,回退到暴露logbook.snapshot的 headless 节点;未固定节点时,失败的节点会轮换到其他合格节点之后。
需要特别注意:Control UI 上的暂停开关是会话级的,Gateway 重启后即复位;需要持久停止请使用captureEnabled: false。
视觉模型的选择顺序
Logbook 解析观察模型(observation model)的顺序如下(实现见 service.ts 的resolveVisionModel):
plugins.entries.logbook.config.visionModel(显式配置,解析provider/model引用,model 自身可含斜杠,见parseModelRef)。tools.media.models下第一个具备图像能力的 Codex 条目(要求type !== "cli"、provider 为codex、含 image 能力),作为借用默认值,同时携带 profile 凭据字段。
其他媒体 provider 会被跳过,因为它们目前不提供 Logbook 所需的结构化提取契约。若设置tools.media.image.enabled: false,则禁用借用的媒体默认值,但显式配置的 LogbookvisionModel依然生效。
没有可用视觉模型时,分析不会报错而是暂停:已抓取的帧保持未分批、批次保持 pending,模型配置好之后可以继续分析(日志每 10 分钟提示一次MODEL_MISSING_MESSAGE)。
Control UI 标签页
启用后,Logbook 标签页提供以下能力:
- Timeline(时间线):按活动展开的卡片,带类别颜色、主应用、分心片段徽标与快照关键帧。
- Day at a glance(一日概览):专注比例、类别分布、主要应用排行(由 store.ts 的
timelineForDay统计得出:trackedMs、distractionMs、按类别与应用聚合的耗时)。 - Daily standup(每日站会):把昨天加上今天变成一段可直接粘贴的更新文本。站会提示词要求输出
## Done、## Today、## Blockers三个小节且 150 词以内,见 prompts.ts 的buildStandupPrompt。 - Ask your day(问一问今天):用自然语言基于已追踪时间线提问(例如"我什么时候审查了 gateway 的 PR?"),回答仅依据时间线卡片与观察证据,证据不足会直说,见
buildAskPrompt。 - Analyze now(立即分析):不等分析间隔,立即关闭当前捕获窗口触发分析。
Gateway RPC 方法
Logbook 在 extensions/logbook/index.ts 中注册了以下 Gateway 方法:
| 方法 | 参数 | 权限范围 | 结果 |
|---|---|---|---|
logbook.status | 无 | operator.read | 抓取、分析、模型、节点、Gateway 日与时区状态 |
logbook.days | 无 | operator.read | 有时间线卡片计数的日与卡片时间边界 |
logbook.timeline | { day?: "YYYY-MM-DD" } | operator.read | 派生卡片与日统计;默认 Gateway 当前日 |
logbook.frames | { startMs, endMs } | operator.write | 指定 epoch 毫秒范围内的帧元数据 |
logbook.frame | { frameId } | operator.write | 单张原始 JPEG 帧的 base64 |
logbook.standup | { day?, refresh? } | operator.write | 某日的缓存或重新生成的站会文本 |
logbook.ask | { day?, question } | operator.write | 某日基于时间线的回答 |
logbook.capture.set | { paused } | operator.write | 会话级暂停状态与更新后的状态 |
logbook.analyze.now | 无 | operator.write | 启动待处理分析,或返回无法启动的原因 |
权限设计的关键点:只读方法只返回运行状态或派生文本;原始截图像素、模型消耗行为与运行时变更都需要operator.write。Control UI 标签页本身也需要operator.write,因为它暴露了这些操作和原始帧预览;只读客户端仍可直接调用派生文本方法(status、days、timeline)。另外logbook.status被标记为profileAccess: "independent"——服务级健康检查不会读取或修改任何用户的持久 profile/会话状态。
隐私说明
屏幕快照可能包含屏幕上的一切内容,包括机密信息,因此 Logbook 的隐私设计贯穿整个链路:
- 帧不出机器(除作为采样输入发送给配置的观察模型外);帧文件、时间线数据库与临时抓取均以属主专属权限写入(目录
0o700、文件0o600,见 store.ts 与 node-host.ts)。 - 观察、近期卡片与问题在卡片合成、站会生成或问答时可能通过默认 agent 模型离开机器,两条模型路由都应套用对应 provider 的数据处理政策。
- 需要完全本地管线时,结构化观察模型与默认 agent 模型都使用本地路由。
- 屏幕抓取的"总开关":在
gateway.nodes.commands.deny中加入screen.snapshot即可同时阻断应用节点的抓图与 Logbook 自身的logbook.snapshot命令——这是代码里显式实现的"kill switch"(见 index.ts 的节点调用策略:SCREEN_CAPTURE_DENIED)。 tools.media.image.enabled: false会停止 Logbook 借用媒体图像模型做分析,此后只有插件配置里显式的visionModel生效。
故障排查
Logbook 标签页不出现
依次检查三道门:
openclaw plugins list --enabled中包含logbook;- 插件或白名单变更后 Gateway 已重启;
- Control UI 连接拥有
operator.write——只读会话不会收到交互式标签页描述符(标签页注册时requiredScopes: ["operator.write"])。
如果设置了plugins.allow,推荐配置下必须同时包含logbook与codex。
抓取报错
openclaw nodes status --connected openclaw nodes describe --node <idOrNameOrIp> openclaw logs --follow排查顺序:
- 确认节点暴露
screen.snapshot或logbook.snapshot; - 在被抓取的 Mac 上授予"屏幕录制"权限;
- 若配置了
nodeId,确认与节点 id 或显示名一致(匹配不区分大小写); - 检查
gateway.nodes.commands.deny中没有screen.snapshot。
健壮性机制(源码可见):连续失败 3 次(CAPTURE_FAILURE_THRESHOLD)后,Logbook 会退避 10 个抓取 tick再重试(CAPTURE_FAILURE_PAUSE_TICKS);未固定节点时还可以轮换到另一个合格节点。node-host 侧的screencapture子进程有独立的 25 秒中止信号,确保在node.invoke的 30 秒外层超时前退出,相关行为由 node-host.test.ts 的假定时器测试覆盖。
抓取成功但不出卡片
- 状态为Model missing意味着没有找到兼容的结构化视觉路由:启用并认证 Codex 插件,或设置有效的显式
visionModel。模型缺失期间帧保持 pending,修复配置后仍可分析(分析 tick 会暂停而不是把帧判为失败,避免永久搁置)。 - 等待
analysisIntervalMinutes到期,或在活动被抓取后选择Analyze now。 - 连续相同帧是空闲证据,不会进入分析批次——测试前先改变屏幕内容。
- 若最近一批显示错误,修复模型或认证问题后选择Analyze now。失败批次只在显式操作下重试,以避免对持续失败的批次反复消耗模型费用(
analyzeNow中store.resetErrorBatches()的设计意图)。
实现验证:测试覆盖
仓库为 Logbook 提供了较为完整的测试矩阵,可作为理解行为的参考:
- analyze.test.ts:覆盖观察段解析与夹紧、12 小时制时钟解析、无效时间拒绝、卡片 JSON 解析、重叠校验、覆盖校验、窗口切分与帧采样等纯逻辑。
- node-host.test.ts:覆盖 macOS 抓图子进程的截止时间行为。
- service-lifecycle.test.ts 与 service.test.ts:覆盖服务的生命周期与抓取/分析逻辑。
- card-reads.test.ts 与 observation-reads.test.ts:覆盖时间线与观察的读取路径。
相关文档
- Logbook 插件完整文档
- Logbook 插件参考页(自动生成)
- 管理插件
- Codex harness
- 媒体理解
- Nodes 节点
- 节点故障排查
- Control UI
【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考