reticlehq/reticle · 上手攻略

  • 仓库:reticlehq/reticle
  • 链接:https://github.com/reticlehq/reticle
  • 分类:agent / engineering(给 coding agent 用的应用内验证工具 · TypeScript)
  • 作者:spark
  • 更新:2026-11-04

一、它是什么

Reticle 是一套给 AI coding agent 用的"真跑一遍应用并给结论"的验证工具。

它要解决的问题,README 讲得极直接:

Your AI agent says "done." Reticle finds out if that is true. 你的 AI agent 写了代码,假设它работает,然后继续往下走。它从来不真的打开应用。 于是坏掉的 modal、静默的 500、以及"部署成功"背后的失败部署,全都会上线。你只能之后手动点出来。你现在成了自己 agent 的 QA。

机制上,Reticle 在你的应用里塞一个仅开发期生效的小 SDK,然后从应用内部(不是从浏览器外部)读取 DOM、网络请求、控制台、状态 store、React fiber。Agent 通过 MCP 调用它的 reticle_* 工具,look / act / observe / assert,最后拿到一个判定(verdict):

verified: "yes" | "no" | "unknown" | "no-fault"

判定不是截图,而是一份带证据的结论:触发了哪个请求、状态怎么变的、哪行控制台报错、以及要打开哪个 file:line。

关键设计: - 只有 yes 算通过。 无法判定的检查返回 unknown 并说明原因,绝不"安静地给绿灯"。 - 它读结构化事件,不读像素。 所以它能看到屏幕上看不出来的东西。 - Flow 可以无模型重放。 说一句 "save that as a flow",之后一次调用就能确定性地重验这条路径,今天的修复不会悄悄弄坏上周的功能。 - CI 门禁。 reticle gate 会让"改了已保存 flow 所涉代码、却没有新的通过记录"的变更失败。

生态:与 Claude Code、Cursor、Codex、Windsurf、VS Code、Gemini CLI 等一切会说 MCP 的 agent 配合。Web(React、Next.js、Vue、Svelte、Angular 等)与桌面(Electron、Tauri)。

版本与许可:npm 包 @reticlehq/server,最新 release v3.9.0(npm 上的 @reticlehq/server 3.6.0 是几周前的版本,GitHub release 更新更快——以 release tag 为准)。除 reticle-tauri crate 是 MIT 外,所有 npm 包均为 Apache-2.0。OpenSSF Scorecard 有徽章。最近提交 2026-11-03。

二、它解决什么问题

AI coding agent 的结构性乐观偏差:它是"生产变更"的机器,天生假设自己的改动生效了。Reticle 的定位是与之对立的验证环——"它去查清楚,而且随时准备回来告诉你不行"。

Reticle 的 README 有一张对照表,说清楚它和"从浏览器外部看"的工具(Playwright / DevTools / browser agent)的分工:

Bug 屏幕上看起来正常吗? Reticle 读到什么
Pay 按钮静默返回 500 是 与那次点击绑定的网络响应
徽章显示 "12",store 里是 0 是 你的应用状态
表单把请求发了两次 是 请求计数
"Deploy succeeded",部署其实失败了 是 store 里的真实状态
溜进来一个控制台报错 是 该操作之后的控制台
组件每秒重渲染 60 次 是 React commit 流

它不做什么(README 里 "What it never does" 明确列出): - 不在页面里执行任意 JavaScript(没有 "evaluate" 工具) - 除非你显式开启 production mode,SDK 不会进生产构建;且运行时守卫会拒绝在生产环境连接 - 不绕过客户端的权限确认提示 - 捕获到的密码、token、卡号在展示前会被替换成 [REDACTED]

三、快速安装

前置

  • Node 20.11+(brew install node 或 nodejs.org)。安装器会检查,版本不够会停下并给出修复提示。
  • 一个你能本地用 dev server 跑起来的 web 应用。
  • 第二步需要一个会说 MCP 的 coding agent。

第 0 步:装 CLI 并注册到 agent

curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh

Windows(PowerShell):

irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex

安装器做三件事:检查 Node ≥ 20.11 → npm install -g @reticlehq/server(把 reticle 命令放进 PATH)→ reticle setup install 给机器上找到的每一个 coding agent 注册 MCP server(Claude Code、Cursor、Windsurf、VS Code、Zed、Gemini CLI、Copilot CLI、OpenCode、Antigravity、Warp、Kiro、Amazon Q、Cline、Roo Code、Amp、Continue、Factory Droid)。

