新闻详情

新闻详情

首页 / 资讯中心 / 详情

Caveman Browse 实现解析:用 a11y 压缩器与 CCR 恢复句柄把 Chrome 可访问性树变成 Agent 可操作的紧凑视图

发布时间:2026/9/6 15:24:30来源:尧图网络
Caveman Browse 实现解析:用 a11y 压缩器与 CCR 恢复句柄把 Chrome 可访问性树变成 Agent 可操作的紧凑视图
Caveman Browse 实现解析用 a11y 压缩器与 CCR 恢复句柄把 Chrome 可访问性树变成 Agent 可操作的紧凑视图【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/cavemancaveman-browse 是 Caveman 仓库中面向 Agent 的本地浏览器交互组件它附着到真实 Chrome读取Accessibility.getFullAXTree原始载荷经引擎的 forced-onlya11y压缩器生成带uid句柄的紧凑树并通过 CCR压缩-恢复存储保留字节级原始数据以便精确恢复。读完本文你将理解它的四个 MCP 工具browser_snapshot/browser_act/browser_eval/browser_recover的完整参数语义、fail-closed 契约的源码实现、有界的 actionability 检测机制以及如何通过集成测试与基准验证其 token 效率。一、模块定位与目录结构browse/CLAUDE.md开篇即声明了该目录的治理边界Browse 产品的源头在独立仓库JuliusBrussee/caveman-browse本目录是消费方副本consumer copy仅在锁定集成、迁移/移除或显式跨仓库同步时才编辑而可访问性树压缩器因为 Engine 归本仓库所有保留在 engine/compressors/axtree.go。按 browse/CLAUDE.md 的 Layout 一节核心只有三个部分文件职责browse/session.goMCP 工具处理器、engine/CCR 集成、UID 目标缓存browse/cdp.go基于 chromedp 的 Mode-A 专用 Chrome 驱动以及有界 actionability 配方browse/cmd/caveman-browse/stdio MCP 二进制含直接 CLI 模式与 detached Chrome 管理两个关键的架构约束写在文档中并有源码佐证依赖隔离本包允许引入 CDP/网络/浏览器依赖而public/mcp不允许。这解释了为什么 browse 单独成包而不是并入通用 MCP 服务。计量口径Browse 产出的所有节省数一律标记为inferred推断值从不发出verified。这与仓库整体的诚实计量设计一致——token 数由本地计数器算出不是账单数据。二、四个 MCP 工具的参数契约browse/session.go 的BrowserTools定义了全部工具面参数约束与文档所述一一对应工具参数约束源码确认browser_snapshoturl仅允许http(s)、about:blank、有界的data:text/htmlwait毫秒数0..30000常量maxSnapshotWaitMS 30_000query焦点词上限maxQueryBytes 4 KiBbrowser_actaction枚举click\|type\|select\|scroll\|wait未知动作返回cave_unknown_actionuid最近一次快照的 UID查无目标返回cave_unknown_uidtext/option各上限 1 MiBmaxActionTextBytesbrowser_evalexpression在当前页面执行 JS上限 1 MiBbrowser_recoverrecovery_handle快照返回的恢复句柄长度 ≤ 512query可选用于在恢复时缩小范围URL 白名单由 session.go 的validateSnapshotArgs实现http/https必须有 hostabout仅放行about:blankdata仅放行data:text/html,或data:text/html;前缀任何file:、javascript:或特权 Chrome scheme 都会以cave_browser_url_denied拒绝。这落实了文档中Navigation deniesfile:、javascript:and privileged Chrome schemes的约束。错误码统一采用cave_snake_code命名cave_invalid_arguments、cave_browser_unavailable、cave_browser_action_failed、cave_unknown_handle等未知句柄/动作一律fail closed——session_test.go 中对每个错误码都有断言测试如cave_unknown_uid、cave_unknown_handle的检查。三、快照管线从原始 AX 树到 uid 紧凑视图snapshotTool的完整调用链session.go#L136-L197参数校验→ 非法参数返回cave_invalid_arguments驱动取数driver.Snapshot由 cdp.go 实现顺序执行DOM.enable→ 可选chromedp.Navigate(url)→ 可选Sleep(wait)→accessibility.GetFullAXTree()把节点数组 JSON 序列化后返回引擎压缩eng.Compress(raw, Options{Mode: ModeCompress, Type: TypeA11y, Query: query})。注意a11y是forced-only类型——axtree.go#L24-L28 的注释明确写道Detect never routes here; callers must forceOptions.Type \a11y\即自动内容嗅探永远不会路由到它必须由调用方强制指定失败闭合fail closed这是 CLAUDE.md 中最重要的契约文档原文强调uid 映射是browser_snapshot的契约不是压缩率的副作用。失败闭合的源码实现当引擎返回RecoveryHandle 树没有变小、或没有 CCR 存储可用snapshotTool的行为是session.go#L165-L177if res.RecoveryHandle { // ...The uid map is this tools contract, not a side effect of a // compression ratio, so we must NOT (a) dump the raw AX tree into uids // ... nor (b) wipe the prior pages uid cache. Fail closed... return mcp.ToolError(cave_browser_snapshot_uncompressed, snapshot did not compress to a uid view; raw tree withheld and prior uids retained) }对应文档的两条铁律绝不把原始 AX 树倒进uids——几百 KB 的原始 JSON比不用 Browse 更差绝不清空目标缓存——保留上一页的 uid让act行为保持可预测。此外还有一道计量闸门session.go#L191-L194若tokens_after tokens_beforeagent 可见结果不比原始 AX 小同样以cave_browser_snapshot_uncompressed拒绝并保留旧 uid。文档注明该契约的历史回归对应 issue #140——破坏这一点会重新打开 #140。精确 token 计量定点迭代快照 payload 的tokens_after与ratio由 finalizeSnapshotPayload 计算它最多迭代 8 轮把 payload 自身 JSON 序列化后的 token 数回填到tokens_after直到tokens_after和ratio两个字段收敛不动。这保证文档要求的两个等式成立tokens_afteragent 可见结果的精确成本含句柄、计量字段本身view_tokens序列化器输出的成本即紧凑树本身不含信封。payload 结构session.go#L125-L134为uids、recovery_handle、tokens_before、view_tokens、tokens_after、ratio、basis。四、a11y 压缩器UID 生成、焦点裁剪与行级保留压缩器位于 engine/compressors/axtree.go处理 CDP 返回的帧内节点数组。几个关键机制4.1 UID 生成规则axUIDBase 生成 UIDu 36 进制 backendDOMNodeId。注释解释了为什么不含 frame id——Phase-1 驱动只支持单个 CDP target把 base64 frame id 嵌进每个可见 uid 会多花几十个 token 而动作驱动根本不用它frame id 保留在恢复元数据中为未来的 OOPIF 拼接留口。并非所有节点都有 UID。shouldExposeAXUID 采用三层判断容器类角色webarea等不给可操作角色白名单button、checkbox、combobox、link、option、radio、textbox、tab等 15 种给其余角色先看focusable/clickable属性再对照一个明确的不给清单heading、statictext、table等未知自定义角色默认给 UID——注释指出漏掉句柄会把自定义控件悄悄变成只读文本。这与文档/README 中UID tokens reserved for actionable or unknown custom roles完全一致。4.2 焦点查询12 条上限 祖先 整行保留focusAXRecords 实现文档所述query keeps at most 12 highest-scoring task matches plus ancestors对每个记录把role name value 状态拼成小写串按查询词命中数打分从最高分向下降级填充至12 条上限matches 12源码 L409若已有节点覆盖全部查询词则最低分锁定为满分避免ORD-*这类公共碎片噪声每条匹配回溯保留其祖先链并把深度重排为紧凑缩进行级保留L430-L455匹配落在表格行/列表项单元格内时把整行兄弟单元格一并保留——注释说得很直白没有客户/金额单元格的订单 ID 读起来就是数据不可用。查询无命中时返回根节点加一条note no accessible match而不是空输出。4.3 输出格式紧凑缩进文本而非 JSON-linesrenderAXRecords 渲染为每行[uid] role name value {state}、两空格缩进的文本。角色还被压缩映射rootwebarea/webarea → page、statictext → text、labeltext → label。pruneDuplicateAXText还会剔除与语义父节点重复的StaticText副本InlineTextBox在droppableGeneric中直接整体丢弃它是 AX 快照中最大的重复来源。恢复元数据只暴露实际可见的 UIDvisibleUIDTargets 过滤uidMap只留下最终输出里出现过的条目——对应文档recovery metadata exposes only UIDs actually shown。五、有界 ActionabilityCDP 确认不等于应用层收敛文档两条 Gotcha——actionability 层刻意有界与CDP action acknowledgement is not application settlement——在 cdp.go 中落地为具体代码。5.1 settled:false 语义所有非wait动作成功后返回 dispatchedAction// CDP acknowledged dispatch, but asynchronous application state may still be // changing. Claiming settledtrue here made agents trust an unverified result. // A focused browser_snapshot is the cheap, evidence-bearing verification step. return ActionResult{OK: true, Settled: false, Note: dispatched; resnapshot to verify}即browser_act返回settled:false必须再做一次焦点快照作为状态证据。集成测试 cdp_integration_test.go 的TestCDPFullTokenEfficientReadActVerifyRecoverLoop完整验证了这个 read→act→verify→recover 循环对agent_checkout.html执行 type、select、点击折叠线以下按钮然后恢复字节级原始载荷。5.2 有界的可操作判定waitActionable 在 5 秒截止内轮询判定一个目标可点击需同时满足盒模型稳定dom.GetBoxModel两次采样x/y/w/h 全部漂移 0.5px先scrollIntoView({behavior:instant})居中可见getComputedStyle检查display/visibility/pointer-events/opacity且getBoundingClientRect宽高 0visible启用非disabled属性、非aria-disabledtrue、不处于[inert]子树enabled——TestCDPActionabilityRejectsDisabledButton专门验证禁用按钮必须被拒绝命中测试dom.GetNodeForLocation取到的后端节点 ID 必须与目标一致或用document.elementFromPoint兜底确认receivesEvents。文档明确声明其适用边界same-origin dashboards and predictable design-system controls, not arbitrary-open-web parityBENCHMARK.md 的 Claim boundary 一节同样注明 OOPIF、对话框、下载、任意站点操作ability 属于 Phase-1 之后的延期项。另外 callOnNodeRaw 的decodeBoolObject对 nil RemoteObject 显式 fail closed注释指出这修复过经 MCP panic 洞杀死整个进程的缺陷同样对应 issue #140。六、直接 CLI 模式detached Chrome 与原子状态文件除 stdio MCP 服务外cmd/caveman-browse/main.go 提供直接 CLI文档要求的独立进程共享一个 target由detached Chrome实现caveman-browse snapshot http://127.0.0.1:3000 caveman-browse snapshot http://127.0.0.1:3000 save settings # 带焦点查询 caveman-browse act uid click caveman-browse act uid type text caveman-browse recover handle [query] caveman-browse eval expression caveman-browse close # 必须真正终止 detached Chrome工作机制main.go首用启动directEndpointL202-L233先在127.0.0.1默认端口 9333 上探测/json/version是否健康不健康则以--headlessnew --remote-debugging-portport --user-data-dirprofile about:blank启动一个脱离当前进程的 Chrome跨平台分离实现见 detach_unix.go 与 detach_windows.go并释放 PID、把日志写入browse-chrome.log跨命令粘滞snapshot成功后把endpoint、target_id、全量 uid 目标表、owned标志写入CAVEMAN_HOME/browse-session.jsonact/eval/close通过loadDirectState重新附着同一 target——这正是separatesnapshot/act/evalprocesses can share a target的实现原子写入saveDirectState 走临时文件 →Chmod(0o600)→ 写 →Sync→Rename流程落实文档state writes stay atomic and mode 0600目录以0o700创建close 语义closeDirectBrowser对自有 Chrome 调用 CDPbrowser.Close()对应 CDPDriver.Shutdown区别于只释放上下文的普通Close并清理状态文件对外部CAVEMAN_BROWSE_CDP端点只删本地状态、不动对端。环境变量变量作用CAVEMAN_BROWSE_CDP复用外部 CDP 端点跳过自启 ChromeCAVEMAN_BROWSE_PORT直接模式的调试端口默认 9333越界即退出CAVEMAN_BROWSE_CHROMEChrome/Chromium 可执行路径缺省按 macOS/Linux/Windows 候选路径探测defaultChromePathCAVEMAN_BROWSE_HEADFUL1时以有头模式运行CAVEMAN_BROWSE_USER_DATA_DIR浏览器 profile 目录缺省为CAVEMAN_HOME/browse-profileCAVEMAN_BROWSE_EPHEMERAL1时 CCR 用内存存储而非 SQLiteCAVEMAN_CCR_DBCCR 数据库路径缺省CAVEMAN_HOME/ccr.dbCAVEMAN_HOME状态根目录缺省~/.caveman全新 HOME 必须能直接工作有专门集成测试覆盖CCR 存储默认落 SQLiteengine/ccr/store_sqlite.go恢复即eng.RetrieveQuery(handle, query)返回字节级原始 AX 载荷recoverTool。七、Site Isolation 与 iframe 叶子边界CLAUDE.md 最后一条 Gotcha 值得单独展开因为它是不要好心办坏事的典型一个iframe是叶子不是坏树。Accessibility.getFullAXTree一次只返回一个 frameiframe 节点的childId指向另一个 frame 响应里才存在的子文档。a11y压缩器把无法解析的childId当作叶子仍然策展 frame 可见节点。正因为如此CDP 驱动保持Chrome 默认的 Site Isolationsite-per-process——不要用禁用它来修跨源 iframe。两处源码相互印证axtree.go 的 validAXTree 末尾注释childId 在本载荷中解析不到不是坏树……把这种 childId 当作叶子边界walk 跳过未知 id而不是拒绝整棵树——多返回一个可用的 uid 映射是安全的拒绝压缩整个页面则不然遍历中byID[id]查不到的 child 直接被walk跳过L180-L183cdp.go#L58-L63 注释记录了历史曾经禁用 Site Isolation 来掩盖跨源 iframe 缺失子文档的问题压缩器修复后不再用一个安全边界去换它因此 allocator 只追加UserDataDir不改隔离标志。八、测试矩阵与基准数据8.1 测试分层文档给出的三层测试命令go test ./browse/...无外部依赖即可跑集成测试需真实浏览器go test ./browse/... # 无依赖单测工具校验、错误码、payload 计量 make test-browse # 解析已安装的 Playwright Chromium 或系统 Chrome # 跑 integration build tag 的 CDP 契约包 直接 CLI make test-browser # 额外包含 extension 测试 make test-e2e # 二者都包含集成测试cdp_integration_test.go//go:build integration与 BENCHMARK.md Integration gates 一节列出的验收面一致type/select/视口外自动滚动点击/动作后焦点验证/禁用控件拒绝/过期 UID 拒绝/字节级恢复/全新 HOME 启动/跨进程 CLI 再附着/显式 Chrome 关闭。CLI 侧的跨进程附着与关闭语义在 main_integration_test.go 中覆盖。8.2 基准诚实的赢与诚实的输BENCHMARK.md2026-08-10Chrome 151.0.7922.108锁定 Playwright 1.56.1Caveman 离线o200k_base计数器五轮取中位数给出可复现数据200 行运营大表语料 testdata/order_dashboard.html表示Tokens对比原始 AX对比 Playwright原始getFullAXTreeJSON398,494n/an/aPlaywrightariaSnapshot()15,704少 96.06%n/aCaveman 完整 agent 可见结果13,368少 96.65%少 14.88%Caveman 焦点结果queryORD-0173121少 99.97%小 129.8 倍小型结账表单agent_checkout.html——文档特意保留的输的样本表示Tokens对比原始 AX对比 Playwright原始 AX4,186n/an/aPlaywright ARIA 文本67少 98.40%n/aCaveman 完整结果157少 96.25%大 2.34 倍Caveman 焦点结果queryEmail Plan Save order111少 97.35%大 1.66 倍基准文档明确解释小页面上 Caveman 的恢复句柄、精确计数器、inferred诚实性标记和 UID 的开销高于裸 Playwright ARIA 文本不宣称无条件的 snapshot-only 胜利不对称性本身Caveman 侧带 MCP 信封/恢复/计量而 Playwright 侧只有文本反而有利于 Playwright 基线。所有数字均为单次快照的inferredtoken 计数不是供应商账单。复现命令BENCHMARK.md 原文CAVEMAN_BROWSE_CHROME/path/to/Chrome \ go test -tagsintegration -run TestCDPQueryScales|TestCDPFullTokenEfficient -count5 -v ./browsePlaywright 基线由 browse/scripts/playwright-aria-baseline.mjs 计数且 token 预算在测试中保持可执行文档要求keep token budgets executable in tests。九、小结Browse 的设计约束清单把 CLAUDE.md 的 Gotchas 与源码证据汇总这套实现可以用七条约束概括uid 映射是契约压缩不达标无恢复句柄或tokens_after tokens_before时 fail closed 为cave_browser_snapshot_uncompressed保留上一页 uid绝不倾倒原始树session.go#L165-L194有界操作ability同源自仪表盘 可预测设计系统控件判定链为盒模型稳定 → 可见 → 启用 → 命中测试cdp.go#L256-L292settled 语义CDP 分发确认 ≠ 应用收敛非 wait 动作恒settled:false需焦点快照取证cdp.go#L224-L229导航白名单仅http(s)/about:blank/有界data:text/htmlsession.go#L263-L279计量精确性tokens_after等于 agent 可见结果精确成本view_tokens等于序列化器输出成本靠定点迭代收敛session.go#L227-L244进程模型直接 CLI 的 Chrome 是 detached 的多命令共享 targetclose必须真正终止它状态写入原子且 0600main.go#L401-L437不拆安全边界保持 Chrome 默认 Site Isolationiframe 的跨帧childId在 a11y 压缩器中按叶子处理axtree.go#L136-L142。配合 browse/README.md构建方式go build ./browse/cmd/caveman-browse、stdio 运行方式、BSL 1.1 许可说明与 LICENSING.md本文覆盖的即当前仓库中browse/目录的全部技术事实一个把读浏览器变成低 token、可恢复、可验证操作的本地 MCP 组件其每一个设计决定都能在 session.go、cdp.go、cmd/caveman-browse/main.go 和 engine/compressors/axtree.go 中找到对应代码。【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

