OpenSRE 产品分析指标体系:从匿名安装到留存与可靠性的完整度量子系统解析
【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre
OpenSRE 内置了一套自托管、面向产品决策的遥测与分析体系:客户端以尽力而为(best-effort)的非阻塞队列上报事件,服务端(webapp)基于 ClickHouse 视图与事件表产出北极星指标。本文以 infrastructure/analytics/METRICS.md 为骨架,结合仓库内的事件定义、传输实现与测试用例,系统讲解 OpenSRE 的产品分析指标口径、身份模型、事件管道与查询边界,帮助你在接入、查询或二次开发这套分析体系时,正确区分"个人用户粒度"与"网关组织粒度",并避免把匿名数据误当作可信用户数据。
一、指标体系的身份基础:三层身份模型
任何分析指标都建立在身份识别之上。METRICS.md 开篇就界定了三类身份来源,理解它们是正确查询全部指标的前提:
| 身份载体 | 来源 | 可解析的身份 | 说明 |
|---|---|---|---|
analytics_id(匿名安装 ID) | ~/.opensre/anonymous_id | 无(仅跨存储安装键) | 随机 UUID,用于安装去重与匿名获客归因 |
Personal bearer(osre_pat_...) | 个人 CLI 登录 | 服务端解析的 Clerk 用户 + 组织 | 可信的个人身份,用于个人类指标 |
Silo bearer(AGENT_USAGE_SECRET) | 托管组织 silo | 经过认证的组织断言,无 Clerk 用户 | 网关类指标的身份来源,chat actor ID 只是事件属性 |
关键约束:chat actor ID 永远只是事件属性,绝不能当作"人"来计数。网关(Slack / Telegram / Discord / Buzz)的 actor 不是 Clerk 用户,因此网关类指标必须与个人类指标严格分离统计。
从源码看,匿名 ID 的生成与持久化位于 provider.py,_get_or_create_anonymous_id()会尝试读取磁盘上的anonymous_id,不存在时以原子写 + 文件锁的方式创建,并记录持久化方式(disk/none)。安装检测事件install_detected使用稳定的install_detected:{anonymous_id}作为事件 ID,服务端据此去重安装(见 README.md 的 Ingest payload 一节),对应实现是provider.py中的_event_insert_id()。
二、事件管道:一份载荷如何从客户端到达 ClickHouse
指标全部由事件推导而来,因此先厘清事件的产生与传输:
- 入队:
Analytics.capture()将事件属性与基础属性合并后放入容量 128 的队列,后台守护线程逐条发送,occurred_at在进入本地队列时赋值,而非网络请求完成时(provider.py)。 - 寻址:目标端点按顺序解析——托管 silo 用
OPENSRE_WEBAPP_URL;个人 CLI 登录用保存的 app URL;否则用OPENSRE_APP_URL,兜底https://app.opensre.com(destination.py)。显式配置错误会失败关闭(fail closed),直接禁用远端投递而不是降级到其他来源。 - 签名:携带 bearer 的请求会对"时间戳 + 原始 JSON 字节"做 HMAC-SHA256 签名,通过
X-OpenSRE-Timestamp与X-OpenSRE-Signature头传递(destination.py)。 - 入站校验:服务端接受
POST {origin}/api/analytics/events,成功返回202 Accepted,按(source, event_id)去重,拒绝未知 schema 版本与事件名。
Ingest 载荷示例(源自 README.md):
{ "schema_version": 1, "event_id": "00ed1192-3433-4e46-856a-9a0992e8b212", "occurred_at": "2026-09-08T12:34:56.789+00:00", "source": "opensre_runtime", "anonymous_id": "4d892bf3-7204-4410-9f03-f84190f8a936", "event": "cli_invoked", "properties": { "entrypoint": "opensre", "command_family": "integrations" } }每个事件都会携带一组公共属性(README.md 的 Common properties 表),其中最影响指标口径的是:
execution_environment:local/ci/container/ci_container,由 analytics_runtime.py 通过 CI 环境变量(CI、GITHUB_ACTIONS、JENKINS_URL等)与容器标记(.dockerenv、cgroup 路径、KUBERNETES_SERVICE_HOST等)分类得到;is_ci:所有"人类"获客与留存指标都必须排除is_ci=true的事件;surface:cli/slack/telegram/discord/buzz,定义于 usage_context.py;session_id/user_id/organization_id:由 usage_context.py 的 ContextVar 绑定机制注入,organization_id在个人请求中是服务端解析结果,在 silo 中是 bearer 认证的运行期断言,在匿名请求中不可信。
运行时分类逻辑由 tests/analytics/test_analytics_runtime.py 覆盖验证,包括四种环境的排列组合(local / ci / container / ci_container)以及 k8s、ECS、Docker、Podman 的识别。
三、事件清单:指标推导的原料
所有可接受事件名由 events.py 中的Event枚举定义(另有内部身份控制事件$identify、$groupidentify由 webapp 翻译处理)。按域分组如下:
| 域 | 事件 | 指标用途 |
|---|---|---|
| 获客 | install_detected、account_authenticated、cli_invoked | 安装、登录转化、入口与命令族 |
| 运行健康 | user_id_load_failed、sentry_init_skipped | 身份持久化与遥测初始化失败 |
| 引导 | onboard_started、onboard_completed、onboard_failed | 引导漏斗 |
| 集成 | integration_setup_started、integration_setup_completed、integration_verified、integration_removed、integrations_listed | 集成采纳与配置/验证转化 |
| 交互动作 | terminal_actions_planned、terminal_actions_executed、terminal_turn_summarized | 终端动作成功数、LLM 回退 |
| Agent 循环 | react_turn_completed | 阶段、迭代数、cap 命中、停止原因、延迟 |
| AI 回合 | $ai_generation | 延迟、token、模型/提供商、结果与错误分类 |
| 网关 | gateway_turn_started、gateway_turn_completed、gateway_turn_failed | 回答率、意图、延迟桶 |
| 定时任务 | scheduled_task_started、scheduled_task_completed、scheduled_task_failed | 定时工作可靠性 |
| 更新 | update_started、update_completed、update_failed | 版本采纳 |
| 本地 Agent 安全 | agent_secret_detected、agent_killed、agent_kill_failed | 本地 Agent 监管 |
| 建议循环 / 引导演示 / 执行策略 | loop_suggestion_*、onboarding_demo_*、repl_execution_policy_decision | 功能暴露与策略决策 |
数据边界提醒:集成事件只是"设置漏斗"(setup funnel),不是集成清单的事实来源;当前已连接集成的清单保存在 webapp 数据库中,不能由事件推导。同理,user_id对网关回合而言是聊天平台 actor ID,永远不是 OpenSRE 账户 ID(README.md)。
四、核心指标定义(METRICS.md 全量继承)
METRICS.md 将指标划分为三大板块。以下口径全部直接继承自该文档,并补充了可验证的事件依据。
4.1 获客与激活(Acquisition and activation)
| 指标 | 事件与计算口径 |
|---|---|
| 安装数(Installations) | 具有install_detected事件的不同非 CIanalytics_id数量 |
| 安装到注册转化(Install-to-signup conversion) | 已关联到 Clerk 注册的安装数(该注册创建于install_detected与首次认证链接之间)÷ 安装总数 |
| 已认证安装(Authenticated installations) | 后续出现过任意 personal-bearer 事件的不同非 CI 安装数。account_authenticated是常规首个链接事件,但指标不依赖该单事件必然送达 |
| 引导转化(Onboarding conversion) | 完成引导的不同非 CI 安装数与引导失败的不同安装数,各自分别除以"已开始引导"的不同安装数 |
| 个人激活(Personal activation) | 服务端解析的用户,其关联安装完成引导后,又记录了非错误的$ai_generation |
| 网关激活(Gateway activation) | 拥有answered=true的已认证gateway_turn_completed的组织数。必须与个人激活分开统计,因为网关 actor 不是 Clerk 用户 |
其中"已认证安装"口径体现了系统的容错设计:链接事件(account_authenticated)可能因网络抖动丢失,因此任何 personal-bearer 事件都可作为关联信号(README.md 明确说明"Downstream linkage accepts any personal-bearer event"),服务端在 ClickHouse 中保存安装/用户关联,并在 PostHog 中将同一anonymous_id合并进用户。
4.2 使用与留存(Usage and retention)
| 指标 | 事件与计算口径 |
|---|---|
| 个人 DAU / WAU / MAU | 指定窗口内记录过 personal-bearercli_invoked或$ai_generation的不同服务端解析用户数 |
| 组织 DAU / WAU / MAU | 指定窗口内存在网关活动的不同已认证组织数,与个人用户分开报告 |
| D1 / D7 / D30 留存 | 已激活个人用户在目标日/窗口内再次出现符合条件的个人事件;组织留存是独立的网关指标 |
| 功能采纳(Feature adoption) | 个人用户按 CLI/AI 功能维度、组织按网关 surface 维度分别统计,绝不可混合两种身份粒度 |
| 集成采纳(Integration adoption) | 完成或验证设置的不同已认证组织数,按服务分组。个人事件携带服务端解析的组织;silo 事件携带 bearer 认证的运行期断言 |
4.3 可靠性与质量(Reliability and quality)
| 指标 | 事件与计算口径 |
|---|---|
| 网关回答率(Gateway answer rate) | answered=true的gateway_turn_completed÷ 全部已完成的网关回合 |
| 终端动作成功率(Terminal action success) | Σexecuted_success_count÷ Σexecuted_count |
| LLM 回退率(LLM fallback rate) | fallback_to_llm=true的terminal_turn_summarized÷ 全部已摘要回合 |
| Agent 可靠性 | 错误、取消、迭代数触顶的 ReAct 回合 ÷ 全部react_turn_completed事件 |
| 定时工作可靠性 | 按任务种类与提供商分组的已完成 vs 失败定时任务 |
| 延迟 | 网关、ReAct、AI 生成的 p50/p95,按 surface、模型、提供商切片 |
五、查询落地:视图边界与事件查询
METRICS.md 明确指出当前实现状态:ClickHouse 视图目前只实现了"安装漏斗"与"账户/会话头条"两类指标。其中analytics_core_metrics.daily_active_users是已认证的 webapp 活动,并非上文定义的个人产品 DAU;其余指标必须通过对analytics_product_events的查询推导。这是一个容易踩坑的口径差异:如果你直接读视图中的 DAU 字段来汇报"个人产品日活",会得到与定义不一致的数字。
正确的落地方式是:
- 安装漏斗 / 账户会话头条 → 使用现有 ClickHouse 视图;
- 个人 DAU/WAU/MAU、激活、留存、功能采纳 → 对
analytics_product_events按上文口径查询,窗口内用DISTINCT服务端解析用户,过滤is_ci=true; - 网关类指标 → 对已认证组织的网关事件单独查询,组织粒度与个人粒度互不混用;
- 集成清单 → 以 webapp 数据库事实为准,不以事件推导。
所有"人类"获客与留存看板都必须排除is_ci=true(README.md 补充:CI 数据可保留用于自动化使用报告)。
六、数据可信度边界与隐私行为
METRICS.md 用一段重要提醒收尾,这也是本体系最容易被误用的部分:
- 匿名安装数与引导数只是方向性指标(directional):开源的客户端无法对机器主人保守签名秘密,任何拥有客户端机器的人都可以修改开源客户端代码。因此匿名预登录事件的计数不可作为可信决策依据;
- 可信指标必须使用 personal-bearer 链接:以服务端验证的链接转化为决策依据;
- 绝不把网关 actor ID 当作 Clerk 用户 ID 使用。
配套的隐私与失败行为(README.md):
- 通过
OPENSRE_NO_TELEMETRY=1、OPENSRE_ANALYTICS_DISABLED=1、DO_NOT_TRACK=1任一均可退出;退出后连目标凭据都不会解析; - 投递失败绝不会让用户命令失败,失败记录写入
~/.opensre/analytics_errors.log(对应 provider.py 的_log_failure(),并在配置目录不可写时回退到临时目录); - 本地事件日志
analytics_events.txt默认开启(可用OPENSRE_ANALYTICS_LOG_EVENTS=0关闭),超过 1000 行自动轮转,便于开发者本地核对事件内容; - webapp 拒绝超大/未知载荷,对源 IP 与分析身份做限流,按事件 ID 去重,对认证流量拒绝过期、缺失或被篡改的签名;
$ai_generation是唯一被设计为包含用户内容的产品事件:密钥形状的值会被脱敏,但任意 incident 细节不会。必须将其视为机密,服务端强制执行保留策略,并避免放入大范围访问的产品看板。
七、给分析使用者的实践清单
最后,将全文要点收敛为一份可直接对照的口径清单:
- 先定身份粒度再写查询:个人指标(激活、DAU、留存、功能采纳)用服务端解析用户;网关指标(组织 DAU、回答率)用已认证组织;两者永不合并在同一查询或看板。
- 记住三个"不是":
daily_active_users视图不是个人产品 DAU;user_id不是 OpenSRE 账户 ID;集成清单不是事件可推导的事实。 - 过滤自动化流量:获客与留存指标排除
is_ci=true,按execution_environment切片观察自动化占比。 - 信任分级:匿名安装计数仅作方向参考,决策看板只依赖 personal-bearer 链接的服务端验证数据。
- 深化阅读:指标口径原文见 METRICS.md;事件契约、ingest 载荷与公共属性见 README.md;事件枚举见 events.py;传输与身份实现见 provider.py 与 destination.py;运行环境分类及测试见 analytics_runtime.py 与 tests/analytics/test_analytics_runtime.py。
【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考