⚠️ 不想往 shell 里 pipe 脚本,用 npm 走:

npm install -g @reticlehq/server
reticle setup mcp

第 1 步:不装任何东西,先检查你的应用

这是最值得先跑的一步——不需要账号、不需要 coding agent、不改你项目里的任何文件:

cd path/to/your-app
npx @reticlehq/server

它会找到你的 dev server(没跑就帮你起,跑完会把它停掉),在 Reticle 浏览器里打开应用,检查页面能否加载、有无控制台报错、有无失败请求、同源链接能否打开(最多 8 个),然后打印判定:

Starting your dev server: npm run dev
Reticle is checking http://localhost:58473/. It installs nothing in your app.
 ✗ Console error on /broken: Uncaught Error: status page broke
 ✗ Failed request on /broken: GET http://localhost:58473/api/missing: HTTP 404
 - 1 of 2 link(s) opened with no fault.
verified: no — 2 fault(s) on http://localhost:58473/

成功判据:输出以 verified: yes 或 verified: no 结尾,然后给出下一步。no 也是一个完成的检查——每条 ✗ 指向一个具体故障。命令只有在 yes 时才退出码 0。

不在应用目录里跑?它会检查这台机器上跑着的那一个 dev server;有多个时它会列出来并不做选择。在 init 已经接好的目录里,同一条命令会改为启动 Reticle server(reticle serve)。

第 2 步:接入 coding agent

npx @reticlehq/server init

init 会:检测框架 → 装两个 dev 依赖(SDK + 构建插件,版本与 CLI 一致)→ 在构建配置里加插件 → 写 reticle-dev 模块 → 写 agent 规则文件 → 给找到的 agent 装 prompt hook → 启动 dev server 并等待应用连上。

先看计划再落地:

npx @reticlehq/server init --dry-run     # 只打印计划,不写任何文件
npx @reticlehq/server init --app apps/web  # monorepo 里指定应用
npx @reticlehq/server init --env KEY=VALUE  # 给应用启动所需的环境变量(可重复)
npx @reticlehq/server init --files-only     # 只写文件,不启动应用
npx @reticlehq/server init --json          # 输出单个 JSON 对象,给 agent 用
npx @reticlehq/server init --no-mcp         # 跳过 agent 注册和规则文件

检查接线状态:

npx @reticlehq/server status

第 3 步:重启 agent,跑第一条真实检查

# 已在项目里注册过 MCP 的,重启一次 coding agent 让它加载新工具

然后对 agent 说一句真实的用户旅程:

"Verify the sign-up flow with Reticle."

agent 会用 reticle_session 找到你的应用,用 reticle_act_and_wait 点击和输入,拿到带证据的判定。

不接 agent 的终端用法

npx @reticlehq/server verify http://localhost:5173 \
  --expect '{"kind":"element","query":{"role":"heading","name":"Welcome"},"state":"visible"}'

它只能验证当前页面的一个事实,不点流程(那是 agent 的活)。同样只有 yes 退出码 0。

⚠️ PowerShell 会改引号。Windows 上把 JSON 写进文件,用 --expect-file check.json 传。

给 agent 装 skill(可选)

npx skills add reticlehq/reticle --skill reticle

Claude Code 上还有插件路径:/plugin marketplace add reticlehq/reticle → /plugin install reticle@reticlehq → /reload-plugins(不用重启)。

四、核心用法

4.1 init 到底改了哪些文件

场景 dev 依赖 构建配置 dev 模块 项目配置
Vite(React / Vue / Svelte…) @reticlehq/react(Vue/Svelte 用 @reticlehq/browser)、@reticlehq/vite-plugin vite.config.ts: plugins: [reticle(), react()] src/reticle-dev.ts .reticle.json
Next.js(App Router) @reticlehq/react、@reticlehq/next next.config.ts: export default withReticle(nextConfig) app/reticle-dev.tsx .reticle.json

.reticle.json 内容形如 { "framework", "projectId", "port" }。projectId 让两个应用同时跑时不串;port 是本地 bridge 端口,只在 4400 被占用时才写入非默认值。

4.2 手工接线(不想用 init 自动改)

README 有完整的 "Wire everything by hand" 章节。核心是三步:装 SDK 与构建插件 → 在构建配置里加插件 → 写 dev 模块:

// src/reticle-dev.ts:由 reticle init 写入。你不 import 它,插件会加载它。
import { registerCapabilities, registerStore } from '@reticlehq/react';
import { useApp } from './store';

