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