# 比价 TOKEN 成本采集与补偿

## 部署前置

App Server 与 PriceBot 使用各自独立的 `.env`，但下面的值必须完全一致：

- `/opt/shaguabijia-app-server/.env`
- `/opt/pricebot-backend/.env`
- 配置项：`INTERNAL_API_SECRET`

不要把密钥原文写入日志、命令历史或 Git。修改后同时重启两个服务。

App Server 启动后会逐个探测 `PRICEBOT_INSTANCES` 的内部读取接口。鉴权不一致时会记录
`PriceBot LLM auth check rejected`，并跳过本轮补偿，避免对所有缺失记录重复发送失败请求。

## 数据链路

1. 当前客户端由 App Server 在 PriceBot 最终 `done` 帧到达时 harvest 比价记录。
2. harvest 成功后立即异步读取同一 `trace_id` 的 LLM 调用，冻结 Token、成本和单价快照。
3. 周期 worker 扫描近期 `success/failed` 且 `llm_cost_yuan IS NULL` 的记录进行补偿；
   为避免用现价伪造历史成本，只处理当前单价配置生效时间之后的记录。
4. 管理后台顶部“平均 TOKEN 成本”使用筛选范围内已冻结成本的数据库平均值。

## 上线验收（只读 SQL）

```sql
SELECT
  (created_at AT TIME ZONE 'Asia/Shanghai')::date AS day,
  count(*) AS records,
  count(llm_cost_yuan) AS cost_records,
  round(avg(llm_cost_yuan)::numeric, 6) AS avg_token_cost
FROM comparison_record
WHERE created_at >= now() - interval '3 days'
GROUP BY 1
ORDER BY 1 DESC;
```

新产生的正常终态比价记录应在短时间内写入 `input_tokens`、`output_tokens` 和
`llm_cost_yuan`。历史记录只有在 PriceBot 的对应 trace JSONL 仍保留时才能准确回填；
原始调用已经清理的记录不能用估算值冒充真实成本。