纳米机器人治疗动脉粥样硬化:靶向泡沫细胞与胆固醇酶缓释全链路解析 2026/9/6 15:57:36

纳米机器人治疗动脉粥样硬化:靶向泡沫细胞与胆固醇酶缓释全链路解析

简介:一份系统阐述动脉粥样硬化治疗纳米机器人设计方案的PDF文档,全书398页、53个大章节,聚焦泡沫细胞受体靶向配体与胆固醇溶解酶缓释两大技术路线。内容涵盖动脉粥样硬化病理机制、胆固醇逆转运通路、受体介导内吞、配体-受体动力学等分子基…

阅读更多 →
纳米机器人靶向泡沫细胞:动脉粥样硬化治疗新策略 2026/9/6 15:57:36

纳米机器人靶向泡沫细胞:动脉粥样硬化治疗新策略

简介:动脉粥样硬化治疗纳米机器人设计方案详解是一份398页的系统性技术资料,共分53个章节,覆盖病理机制、靶向配体设计与胆固醇溶解酶缓释系统开发等核心环节,适合生物医学工程、纳米药物递送及心血管疾病交叉领域的研究者与工程师…

阅读更多 →
supabase 仓库中的 Vitest 配置实践:vitest.config.ts 核心选项与多包测试体系详解 2026/9/6 15:57:35

