fix: 消耗任务 clamp2 改守恒口径,消除余额快照滞后超烧风险

- b0_est = 拉包时刻 余额+usage (= B0+L,与 v6 闸门同构)
- clamp2: plan ≤ b0_est − SMALL_BUFFER − usage_now; 停止条件 2 改
  usage ≥ b0_est − SMALL_BUFFER,每轮实时读共享 key,真实用户消耗
  结构性计入,两方合计超烧杜绝(残余风险收敛为 §7.5 L 同款)
- 数字用例验证: L=0 撞墙剩 SMALL_BUFFER(旧方案执行中用户耗 100k 超扣 100k)
- docs: §8 排障 4/§9 条目翻转为已实施;新增视觉图片 reserve 估算
  口径校准待确认项(LiteLLM 85/765 OpenAI 口径 vs 火山未公开公式)
This commit is contained in:
vibe-code
2026-08-13 08:31:37 +00:00
parent 660efdfbeb
commit f15b64e31f
3 changed files with 41 additions and 24 deletions
+19 -11
View File
@@ -8,7 +8,7 @@
# - 直连 Ark API(Bearer token,绕过 LiteLLM 限额,避免消耗任务自杀)
# - 消耗量手动 INCR 进 daily_usage(与 LiteLLM 回调同 key):
# ① 算准采集上限缺口,② 空窗期限额能正确拦截真实用户(防扣费)
# - 三条停止条件:daily_usage ≥ 2M / 余额快照 − 已烧 ≤ 0 / 已烧 ≥ plan
# - 三条停止条件:daily_usage ≥ 2M / 总用量 ≥ 守恒墙(b0_est−SMALL_BUFFER,与 v6 闸门同构) / 已烧 ≥ plan
#
# 手动运行:
# python volc_consume.py --dry-run # 只算计划不消耗
@@ -429,8 +429,9 @@ def run_consume_model(model, source_groups, order, packages=None, dry_run=False)
对单个监控模型执行"洗过期包"消耗。
目标 = Σ窗口内包计划(均分×1.1/冲刺),clamp:
- 采集上限:plan ≤ CONSUME_DAILY_CAP − 当日已消耗
- 防扣费:plan ≤ 余额快照 − SMALL_BUFFER
停止条件(每轮检查):daily_usage ≥ 2M / 余额快照−已烧 ≤ 0 / 已烧 ≥ plan
- 防扣费:plan ≤ b0_est − SMALL_BUFFER − 当日已消耗(b0_est = 拉包时刻 余额+usage,
守恒口径与 v6 闸门同构,见 docs/volc-quota-notes.md §9)
停止条件(每轮检查):daily_usage ≥ 2M / 总用量 ≥ b0_est − SMALL_BUFFER / 已烧 ≥ plan
:param packages: 复用 run_consume_all 的一次拉包结果;None 时自行拉取
"""
if packages is None:
@@ -451,8 +452,11 @@ def run_consume_model(model, source_groups, order, packages=None, dry_run=False)
usage_now = _current_daily_usage(model)
# clamp 1: 采集上限(超出部分不返还,白烧)
plan = min(plan, CONSUME_DAILY_CAP - usage_now)
# clamp 2: 余额快照 − SMALL_BUFFER(脚本自身不烧穿余额,防扣费)
plan = min(plan, max(0, balance - vls.SMALL_BUFFER))
# clamp 2: 守恒墙(与 v6 闸门同构,见 docs/volc-quota-notes.md §7.5/§9)
# b0_est = 拉包时刻 余额快照 + usage = B0 + L(L = 滞后窗口未结算消耗);
# 有效墙 min(2M, b0_est − SMALL_BUFFER),usage_now 实时含真实用户 → 两方合计结构性消除
b0_est = balance + usage_now
plan = min(plan, max(0, b0_est - vls.SMALL_BUFFER - usage_now))
plan = int(max(0, plan))
if plan < CONSUME_MIN_PLAN:
@@ -460,18 +464,19 @@ def run_consume_model(model, source_groups, order, packages=None, dry_run=False)
return
vls.log(
f"▶️ [{model}] 目标消耗 {plan:,} | 余额 {balance:,} | 当日已用 {usage_now:.0f}"
f"▶️ [{model}] 目标消耗 {plan:,} | 守恒墙 {int(b0_est - vls.SMALL_BUFFER):,} | 当日已用 {usage_now:.0f}"
)
if dry_run:
vls.log(f"🔍 [dry-run] 仅计算,不发送请求")
return
_run_requests(model, plan, balance, source_groups, order)
_run_requests(model, plan, b0_est, source_groups, order)
def _run_requests(model, plan, balance_snapshot, source_groups, order):
def _run_requests(model, plan, b0_est, source_groups, order):
"""
循环发送消耗请求。速率:目标 1 小时内完成(23:20 触发,00:00 结算)。
b0_est: 拉包时刻守恒池 = balance + usage(= B0 + L),有效墙 = min(2M, b0_est − SMALL_BUFFER)。
"""
burned = 0
fail_count = 0
@@ -509,9 +514,12 @@ def _run_requests(model, plan, balance_snapshot, source_groups, order):
if _current_daily_usage(model) >= CONSUME_DAILY_CAP:
vls.log(f"🛑 [{model}] 当日采集已达上限 {CONSUME_DAILY_CAP:,},停止", level="WARNING")
break
# 停止条件 2: 余额快照耗尽(防扣费)
if (balance_snapshot - burned) <= 0:
vls.log(f"🛑 [{model}] 余额快照已耗尽,停止(防扣费)", level="WARNING")
# 停止条件 2: 守恒墙耗尽(防扣费;usage 实时含真实用户+自身,两方合计结构性杜绝)
if _current_daily_usage(model) >= b0_est - vls.SMALL_BUFFER:
vls.log(
f"🛑 [{model}] 守恒墙已耗尽(b0_est−SMALL_BUFFER),停止(防扣费)",
level="WARNING",
)
break
# 停止条件 3: 计划完成
if burned >= plan: