From 729e5c7bc3d1d8da575bf124a7dbfe8177fb9efc Mon Sep 17 00:00:00 2001 From: root Date: Tue, 11 Aug 2026 02:53:18 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=99=90=E9=A2=9D=E5=B3=B0=E5=80=BC?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=A6=96=E9=94=81+=E4=BD=99=E9=A2=9D?= =?UTF-8?q?=E9=97=A8=E6=8E=A7=E9=87=8D=E9=94=81=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=B6=8A=E7=AE=97=E8=B6=8A=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原 Smart Peak 逻辑把每次用量增长误判为余额恢复(Jump)锁更高峰值, 叠加火山 AvailableAmount 更新滞后,stable_limit 当天一路抬升 (399,836 -> 599,511)且闸门永不触发,额度实际被烧穿。 新策略(volc:peak_pool 当日键): - 首次同步锁定当日峰值(usage + balance) - 仅 balance 自身净上涨(新资源包/对账回补 >=50k)按发放增量抬峰 - pool 回落时 Drop 收紧,永不回升 - usage 驱动的 pool 上涨一律不得抬高限额 新增 volc:last_balance 键记录上次余额快照 --- volc_limit_sync.py | 60 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/volc_limit_sync.py b/volc_limit_sync.py index 18ed570..d984ec7 100644 --- a/volc_limit_sync.py +++ b/volc_limit_sync.py @@ -1308,21 +1308,32 @@ def active_monitor_loop(): dynamic_key = f"limit:dynamic:volcengine:remaining:{target}" # ========================================== - # 🏔️ Smart Peak Tracking (Auto-Correction) + # 🏔️ Daily Peak Lock (First-Sync + Balance-Gated Re-Lock) # ========================================== - # Strategy: - # 1. Capture Jumps (Recovery): If Balance jumps UP, trust it immediately. (Fixes latency) - # 2. Capture Drops (Expiry): If Balance drops HUGE (>20%), trust it. (Fixes expiry) - # - Why trust drops? Because if it's a false drop (glitch), Step 1 will fix it - # automatically on the next sync when it "Jumps" back up. + # 背景:AvailableAmount 是各资源包实例的实时剩余,但火山统计有 + # 更新滞后(高用量时段会短暂冻结,实测 20 万 token 消耗内余额不动)。 + # 旧逻辑把每次用量增长误判为"余额恢复"(Jump)锁更高峰值, + # 导致 stable_limit 越算越多(当天 399,836 -> 599,511 一路抬升)。 + # 修正策略(日内限额单调可控): + # 1. 首次同步锁定当日峰值(= usage + balance 的总配额估计); + # 2. 仅当 balance 自身净上涨(新资源包发放/对账回补,≥50k) + # 时,按新增额度抬高峰值 —— 幅度 = 历史峰值 + 发放增量, + # 绝不把滞后虚高的 usage 一起算进去; + # 3. balance 回落(额度扣减追上用量)时 Drop 收紧; + # 4. usage 增长驱动的 pool 上涨一律不得抬高限额。 + # 实测:协作奖励计划包每自然日发放、偶发一天 2 个,故必须有第 2 条; + # 次日 00:00 (CST) 自动重建当日峰值。 total_pool = current_usage + balance peak_key = f"volc:peak_pool:{today_str}:{target}" - # Short-term memory (Last seen value) + # Short-term memory (Last seen value) - 仅用于日志对比/增量计算 last_pool_key = f"volc:last_seen_pool:{target}" last_pool_val = redis_client.get(last_pool_key) last_pool = float(last_pool_val) if last_pool_val else 0.0 + last_balance_key = f"volc:last_balance:{target}" + last_balance_val = redis_client.get(last_balance_key) + last_balance = float(last_balance_val) if last_balance_val else 0.0 # Long-term memory (Day's High Water Mark) old_peak_val = redis_client.get(peak_key) @@ -1330,21 +1341,31 @@ def active_monitor_loop(): current_peak = historical_peak - # 1. JUMP DETECTION (Recharge / Latency Resolved) - # If pool jumps significantly (>5%) from last seen, it's a fresh, true value. - if total_pool > (last_pool * 1.05) and last_pool > 0: - if DEBUG_MODE: + # 1. INITIALIZATION (First sync of the day): lock once + if historical_peak == 0: + if DEBUG_MODE and last_pool > 0: print( - f"DEBUG: 📈 Balance Jump ({int(last_pool):,} -> {int(total_pool):,}) - Locking New Peak.", + f"DEBUG: 📌 Locking Daily Peak ({int(last_pool):,} -> {int(total_pool):,}) - First Sync Today.", flush=True, ) current_peak = total_pool redis_client.setex(peak_key, 172800, int(current_peak)) - # 2. DROP DETECTION (Resource Expiry) - # If pool drops (even small amounts), we accept it. - # Why? Because keeping a phantom high peak is dangerous. - # If it was a glitch, Rule #1 will fix it next time it bounces back. + # 2. RECHARGE (Balance-driven upward re-lock) + # 新资源包发放 / API 对账回补 → balance 自身净上涨 ≥50k。 + # 只把"发放增量"加进已锁定的峰值,不重算整个滞后 pool。 + elif last_balance > 0 and (balance - last_balance) >= 50000: + grant_delta = int(balance - last_balance) + current_peak = historical_peak + grant_delta + if DEBUG_MODE: + print( + f"DEBUG: 🆕 New Quota Detected (balance {int(last_balance):,} -> {int(balance):,}, +{grant_delta:,}) - Re-locking Daily Peak to {int(current_peak):,}.", + flush=True, + ) + redis_client.setex(peak_key, 172800, int(current_peak)) + + # 3. DROP DETECTION (Resource Expiry / latency catch-up) + # pool 回落时收紧限额;回落之后保持不变,绝不回升。 elif total_pool < historical_peak and historical_peak > 0: drop_ratio = ( historical_peak - total_pool @@ -1357,13 +1378,12 @@ def active_monitor_loop(): current_peak = total_pool redis_client.setex(peak_key, 172800, int(current_peak)) - # 3. INITIALIZATION / DRIFT - elif historical_peak == 0 or total_pool > historical_peak: - current_peak = total_pool - redis_client.setex(peak_key, 172800, int(current_peak)) + # 4. NO USAGE-DRIVEN RE-LOCK: 用量增长(balance 不变)不得抬高限额。 + # (旧逻辑的 Bug 就在这里:把滞后虚高当余额恢复。) # Always update "Last Seen" for next comparison redis_client.setex(last_pool_key, 86400, int(total_pool)) + redis_client.setex(last_balance_key, 86400, int(balance)) # Calculate Stable Limit safety_margin = max(current_peak * 0.15, 250000)