Files
memind/docs/h5-metering-gateway.md
john 229805a070 Improve WeChat MP replies and ship MindSpace/H5 production updates.
Add WeChat service account routing with sync acks, connectivity tests, and context isolation; document deploy runbooks; and bundle related MindSpace, voice, Plaza, and server gateway changes for production rollout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 23:06:43 +08:00

52 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# H5 计量计费网关设计
## 背景:当前计费的问题
当前计费内联在 `tkmind-proxy.mjs` 里,靠嗅探上游 SSE 的 `Finish` 帧扣费。100 服务实测发现三类问题:
1. **定价与成本脱钩,约 20× 超收**:默认 flat `2分/1k input` 对 DeepSeek 中继(goose `custom_tkmind_relay_deepseek`)严重偏贵。对账每条会话 H5 实扣 / goose 自报 `accumulated_cost × 7.2` 稳定落在 ~20×。换 provider 又会反向亏——单一硬编码 token 单价无法跟随模型。
2. **计量点分散**:只覆盖走 `tkmind-proxy` 的 H5 会话;`mindspace-agent-runner` 等其他 LLM 出口可能未计费。
3. **可靠性弱**`onFinish` 为 fire-and-forget`sse-billing.mjs``.catch(()=>{})`),扣费失败即漏计;`requestId` 全程传 `null`,无幂等键、无流水对账;读 `previous` 在事务外存在并发双扣竞态(`user-auth.mjs:943`)。
## 已落地的止血改动(本次)
`billing.mjs` 扩展 `H5_USE_BACKEND_COST` 成本路径,新增 `H5_MARGIN_MULTIPLIER`
```
最终扣费 = 上游 accumulated_cost(USD) 增量 × H5_USD_CNY_RATE × H5_MARGIN_MULTIPLIER
```
- 自动跟随 provider/模型,换模型不需重调 token 单价。
- 仅当上游回传 `accumulatedCost` 时生效;缺失则**回退**原 flat token 路径,不破坏现有计费。
- 生产启用:`.env``H5_USE_BACKEND_COST=1` + `H5_MARGIN_MULTIPLIER=<目标毛利>`
> ⚠️ 上线前需确认:一帧真实 SSE 的 `token_state` 是否带 `accumulated_cost`goose `sessions.db` 有该列,但要确认 SSE Finish 事件也序列化了它)。确认前 multiplier 改动是安全的(无 cost 即回退)。
## 目标架构:独立计量网关
把"计量 + 定价 + 扣费 + 对账"从 H5 代理里抽出,成为所有 LLM 出口的统一收口点。
```
H5 session ─┐
agent-runner ┤→ [计量网关] → upstream(goose/...) → usage+cost
cover-ai 等 ─┘ │
├─ 定价引擎(按 provider/模型,cost × margin
├─ 幂等扣费(requestId 去重 + 事务内读写钱包)
└─ ledger 流水(每次调用一条,可对账/审计/退款)
```
### 关键设计点
1. **统一收口**:所有发往 LLM 的调用都经网关,拿 provider 回传的真实 `usage` + `cost`,而非各出口各自实现。
2. **定价引擎按 provider 配置**`{ provider, model } → { 计价基准, marginMultiplier }`。DeepSeek 与未来的 Claude 成本差几十倍,必须差异化,不能一个 flat 单价打天下。优先用成本基准(cost × margin),无 cost 的 provider 才退回 token 单价表。
3. **幂等扣费**:每次调用带 `requestId`ledger 以 `requestId` 唯一约束,重放/重连不重复扣。当前 SSE 重连靠"accumulated 单调 → delta 0"兜底,脆弱,应换显式幂等键。
4. **事务内读写**:钱包扣减与计费状态读取在同一事务 + `FOR UPDATE`,消除并发双扣。
5. **ledger 流水表**`(request_id, user_id, session_id, provider, model, input_tokens, output_tokens, upstream_cost_usd, charged_cents, margin, created_at)`。支撑对账(H5 扣费 vs 上游成本)、用户账单明细、纠纷退款。
6. **失败可恢复**:扣费写库失败要可重试/补偿,不能像现在 fire-and-forget 直接吞掉。
### 落地阶段
- **P0(已做)**:成本模式 + margin,env 切换止血 20× 超收。
- **P1**:补 `requestId` 幂等 + 修事务竞态 + ledger 流水表(仍在 proxy 内,先把可靠性和对账补齐)。
- **P2**:抽出独立计量模块/服务,纳入 agent-runner 等其他出口,定价引擎按 provider 配置化。