if (import.meta.env.DEV) {
  registerStore('app', useApp);   // 传 STORE 本身,不是 () => store.getState()
  registerCapabilities({
    testids: ['login-submit', 'cart-total'],   // 关键流程碰到的 data-testid
    signals: ['order:saved'],                    // 你用 reticle.signal() 发射的成功信号
    stores: ['app'],
  });
}

⚠️ registerStore 传 store 本身,不要传 () => store.getState()——store 形式才能看到每一次变化。这是最容易写错的一行。

reticle-dev 是仅开发期的:它检查 import.meta.env.DEV(Next.js 用 NODE_ENV === 'development'),生产构建里什么都不做。

4.3 断言语法

// agent 点击了 "Pay",该发生的事真的发生了吗?
reticle_assert({
  predicate: { kind: "allOf", predicates: [
    { kind: "net",     method: "POST", urlContains: "/api/order", status: 200 },
    { kind: "element", query: { role: "dialog", name: "Order confirmed" }, state: "visible" },
    { kind: "signal",  name: "order:saved" },          // 扣费确实提交了
    { kind: "console", level: "error", absent: true }  // ……而且什么都没报错
  ]}
})
// → { verified: "no",
//     because: "the declared consequence did not hold",
//     pass: false,
//     failureReason: "POST /api/order returned 500, expected 200",
//     source: "src/checkout/PayButton.tsx:42" }

4.4 常用交互话术

"我改了 checkout。用 Reticle 验证完再跟我说做完了。"
"页面看着对但底下有问题。用 Reticle 查查发生了什么。"
"用 Reticle 复现这个 bug,然后修复,再用同样的步骤验证修复。"
"用 Reticle 记录登录流程,之后每次改动都重新验证。"
"用 Reticle 走一遍主要路由,告诉我哪里坏了。"

4.5 CI 门禁

npx @reticlehq/server gate --since HEAD~1

gate 会找出你的改动影响到的已保存 flow,除非每个都有通过的产物,否则以非零码退出。README 强调了一句很到位的话:没有人能靠"推理自己 diff"来通过这个检查。

4.6 探测与模拟

explore 可以用日常语言描述一段旅程来驱动(--persona "一个注册的新用户")。每个角色拿到独立的浏览器上下文,多个 agent 可以并行驱动同一个应用。

4.7 HUD(页面内浮层)

页面右下角有一个 HUD,显示 agent 的每个动作、每个判定、保存下来的 flow,以及你钉在页面上的笔记。

五、典型适用场景

  1. coding agent 的自验证环:让 agent 在宣布"完成"前必须跑一遍真实应用,拿到 file:line 才算过。这是 Reticle 的主场景。
  2. CI 里防止回归:录好关键 flow 后用 gate 卡住"改了代码但没重验"的提交。
  3. 安全行为验证:各角色的访问控制是否成立(受限调用返回 403)、越权调用是否零次触发、密钥是否从没渲染到页面里、CSP 违规是否变成控制台错误。⚠️ 它与漏洞扫描器是互补关系:扫描器找洞,Reticle 验证你的应用行为。
  4. 可访问性与 UX:控件能否通过 role 和 accessible name 到达、对话框打开时焦点是否进入、Enter/Escape 是否触发动作。⚠️ 全量 WCAG 审计仍应配合 axe。
  5. 性能与监控:一次操作只发一个请求而不是五个;LCP、layout shift、长任务从页面里读;React 渲染次数。
  6. SEO 检查:页面 title、heading、每个链接的 href、重定向是否落到正确路由。
  7. Electron / Tauri 桌面应用:包括纯浏览器工具看不到的 IPC 边界。

六、坑与注意

坑 1:init 之后必须重启 dev server

现象:如果你的 dev server 之前就在跑,server 在 init 改动构建配置之前就读过它。 影响:不重启的话,它服务的是没有 Reticle 的应用——看起来 init 成功了,应用却连不上。 修复:init 完成后重启 dev server 并刷新页面。README 把它写成硬性步骤。

坑 2:coding agent 也必须重启一次

现象:MCP 工具是 agent 启动时加载的。 影响:不重启的 agent 看不到 reticle_* 工具,会说"我没有这个工具"或默默不用它。 修复:跑完安装脚本/agent 注册后重启 coding agent。(Claude Code 上用插件路径 + /reload-plugins 可以免重启。)

