creating-replay-vision-scanners

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Creating Replay Vision scanners

创建Replay Vision扫描器

A scanner is a standing LLM probe over session recordings. Once created and enabled, it runs on a Temporal schedule that sweeps every 5 minutes, applying its prompt to each new matching recording and recording the result as an observation (a queryable
$recording_observed
event). Each observation counts against a monthly org quota (a fixed number of observations per calendar month).
That schedule is exactly why creation needs a gut-check: a scanner with a permissive query and full sampling starts consuming quota automatically and can drain the whole month's budget within its first few sweeps. Creation itself does not check quota — that protection only kicks in at observation time, by which point the budget may already be gone.
扫描器是针对会话录制的常驻LLM探针。创建并启用后,它会按照每5分钟执行一次的Temporal调度运行,将其提示应用于每个新匹配的录制内容,并将结果记录为观测数据(可查询的
$recording_observed
事件)。每个观测数据都会消耗组织月度配额(每个日历月的固定观测数量)。
正是这种调度机制要求在创建前进行审慎检查:如果扫描器的查询条件过于宽松且采用全采样率,会自动开始消耗配额,甚至可能在几次扫描后就耗尽整个月的预算。创建操作本身不会检查配额——这种保护仅在生成观测数据时生效,届时预算可能已被耗尽。

Core principle: size before you ship

核心原则:先规划规模再创建

Never create an enabled scanner blind. Estimate its volume, check remaining quota, and — when the projected volume is a meaningful fraction of what's left — show the user the numbers and get confirmation before creating. This is the heart of the skill; the rest is supporting detail.
切勿盲目创建已启用的扫描器。先估算其观测规模,检查剩余配额,当预估规模占剩余配额的比例较高时,需向用户展示具体数值并获得确认后再创建。这是本技能的核心,其余内容均为辅助细节。

The flow

操作流程

Step 1: What should the scanner do?

步骤1:扫描器的功能定位

Pick a
scanner_type
and write its
scanner_config
. Every type needs a
prompt
; the rest is type-specific:
TypeWhat it produces
scanner_config
shape
monitor
Open-ended observation against a prompt (e.g. "flag rage clicks")
{"prompt": "..."}
classifier
Assigns tags from a fixed label set
{"prompt": "...", "tags": ["tag-a", "tag-b"]}
tags
needs ≥1 entry; optional
"multi_label": true
,
"allow_freeform_tags": false
scorer
Numeric score on a rubric
{"prompt": "...", "scale": {"min": 1, "max": 5, "label": "frustration"}}
min
<
max
;
label
optional
summarizer
Free-text summary; optional facet embeddings for search
{"prompt": "..."}
; optional
"length": "short" | "medium" | "long"
(default
"medium"
),
"emits_embeddings": false
scanner_type
is locked after creation — to change it you delete and recreate, so confirm the type is right up front, and get the
scanner_config
shape right (a wrong shape is a create error, not a silent default).
If the user's intent makes the type and prompt obvious, just proceed — don't interrogate them.
选择
scanner_type
并编写其
scanner_config
。每种类型都需要
prompt
;其余参数则因类型而异:
类型产出内容
scanner_config
结构
monitor
基于提示的开放式观测结果(例如“标记狂点行为”)
{"prompt": "..."}
classifier
从固定标签集中分配标签
{"prompt": "...", "tags": ["tag-a", "tag-b"]}
tags
至少包含1个条目;可选参数
"multi_label": true
"allow_freeform_tags": false
scorer
基于评分标准的数值评分
{"prompt": "...", "scale": {"min": 1, "max": 5, "label": "frustration"}}
min
<
max
label
为可选参数
summarizer
自由文本摘要;可选用于搜索的分面嵌入向量
{"prompt": "..."}
;可选参数
"length": "short" | "medium" | "long"
(默认值为
"medium"
)、
"emits_embeddings": false
scanner_type
在创建后不可修改——如需更改,需删除后重新创建,因此需提前确认类型是否正确,并确保
scanner_config
结构无误(结构错误会导致创建失败,而非自动使用默认值)。
如果用户的意图已明确类型和提示内容,可直接推进流程,无需反复询问。

Step 2: Which sessions?

步骤2:选择目标会话

The
query
is a
RecordingsQuery
shape that selects which recordings the scanner watches.
date_from
and
date_to
are ignored (the schedule controls time), so don't bother setting them. Narrow the query to the sessions that actually matter — by event, URL, person property, duration, etc. A narrow query is the single biggest lever on cost.
sampling_rate
(0..1, default 1.0) is a random downsample applied after the query matches. Lower it to trade coverage for budget.
query
是用于选择扫描器监控会话的
RecordingsQuery
结构。
date_from
date_to
参数会被忽略(时间范围由调度控制),因此无需设置。需将查询范围缩小至真正相关的会话——可通过事件、URL、用户属性、时长等维度筛选。缩小查询范围是控制成本最有效的手段。
sampling_rate
(取值范围0-1,默认值1.0)是在查询匹配后应用的随机降采样比例。降低该值可在覆盖范围和预算之间进行权衡。

Step 3: Size it — the gut-check (do not skip)

步骤3:规模规划——审慎检查(不可跳过)

Before creating, run both checks and reason about them together:
  1. Estimate volume — call
    vision-scanners-estimate-create
    with the proposed
    query
    +
    sampling_rate
    . It returns
    matched_sessions_in_window
    , the
    window_days
    measured, and
    estimated_observations_per_month
    .
  2. Check budget — call
    vision-quota-retrieve
    for
    remaining
    and
    exhausted
    against the org's monthly
    monthly_quota
    .