supabase 仓库中的 Vitest 配置实践:vitest.config.ts 核心选项与多包测试体系详解

supabase 仓库中的 Vitest 配置实践:vitest.config.ts 核心选项与多包测试体系详解 【免费下载链接】supabase The Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications. 项目地址…

阅读更多 →
Ghost Shade 设计系统:新增组件的验收清单与实现规范(命名、cva 变体、Story 约定与 Token 纪律) 2026/9/6 15:57:35

Ghost Shade 设计系统:新增组件的验收清单与实现规范(命名、cva 变体、Story 约定与 Token 纪律)

Ghost Shade 设计系统:新增组件的验收清单与实现规范(命名、cva 变体、Story 约定与 Token 纪律) 【免费下载链接】Ghost Independent technology for modern publishing, memberships, subscriptions and newsletters. 项目地址: https://…

阅读更多 →
神经网络增强PRM:动态环境下路径规划的实时性解法 2026/9/6 15:57:35

神经网络增强PRM:动态环境下路径规划的实时性解法

简介:面向移动机器人实时避障路径规划的学术论文文件,适合机器人学、人工智能与控制工程领域的研究者、学生及工程师阅读。论文提出将概率路线图与神经网络相结合,通过扩展偏倚最小共识算法,在随机地图上实现动态环境下的无碰撞路…

阅读更多 →
MIT线性代数笔记:从矩阵分解到SVD,用几何视角建立知识框架 2026/9/6 15:54:35

MIT线性代数笔记:从矩阵分解到SVD,用几何视角建立知识框架

简介:这是一份基于MIT公开课整理的线性代数学习笔记,覆盖从方程组几何解释、矩阵消元、LU分解、四个基本子空间,到投影与最小二乘、Gram-Schmidt正交化、特征值与特征向量、SVD等核心专题,内容循序渐进,适合正在学习线…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