坑 3:prompt hook 会记录你的 prompt

现象:init 会给每个找到的 agent 装 prompt hook(如 .claude/settings.json、.cursor/hooks.json、.codex/hooks.json、.gemini/settings.json、.windsurf/settings.json、.github/hooks/reticle-prompt-capture.json、.factory/hooks.json),把每个 prompt 脱敏后存进 .reticle/request.json 和 .reticle/requests.jsonl。 影响:prompt 里可能带敏感上下文;链接了项目后,prompt 默认会随 run 一起上传。 修复:想留在本机就在 .reticle.json 里设 "shareRequests": false。用 --no-prompt-capture 可以完全跳过这个 hook;reticle hook uninstall 可以卸载。

坑 4:init 会往你的项目里塞不少东西

现象:init 改 dev 依赖、构建配置、.reticle.json、reticle-dev 文件、CLAUDE.md、AGENTS.md、RETICLE.md、.claude/commands/reticle.md。 影响:规则文件是追加(appended)而非覆盖——不会毁掉你已有内容,但在 CI diff 里会显得很吵。 修复:先跑 --dry-run 看完整计划;--files-only 只写文件;--no-mcp 跳过 agent 注册与规则文件。

坑 5:⚠️ 标记的安装项不要忽略

现象:init 打印的标记有 ✓ done、· already in place、– skipped by a flag、⚠ could not be done(会打印具体修复方法)、ℹ done but incomplete。 影响:跳过一条 ⚠ 或 ℹ,你会得到一个"绿灯"但其实什么也找不到的安装。 修复:把 ⚠ 和 ℹ 当作待办逐条清掉,再开始信任判定结果。

坑 6:版本必须对齐

现象:SDK 与构建插件按与 CLI 相同的版本安装。 影响:CLI 与 SDK 版本错配会导致连接不上或行为诡异。 修复:升级 CLI 时同步重跑 init / 重新装依赖。生产部署把 @reticlehq/server@<version> 显式 pin 住(MCP 配置里就是这样写的)。

坑 7:Reticle 看不见的东西(能力边界)

现象:README 的 "Capabilities and limits" 明确列出。 影响:对 IndexedDB、Web Workers、closed shadow root、跨域 iframe 里的问题,Reticle 给不出结论。 修复:靠 unknown 判定识别这种情况,别把 unknown 当 yes。另外它对"围绕单个动作的竞态"只是部分支持——能发现"请求没发完"和"请求发了两次",但不是完整的竞态分析器。

坑 8:unknown 不是通过

现象:判定有四种:yes、no、unknown(证据不足以定论)、no-fault(根本没声明要验什么)。 影响:把 unknown 当绿灯是最危险的误读。 修复:只有 yes 算通过。README 的原话是 "unknown means cannot tell, not pass"。CI 里要按这个语义配置。

坑 9:.reticle/ 里有敏感数据,别整个提交

现象:.reticle/ 下有 session journal,含请求体和页面文本。 影响:不小心 git add . 会把敏感的请求内容提交到仓库。 修复:Reticle 会写一个 .reticle/.gitignore 把它挡在 git 之外。应该提交的是 .reticle/flows/(保存的 flow),这样同事和 CI 能重放;其余 .reticle/ 保持本地。

坑 10:默认会发匿名使用统计

现象:默认发送匿名使用计数(跑了哪些命令和工具,带随机 id,不含你的应用内容、不含 IP 或位置)。 影响:合规审查时需要解释这个出站行为。 修复:reticle telemetry disable、RETICLE_TELEMETRY=0 或 DO_NOT_TRACK=1 可关闭,且会一并关掉其它可选出站调用。完整清单在 docs/telemetry.md。

坑 11:链接项目后数据会上传

现象:不链接项目时,应用数据(DOM、网络体、控制台、状态、源码)不出你的机器,判定完全本地做出,不需要账号。链接后(reticle connect 或 CI 里设 RETICLE_API_KEY),run / memory / flows 才会同步。 影响:以为"本地工具"其实在往云上发东西。 修复:链接后用 reticle config --runs/--memory/--flows on|off 精确控制同步哪些;CI 里要用云端功能才设 RETICLE_API_KEY。另外密钥字段值永不出机器,Harness 运行时平台只看得到步骤。

坑 12:平台侧功能有免费额度,但不是完全开源

