---
url: /docs/agentbuff-stack/tool-usage-events.md
---
# 工具使用事件

当前阶段为 I11 的公开工具使用观测，默认关闭。它和 Cloudflare 的公共页访问统计、营销邮件同意、账号注册、任务执行及支付结算各自独立。

## 统计口径

| 状态 | 从哪里触发 | 能证明什么 |
| --- | --- | --- |
| 处理开始 | 用户点击处理，浏览器实际调用同步工具处理器 | 浏览器报告一次处理尝试，失败也可计入 |
| 处理成功 | 处理器返回可预览结果 | 浏览器报告这次处理成功 |
| 下载发起 | 有当前处理结果时点击下载，并实际调用下载链接 | 浏览器报告下载发起；不证明最终保存到磁盘 |

API 的响应来源固定为 `browser_reported`，数据库 `tool_observation` 也只存浏览器上报。它不是服务端运行日志、独立用户数、付费转化率或收入证据。公开请求即使具有正确来源和同意字段，也可能由自动程序构造；限流与严格校验不能证明处理真的发生在浏览器。当前没有收入归因、服务端任务统计、支付购买事件或统计管理面板，不能把这一阶段写成完整转化分析已完成。

打开页面、试用示例、编辑输入、复制、保存账号、恢复标签页里的输入都不触发这些事件。处理一次生成一个只存在于内存的随机 UUID；再次点击处理是新的尝试。一个尝试内的重复成功 / 下载上报只计一次，因而下载数是“发生过下载的处理次数”，不是下载按钮点击总数。重新加载页面后恢复的结果没有观测 ID；仅下载它不会补造一次处理记录。

## 配置与升级

在 `packages/core/website.ts` 中配置：

```ts
analytics: {
  provider: "none",
  toolEvents: {
    enabled: false,
    consentVersion: "2026-10-10",
    retentionDays: 30,
  },
  serverEvents: {
    enabled: false,
    consentVersion: "2026-10-10.2",
    retentionDays: 30,
  },
},
```

`provider` 只控制原有公共页 beacon。`toolEvents.enabled` 独立控制工具内的明确选择与第一方 API，不需要 Cloudflare 统计 token 或新的供应商密钥。`consentVersion` 必须非空且不超过 80 字符；变更用途或同意文案时更新版本，旧版本会重新出现未勾选选择。`retentionDays` 为 1—90 天。

启用前应用完整增量迁移至 `0017_striped_korath.sql`，再一起重建公共页与 API。该迁移只新增观测与短期限流表，不改旧 SQL、账号、任务或账本。现有站升级还需给自己的配置加入上述 `toolEvents` 字段。主预览继续保留 0012 且关闭此模块；独立验收数据库使用完整迁移。API 默认关闭时先返回 404，定时任务也不读取这两个表，因此不会要求主预览提前迁移。

## 明确同意与隐私

公开工具底部的选择默认不勾选。勾选后只记录之后发生的处理，不回填先前行为；拒绝、撤回、浏览器存储不可用及上报失败均不影响处理、预览或下载。英文是产品界面语言，本页为中文操作教程。

浏览器仅保存按站点 ID 和同意版本区分的 `yes` / `no` 选择，不保存运行 ID、输入、结果或用户追踪标识。存储不可用时选择仅在当前页面有效。用户可以取消勾选；另一个标签页撤回会通过存储变化同步到当前页面。撤回会中止当前请求并丢弃排队请求，重新勾选也不会复用撤回前的运行 ID。已经被服务器接收的匿名观测无法按账号或浏览器反查并撤销，按保留策略清理；请求到达服务器后再中止也不能保证撤回该次接收。

请求体只允许运行 UUID、固定工具 ID、同意版本、肯定同意、成功与下载状态。拒绝额外字段，不接收输入、结果、文件名、邮箱、账号 ID、页面 URL、客户端时间、任意事件名或购买金额。请求省略账号 Cookie，并设置不发送来源页面 URL；私有工作台没有新增统计脚本或自动账号营销同意。上报失败只显示简短提示，不显示服务端内部异常。

为限制公开端点，服务器按可信平台 IP 使用现有鉴权密钥计算每日轮换的 HMAC 摘要，最多接收每分钟 20 次合法报告；不存原始 IP，摘要也不与运行记录关联。平台没有 IP 信息时共享一个受限桶。该摘要不是无任何元数据的“完全匿名”，也不能用作用户留存统计。原有基础设施日志仍需由部署者按自己的隐私政策管理。

## 去重、失败与清理

`POST /api/tool-observations` 校验本站精确 `Origin`、JSON 类型、最多 1 KiB 请求体、已知工具与当前同意版本。一个 UUID 只允许同一工具与同一同意版本；并发请求在 PostgreSQL 事务中串行收敛成一行。成功 / 下载接收时间只首次写入，晚到的“只开始”报告不降级已成功状态。下载报告包含累计成功状态，即使第一次处理报告丢失，随后实际下载仍能补齐这次观测。

浏览器队列最多四个请求，每个请求最多等待四秒；不自动重试，不持久化待发内容。离线、拦截、超时、限流、离开页面或队列满都可能导致漏报。上报完成与处理结果互不等待，不能为了统计阻塞工具。记录时间是服务端接收时间，不是浏览器精确发生时间，也不是处理耗时。

已存在运行超过 24 小时后拒绝更新。默认保留 30 天，定时任务每批最多删除 500 行过期观测和 500 行超过一天未更新的限流桶；实际删除取决于任务执行和积压，不能承诺到点立即删除。关闭模块后同时停止自动清理；站主如需删除旧观测，应在已升级的目标库中明确执行清理或在保留窗口后完成清理再关闭。去重覆盖仍被保留的记录，不保证已删除 UUID 的永久去重；浏览器不会跨页面恢复或自动重放旧 UUID。

可在受授权的数据库管理环境按 UTC 接收日期查看汇总：

```sql
SELECT (created_at AT TIME ZONE 'UTC')::date AS received_day,
       tool_id,
       count(*) AS reported_attempts,
       count(succeeded_at) AS reported_successes,
       count(download_initiated_at) AS reported_download_runs
FROM tool_observation
GROUP BY received_day, tool_id
ORDER BY received_day DESC, tool_id;
```

此查询没有公开 HTTP 入口。统计清理失败会记录通用错误，且在原有文件 / 任务维护之后运行，不能阻塞任务恢复。实际任务、附件下载与积分包确认已另外接入[工作台服务端事件](./server-activity-events)，需账号独立同意；购买确认页读取共用服务端唯一键。订阅支付事件与真实外部验收仍按 I11 后续推进。

## 本地验收

定向测试覆盖默认关闭且表缺失、同意 / 来源 / 字段校验、并发去重、累计状态、不降级、旧运行、限流与清理；产品交互测试覆盖选择前零请求、失败处理、真实成功与下载、撤回丢弃、上报失败不阻塞及关闭后忽略旧选择。

独立真实 Worker / PostgreSQL 验收入口：

```sh
bun --env-file .env --env-file .env.local apps/api/local/validate-marketing.ts --tool-events
```

该入口复用已有受控本地验收器，创建并迁移自己持有的一次性数据库，真实邮件仍捕获，外部请求禁用，结束时删除数据库与运行资源；不升级主库、不修改默认配置。加 `--ui` 可检查独立英文工具页，完成一次同意后的文本处理与下载，再撤回；验收器会核对数据库接收记录。正常主预览没有同意控件是关闭状态的预期行为。