Then decide:
  • If
    estimated_observations_per_month
    comfortably fits within
    remaining
    , proceed.
  • If it's a large fraction of (or exceeds)
    remaining
    , stop and tell the user the concrete numbers — e.g. "This scanner is projected to produce ~X observations/month; you have Y of Z left this month." — and confirm before creating, or suggest tightening the
    query
    or lowering
    sampling_rate
    first.
  • If the org is already
    exhausted
    , say so — a new enabled scanner won't produce anything until the quota resets, and its observations will be silently skipped.
Confirmation here is a conversation step, not an API capability — surface the trade-off and let the user choose. When the projected volume is clearly small relative to the budget, you don't need to ask.
创建前,需同时执行以下两项检查并综合分析:
  1. 估算规模——调用
    vision-scanners-estimate-create
    接口,传入拟议的
    query
    sampling_rate
    。接口会返回
    matched_sessions_in_window
    (统计窗口内匹配的会话数)、
    window_days
    (统计天数)以及
    estimated_observations_per_month
    (月度预估观测数)。
  2. 检查预算——调用
    vision-quota-retrieve
    接口,获取组织月度
    monthly_quota
    remaining
    (剩余配额)和
    exhausted
    (是否已耗尽)状态。
随后根据结果决策:
  • 如果
    estimated_observations_per_month
    远小于
    remaining
    ,可直接推进创建。
  • 如果预估规模占
    remaining
    的比例较高(或超出),需暂停操作并告知用户具体数值——例如“该扫描器预计每月产生约X条观测数据;本月您的配额剩余Y/Z”——并在创建前获得用户确认,或建议先缩小
    query
    范围或降低
    sampling_rate
  • 如果组织配额已
    exhausted
    ,需告知用户——新启用的扫描器在配额重置前不会生成任何观测数据,其观测请求会被静默跳过。
此处的确认属于对话环节,而非API功能——需向用户说明权衡关系并由用户选择。当预估规模远小于预算时,无需询问确认。

Step 4: Create

步骤4:创建扫描器

Call
vision-scanners-create
. Minimal example:
json
{
  "name": "Rage click monitor",
  "scanner_type": "monitor",
  "scanner_config": { "prompt": "Flag sessions where the user repeatedly clicks the same element in frustration." },
  "query": { "kind": "RecordingsQuery", "events": [{ "id": "$rageclick", "type": "events" }] },
  "sampling_rate": 1.0,
  "model": "gemini-3-flash-preview",
  "enabled": true
}
name
must be unique within the team. Set
enabled: false
if the user wants to create it paused (no schedule, no quota consumption) and turn it on later.
调用
vision-scanners-create
接口。最简示例:
json
{
  "name": "Rage click monitor",
  "scanner_type": "monitor",
  "scanner_config": { "prompt": "Flag sessions where the user repeatedly clicks the same element in frustration." },
  "query": { "kind": "RecordingsQuery", "events": [{ "id": "$rageclick", "type": "events" }] },
  "sampling_rate": 1.0,
  "model": "gemini-3-flash-preview",
  "enabled": true
}
name
在团队内必须唯一。如果用户希望创建后暂停运行(无调度、不消耗配额),可设置
enabled: false
,之后再启用。

After creation

创建后操作

  • Show the scanner's PostHog URL from the response so the user can review it in the UI.
  • Results take a few minutes to appear (rasterizing the recording to video + the LLM call are slow). Inspect them with
    vision-scanners-observations-list
    for one scanner over time, or
    vision-observations-list
    (requires
    session_id
    ) for every scanner's findings on a single session. To dig into a recording, hand off to the
    investigating-replay
    skill.
  • 展示响应中的扫描器PostHog URL,方便用户在UI中查看。
  • 结果需数分钟后才会显示(将录制内容栅格化为视频+LLM调用的过程较慢)。可使用
    vision-scanners-observations-list
    查看单个扫描器的历史观测结果,或使用
    vision-observations-list
    (需传入
    session_id
    )查看所有扫描器对单个会话的检测结果。如需深入分析录制内容,可转交至
    investigating-replay
    技能处理。

Updating an existing scanner

更新现有扫描器

vision-scanners-update
is a partial update — send only changed fields. Re-run the Step 3 gut-check whenever you widen scope: a broader
query
or a higher
sampling_rate
raises the sweep volume just like a fresh broad scanner would. Toggling
enabled
, tweaking the prompt, or narrowing the query don't need a re-estimate. Editing config bumps
scanner_version
; past observations keep a snapshot of the old config.
vision-scanners-update
是增量更新接口——仅需传入修改的字段。每当扩大扫描范围时,需重新执行步骤3的审慎检查:更宽泛的
query
或更高的
sampling_rate
会像新创建的宽范围扫描器一样增加扫描规模。切换
enabled
状态、调整提示内容或缩小查询范围无需重新估算。修改配置会提升
scanner_version
;历史观测数据会保留旧配置的快照。

Gotchas

注意事项

  • One observation per (scanner, session). Re-running a scanner on a session it already observed — even a failed or ineligible one — is a no-op and won't produce a fresh scan.
  • Ineligible ≠ failed. Observations can land
    ineligible
    (e.g.
    too_short
    ,
    no_recording
    ) — a terminal non-error outcome. Check
    error_reason
    when triaging why a scanner produced nothing.
  • Provider/model are Google/Gemini only in the current version.
  • 每个(扫描器,会话)组合仅生成一条观测数据。即使扫描器已观测过某会话(包括观测失败或不符合条件的情况),再次运行也不会生成新的扫描结果。
  • 不符合条件≠失败。观测结果可能标记为
    ineligible
    (例如
    too_short
    no_recording
    )——这是终端非错误状态。排查扫描器无产出的原因时,需检查
    error_reason
  • 当前版本仅支持Google/Gemini作为服务商/模型。