现象:开源工具(SDK、本地 daemon、MCP 工具、HUD)是完整验证环,不要账号。但 Harness(用日常语言描述一个人和一个旅程,让 Reticle 驱动并验证每一步)在 Reticle 平台上决策;新账号有免费额度,绑定卡后是 14 天试用 + 500 credits。app.reticle.sh 是 dashboard,需要登录。 影响:以为"开源 = 全免费全本地",遇到额度不足会一头雾水。 修复:只做本地验证循环,完全不需要平台账号。需要 Harness 才去开。

坑 13:不能拿它替代跨浏览器测试

现象:被测试和驱动的浏览器是 Chromium(外加 Electron 与 Tauri 的 webview)。SDK 跑在你已经打开的 tab 里。 影响:Safari / Firefox 特有的问题它抓不到。 修复:Playwright 用在你不拥有的站点和多浏览器矩阵上;Reticle 用在你自己写的应用上。README 明确说"两者都用"。

坑 14:文件权限和密钥

现象:bridge 只监听 127.0.0.1:4400,配一个只属于 owner 的 token,存在 ~/.reticle/。 影响:这是安全边界,但别把该目录共享出去。 修复:不要把 ~/.reticle/ 放进任何共享目录或备份到公共位置。

七、与同类对比

维度 reticlehq/reticle Playwright Cypress 浏览器类 agent(browser-use 等)
观察位置 应用内部(DOM/网络/控制台/store/React fiber) 浏览器外部(像素 + DOM) 浏览器外部/半内部 浏览器外部(像素/截图)
输出形态 判定 yes/no/unknown + 证据 + file:line 截图 / trace / 断言结果 截图 / 断言结果 截图 + 自然语言描述
能否发现"屏幕正常但状态错" ✅ ❌ ❌ ❌
能否发现静默 500 ✅ 需显式断言 需显式断言 部分(靠截图猜)
是否执行任意 JS ❌ 无 evaluate 工具 ✅ ✅ ✅
无模型重放已录流程 ✅ flow 确定性重放 ✅ ✅ ❌ 每次都要模型
CI 门禁语义 ✅ gate ✅ ✅ ❌
跨浏览器 ❌ 仅 Chromium(+Electron/Tauri) ✅ 全矩阵 部分 ✅
像素级 diff ❌ ✅ ✅ 不适用
与 coding agent 集成 ✅ MCP 原生 需自写 MCP wrapper 需自写 ✅
生产构建含 SDK ❌ 默认不含 不适用 不适用 不适用

README 自己给的分工:"Playwright for sites you do not own, many browsers, real pixels. Reticle for the app you build, inside your agent's loop." 并且强调配合关系:像素 diff 用视觉测试工具,全量 WCAG 用 axe,找洞用安全扫描器。

八、基准数据(作者自测,需自行复现)

仓库内置了一个 88 bug 的注册表(86 个真实回归 + 2 个假阳性陷阱),对比 Reticle 与一个 Playwright 脚本,每个数字都来自提交进仓库的 harness,可复现:

node bench/pw-vs-reticle/run.mjs

README 报告的数字: - 整体:Reticle 85/88 vs Playwright 59/88 - 两者判定分歧的六个类别里:Reticle 抓到 28 个,Playwright 只抓到 2 个(14×) - 重跑四流程套件 100 次的累计 token:Reticle 128k vs Playwright MCP 12.1M - 单次重跑:Reticle 约 480 token(约 251× 便宜),且无模型、无 flake - 到判定耗时:2.6 秒的时间门控转场 176 ms 验证 vs 真实等待 2,978 ms;16 条 flow 批量 5.2 秒 vs 逐条 35.4 秒

⚠️ 诚实标注:这些是作者自己仓库里的自测,用的是自家 harness 和自家挑选的 bug 集合,不是第三方独立评测。对"Reticle 在我的项目上也这么神"这件事,本文的立场是——机制可信(读结构化事件而不是像素,逻辑上确实能发现更多),数字请自行在 bench/ 里复现后再引用,不要直接把 14× 当成通用结论。

九、一句话推荐

如果你的团队在用 AI coding agent 写前端/桌面应用、并且已经吃过"agent 说 done 其实没 work"的亏——Reticle 值得装:一条 npx @reticlehq/server 就能零安装给你一个判定,init 之后 agent 会拿到 file:line 级证据,gate 能把回归卡在 CI 里;但务必记住它只在 Chromium 系生效、默认进不了生产构建、.reticle/ 里的 session 数据别提交、以及最关键的一条——unknown 永远不等于 yes。